{"id":81087,"date":"2018-08-27T09:11:35","date_gmt":"2018-08-27T06:11:35","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=81087"},"modified":"2018-09-06T09:26:37","modified_gmt":"2018-09-06T06:26:37","slug":"build-a-secure-api-with-spring-boot-and-graphql","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/08\/build-a-secure-api-with-spring-boot-and-graphql.html","title":{"rendered":"Build a Secure API with Spring Boot and GraphQL"},"content":{"rendered":"<p><span style=\"font-size: 20px;\"><b>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever.<\/b> Tired of building the same login screens over and over? <a href=\"https:\/\/developer.okta.com\/signup?utm_source=Java%20Code%20Geeks&#038;utm_medium=Content%20Syndication&#038;utm_campaign=secure%20api%20spring%20boot%20graphql\">Try the Okta API for hosted authentication, authorization, and multi-factor auth.<\/a><\/span><\/p>\n<p>GraphQL is a data query language developed by Facebook in 2012 to solve a shortcoming of REST APIs and traditional database models. All too often, when programmers write REST API data queries, they default to retrieving entire data structures when they need only a part of it. For example, if you want to find out the number of comments on a blog post, a developer might typically retrieve the entire post and all associated fields along with all the comments and all their associated fields <strong>only to<\/strong> count the number of comments in the resulting array.<\/p>\n<p>This is pretty inefficient. However, modern computers are fast. Even a shared server these days is pretty damn fast, as long as you have hundreds or thousands of users. However, when you get to Facebook scale, reaching a sizeable portion of the human beings on the internet, this breaks down. This kind of inefficiency becomes either unworkable or expensive.<\/p>\n<p>It is possible, of course, to write a better SQL query (or NoSQL query) and write a specific API front end call to count the number of blog posts that is far more efficient &#8211; but you have to do this for every specific data query case.<\/p>\n<p>There\u2019s also the problem of wanting more data. What if you want a set of users blog posts and their associated comments AND you also want another set of unrelated data? Typically you make two separate calls to the REST API. In fact, a REST API interaction can result in dozens of calls over the course of a specific API interaction as all necessary data is retrieved. Again, on modern broadband and with relatively few users, this is functional. With hundreds of millions or even billions of users, it breaks down. Milliseconds of efficiency matter. Reducing the number of network calls matters.<\/p>\n<p>There has to be a better way, a more generalized way to allow a front end to request only the data it wants, and to reduce the number of network interactions by combining requests for data.<\/p>\n<p>This is why Facebook developed GraphQL. It provides a framework to describe your data model and allow consumers of the data to ask for exactly what they want and to retrieve predictable results.<\/p>\n<h2>When Would I Use GraphQL?<\/h2>\n<p>GraphQL is enormously powerful and flexible, and when used at internet scale, can provide a significant performance improvement over traditional REST APIs. So why <strong>wouldn\u2019t<\/strong> you use it? Well, in my experience, on smaller projects, I felt like I was often just moving a lot of REST logic into GraphQL schema definitions, where validation and authorization code ended up being nested into a fairly ugly gigantic schema. I also felt like I was duplicating my data type definitions: once in GraphQL and another time in my ORM (this may not be a problem with all implementations).<\/p>\n<p>GraphQL also brings a unique set of security concerns &#8211; there\u2019s nothing wrong with it; it\u2019s just going to be different than using REST APIs or SQL queries so you need to spend a little time researching security. I would consider using it in a situation where an application was going to scale quickly or where the data set might evolve significantly over time. If I had a limited set of well defined data on a smaller project, I\u2019d probably just stick with a REST API.<\/p>\n<h2 id=\"how-do-i-use-graphql\">How Do I Use GraphQL?<\/h2>\n<p>From a developer perspective, there are two major components:<\/p>\n<ul>\n<li>the type descriptions<\/li>\n<li>the query language<\/li>\n<\/ul>\n<p>The type descriptions end up looking a lot like ORMs (if you\u2019re familiar with those). You define types and fields on those types. Later you also define functions to retrieve that information from your database.<\/p>\n<p>For example, let\u2019s look at a very simple blog post definition.<\/p>\n<pre class=\"brush:bash; gutter: false\">type Post {  \r\n    id: ID!  \r\n    text: String!  \r\n}<\/pre>\n<p>Pretty basic. A <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">post<\/code> has an <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">id<\/code> and a <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">text<\/code> field. Let\u2019s add some comments to the Post type definition.<\/p>\n<pre class=\"brush:bash; gutter: false\">type Post {  \r\n    id: ID!  \r\n    text: String!  \r\n    comments: [Comment!]!  \r\n}  \r\n  \r\ntype Comment {  \r\n    id: ID!  \r\n    text: String!  \r\n}<\/pre>\n<p>Now the type Post contains an array of type Comments. How do we turn this into a usable GraphQL schema definition?<\/p>\n<p>We need to do two things:<\/p>\n<ol>\n<li>Define a \u201cQuery\u201d type\u2013the entry point for all GraphQL queries into our data<\/li>\n<li>Write methods for each field on each type that return the requested field from the data type<\/li>\n<\/ol>\n<h2>Define Your GraphQL Schema Query<\/h2>\n<p>In the simple example application we\u2019re building, we would want to be able to query for Posts, so lets add a Query type with a <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">post<\/code> field of type Post. Our GraphQL schema would now look like this:<\/p>\n<pre class=\"brush:bash; gutter: false\">type Query {  \r\n    post(id: ID!): Post  \r\n}\r\n\r\ntype Post {  \r\n    id: ID!  \r\n    text: String!  \r\n    comments: [Comment!]!  \r\n}  \r\n  \r\ntype Comment {  \r\n    id: ID!  \r\n    text: String!  \r\n}\r\n<\/pre>\n<p>Just to reiterate, the types Post and Comment directly describe our data structure, and the type Query is a GraphQL-ism, a special type that defines the read-only entry point for the schema. There is also a Mutation type that provides a mutable access point in the schema.<\/p>\n<p>Another thing to note is that fields can have arguments. If you look at the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">post<\/code> field on the Query type, you\u2019ll notice it has an argument of type ID. This argument can be specified in the query and will be passed to the function that is called to retrieve the data.<\/p>\n<p>The exclamation points, by the way, simply mean that the type is non-nullable.<\/p>\n<h2>Types in GraphQL<\/h2>\n<p>GraphQL is basically about defining fields on types and querying for those fields. It is strongly typed, and has 5 built in scalar types:<\/p>\n<ul>\n<li>Int: a 32-bit integer<\/li>\n<li>Float: A signed double-precision floating-point value<\/li>\n<li>String: A UTF\u20108 character sequence<\/li>\n<li>Boolean: true or false<\/li>\n<li>ID: unique identifier, serialized as a String<\/li>\n<\/ul>\n<p>Custom Scalar types can also be defined, such as a Date type, for example, and methods must be provided for serialization, deserialization, and validation.<\/p>\n<p>Enums and Lists\/Arrays can also be specified. We created a List of <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Comments<\/code> in our <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Post<\/code> type above.<\/p>\n<p>The <a href=\"http:\/\/graphql.github.io\/learn\/schema\/\">official GraphQL documentation<\/a> have more information on types and schemas.<\/p>\n<h2 id=\"using-graphql-in-java\">Using GraphQL in Java<\/h2>\n<p>In this tutorial, we are going to use a project called <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">graphql-tools<\/code> to integrate GraphQL with Spring Boot. According to the <a href=\"https:\/\/github.com\/graphql-java\/graphql-java-tools\">project github page<\/a> readme, <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">graphql-tools<\/code> \u201callows you to use the GraphQL schema language to build your <a href=\"https:\/\/github.com\/graphql-java\/graphql-java\">graphql-java<\/a> schema and allows you to BYOO (bring your own object) to fill in the implementations.\u201d<\/p>\n<p>It works great if you have, or want to have, plain old java objects (POJO) that define your data model. Which I do.<\/p>\n<p>What would our POJOs look like?<\/p>\n<pre class=\"brush:bash; gutter: false\">class Post {  \r\n  \r\n    protected int id;  \r\n    protected String text;  \r\n  \r\n    Post(int id) {  \r\n        this.id = id;  \r\n        this.text = \"\";  \r\n        this.comments = new ArrayList();  \r\n    }  \r\n  \r\n    Post(int id, String text, ArrayList comments) {  \r\n        this.id = id;  \r\n        this.text = text;  \r\n        this.comments = comments;  \r\n    }  \r\n  \r\n    protected ArrayList comments;  \r\n  \r\n}\r\n\r\nclass Comment {  \r\n  \r\n    private int id;  \r\n    private String text;  \r\n  \r\n    Comment(int id, String text) {  \r\n        this.id = id;  \r\n        this.text = text;  \r\n    }  \r\n      \r\n}<\/pre>\n<p>These classes would define the basic types of our data model, and would correspond to the types in the GraphQL schema. They would be defined in separate java class files. (See what I mean about having duplicate data definitions?)<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>We would also need to define a couple \u201cResolvers\u201d. Resolvers are used by <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">graphql-tools<\/code> to resolve non-scalar types. Each type in our GraphQL schema that contains non-scalar types needs to have an associated Resolver. Thus our <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Query<\/code> type and our <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Post<\/code> type need resolvers, but our Comment` type does not.<\/p>\n<p>Here is what the Post Resolver might look like:<\/p>\n<pre class=\"brush:bash; gutter: false\">class PostResolver implements GraphQLResolver {  \r\n  \r\n    public List getComments(Post post) {  \r\n        return post.comments;  \r\n    }  \r\n}<\/pre>\n<p>And here is a skeleton for the Query Resolver:<\/p>\n<pre class=\"brush:bash; gutter: false\">class Query implements GraphQLQueryResolver {  \r\n \r\n    Post getPost(int id) {\r\n\t    \/\/ Do something to retrieve the post\r\n    }  \r\n}<\/pre>\n<h2>Download the Spring Boot Example App<\/h2>\n<p>So now we get to the exciting part! Building a Spring Boot application that uses GraphQL, and securing that application with Okta (which we\u2019ll get to last, and which Okta has made super easy).<\/p>\n<p>Now would be a great time to go ahead and download <a href=\"https:\/\/github.com\/oktadeveloper\/okta-springboot-graphql-example\">our example application<\/a>. It\u2019s based on the example-graphql-tools project from <a href=\"https:\/\/github.com\/graphql-java\/graphql-spring-boot\">this awesome project<\/a> on the graphql-java github page.<\/p>\n<pre class=\"brush:bash; gutter: false\">git clone https:\/\/github.com\/oktadeveloper\/okta-springboot-graphql-example.git<\/pre>\n<p>This project is actually two sub-projects:<\/p>\n<ul>\n<li><strong>OktaShowToken<\/strong>: used to retrieve a working authorization token from an Okta OAuth OIDC application<\/li>\n<li><strong>OktaGraphQL<\/strong>: Spring Boot resource server based on GraphQL (to which we\u2019ll be adding Okta Auth at the end<\/li>\n<\/ul>\n<h2>Create Okta OAuth Application and Install HTTPie<\/h2>\n<p>This tutorial makes the assumption that you already have a free Okta Developer account (if not, why don\u2019t you head over to <a href=\"https:\/\/developer.okta.com?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">developer.okta.com<\/a> and create one).<\/p>\n<h3>Why Okta?<\/h3>\n<p>At Okta, our goal is to make <a href=\"https:\/\/developer.okta.com\/product\/user-management\/?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">identity management<\/a> a lot easier, more secure, and more scalable than what you\u2019re used to. Okta is a cloud service that allows developers to create, edit, and securely store user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.okta.com\/product\/authentication\/?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">Authenticate<\/a> and <a href=\"https:\/\/developer.okta.com\/product\/authorization\/?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">authorize<\/a> your users<\/li>\n<li>Store data about your users<\/li>\n<li>Perform password-based and <a href=\"https:\/\/developer.okta.com\/authentication-guide\/social-login\/?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">social login<\/a><\/li>\n<li>Secure your application with <a href=\"https:\/\/developer.okta.com\/use_cases\/mfa\/?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">multi-factor authentication<\/a><\/li>\n<li>And much more! Check out our <a href=\"https:\/\/developer.okta.com\/documentation\/?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">product documentation<\/a><\/li>\n<\/ul>\n<h3>Create a New OIDC App in Okta<\/h3>\n<p>To create a new OIDC app on Okta, you can begin with the default settings, then:<\/p>\n<ol>\n<li>Log in to your developer account, navigate to <strong>Applications<\/strong>, and click on <strong>Add Application<\/strong>.<\/li>\n<li>Select <strong>Web<\/strong> and click <strong>Next<\/strong>.<\/li>\n<li>Give the application a name, add <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">http:\/\/localhost:8080\/login<\/code> as a Login redirect URI, and click <strong>Done<\/strong>.<\/li>\n<\/ol>\n<p>We\u2019re going to use HTTPie, a great HTTP command line client. So if you don\u2019t have that installed, check it out and follow the installation instructions on <a href=\"https:\/\/httpie.org\/\">httpie.org<\/a>.<\/p>\n<h2>Check Out the OktaGraphQL Example App<\/h2>\n<p>Let\u2019s ignore the OktaShowToken project for a moment and take a look at the OktaGraphQL, which is initially configured to run without authentication.<\/p>\n<p>You\u2019ll notice that there isn\u2019t really much to it, beyond the POJO classes and resolvers in the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">com.okta.springbootgraphql.resolvers<\/code> package, as well as the GraphQL schema definition found in <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">src\/main\/resources\/graphql-tools.graphqls<\/code>.<\/p>\n<p>Most of this should be pretty self-explanatory at this point. I\u2019ll simply point out that our Query class (the query resolver) is a bit of a quick and dirty hack to avoid having to setup an actual database data source. We\u2019re just generating the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Post<\/code>s and <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Comment<\/code>s on the fly based on their ID number. In the real implementation, you\u2019d be adding some more business layer logic here, such as authorization, and looking up the data in your data source.<\/p>\n<pre class=\"brush:bash; gutter: false\">class Query implements GraphQLQueryResolver {  \r\n  \r\n    Post getPost(int id) {  \r\n  \r\n        if (id == 1) {  \r\n            ArrayList comments = new ArrayList() {{  \r\n                add(new Comment(1, \"GraphQL is amazing!\"));  \r\n            }};  \r\n            return new Post(id, \"Okta + GraphQL is pretty sweet.\", comments);  \r\n        }  \r\n        else if (id == 2) {  \r\n            ArrayList comments = new ArrayList() {{  \r\n                add(new Comment(1, \"I can't believe how easy this is.\"));  \r\n            }};  \r\n            return new Post(id, \"Is GraphQL better than a REST API?\", comments);  \r\n        }  \r\n        else {  \r\n            return null;  \r\n        }  \r\n    }\r\n}<\/pre>\n<h2>Run Your First GraphQL Query<\/h2>\n<p>Open a terminal and from the OktaGraphQL project directory, start the Spring Boot application using the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/gradlew bootRun<\/code> command.<\/p>\n<p>It may take a few seconds to get started. You should see some output that ends like this:<\/p>\n<pre class=\"brush:bash; gutter: false\">Tomcat started on port(s): 9000 (http) with context path ''\r\nStarted GraphQLToolsSampleApplication in 19.245 seconds (JVM running for 19.664)<\/pre>\n<p>Leave that terminal window open and open another terminal window. Navigate again to the project root. Use the following command to run our first GraphQL Query:<\/p>\n<pre class=\"brush:bash; gutter: false\">http POST http:\/\/localhost:9000\/graphql\/ &lt; json-requests\/post1-all-data.json<\/pre>\n<p>Here we\u2019re making a POST request with content type <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">application\/json<\/code> (because this is the default for <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">HTTPie<\/code>) and we\u2019re sending the query found in the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">json-requests\/post1-all-data.json<\/code> file as the request body.<\/p>\n<p>The request body from <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">json-requests\/post1-all-data.json<\/code>:<\/p>\n<pre class=\"brush:bash; gutter: false\">{  \r\n  \"query\": \"{ post(id: '1') { id, text, comments { id, text} } }\"  \r\n}<\/pre>\n<p>The expected result:<\/p>\n<pre class=\"brush:bash; gutter: false\">HTTP\/1.1 200 \r\nContent-Length: 122\r\nContent-Type: application\/json;charset=UTF-8\r\nDate: Fri, 03 Aug 2018 21:50:25 GMT<\/pre>\n<pre class=\"brush:bash; gutter: false\">{\r\n    \"data\": {\r\n        \"post\": {\r\n            \"comments\": [\r\n                {\r\n                    \"id\": \"1\",\r\n                    \"text\": \"GraphQL is amazing!\"\r\n                }\r\n            ],\r\n            \"id\": \"1\",\r\n            \"text\": \"Okta + GraphQL is pretty sweet.\"\r\n        }\r\n    }\r\n}<\/pre>\n<p>At this point you could play around with the JSON request files, asking for less data or requesting a different post.<\/p>\n<p>We\u2019re going to move on to adding authentication.<\/p>\n<h2>Add Okta for OAuth<\/h2>\n<p>At this point we\u2019re gonna need a few things from your Okta OAuth application settings:<\/p>\n<ul>\n<li>client ID<\/li>\n<li>client secret<\/li>\n<li>your Okta base URL (something like this: <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">https:\/\/dev-123456.oktapreview.com<\/code>)<\/li>\n<\/ul>\n<p>The client ID and client secret can be found in the general settings for your application (select the <strong>Application<\/strong> menu, select the application you want to use, and finally select the <strong>General<\/strong> tab).<\/p>\n<p>In the OktaGraphQL project, create a <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">gradle.properties<\/code> file and fill in the following properties:<\/p>\n<pre class=\"brush:bash; gutter: false\">oktaClientId={yourClientId}\r\noktaBaseUrl=https:\/\/{yourOktaDomain}<\/pre>\n<p>In the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">src\/main\/resources\/application.yml<\/code> file, add the following properties:<\/p>\n<pre class=\"brush:bash; gutter: false\">okta:  \r\n   oauth2: \r\n      issuer: ${oktaBaseUrl}\/oauth2\/default  \r\n      clientId: ${oktaClientId}  \r\n      scopes: 'email profile openid'<\/pre>\n<p>Add the following dependencies to the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code> file in the OktaGraphQL project. These are the Spring Boot OAuth dependencies and the <a href=\"https:\/\/github.com\/okta\/okta-spring-boot\">Okta Spring Boot starter<\/a>.<\/p>\n<pre class=\"brush:bash; gutter: false\">compile group: 'com.okta.spring', name: 'okta-spring-boot-starter', version: '0.6.0'  \r\ncompile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.3.3.RELEASE'  \r\ncompile ('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.1.RELEASE')<\/pre>\n<p>Now let\u2019s add two annotations (<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableResourceServer<\/code> and <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableOAuth2Sso<\/code>) to the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">GraphQLToolsSampleApplication<\/code> class. It should look like this:<\/p>\n<pre class=\"brush:bash; gutter: false\">package com.okta.springbootgraphql;  \r\n  \r\nimport org.springframework.boot.SpringApplication;  \r\nimport org.springframework.boot.autoconfigure.SpringBootApplication;  \r\nimport org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;  \r\nimport org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;  \r\n  \r\n@SpringBootApplication  \r\n@EnableResourceServer  \r\n@EnableOAuth2Sso  \r\npublic class GraphQLToolsSampleApplication {  \r\n  \r\n    public static void main(String[] args) {  \r\n        SpringApplication.run(GraphQLToolsSampleApplication.class, args);  \r\n    }  \r\n}<\/pre>\n<p>Stop your Spring Boot app (if it\u2019s still running) and restart it using <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/gradlew bootRun<\/code>.<\/p>\n<p>Run a query against the GraphQL server and you\u2019ll see a 401 error:<\/p>\n<pre class=\"brush:bash; gutter: false\">HTTP\/1.1 401 \r\nCache-Control: no-store\r\nContent-Type: application\/json;charset=UTF-8\r\nDate: Fri, 03 Aug 2018 22:10:50 GMT\r\nPragma: no-cache\r\nTransfer-Encoding: chunked\r\nWWW-Authenticate: Bearer realm=\"api:\/\/default\", error=\"unauthorized\", error_description=\"Full authentication is required to access this resource\"\r\nX-Content-Type-Options: nosniff\r\nX-Frame-Options: DENY\r\nX-XSS-Protection: 1; mode=block<\/pre>\n<pre class=\"brush:bash; gutter: false\">{\r\n    \"error\": \"unauthorized\",\r\n    \"error_description\": \"Full authentication is required to access this resource\"\r\n}<\/pre>\n<h2>Get an Access Token<\/h2>\n<p>To access our protected GraphQL server now, we need an Okta access token. Typically this would be managed through the context of an application front end. For the purposes of this tutorial, we\u2019re going to use our OktaShowToken application to retrieve an authorization token from our Okta application.<\/p>\n<p>In the OktaShowToken project, create a <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">gradle.properties<\/code> file and fill in the following properties:<\/p>\n<pre class=\"brush:bash; gutter: false\">oktaClientId={yourClientId}\r\noktaClientSecret={yourClientSecret}\r\noktaBaseUrl=https:\/\/{yourOktaDomain}<\/pre>\n<p>Open a terminal, go to the OktaShowToken project root, and run <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/gradlew bootRun<\/code>.<\/p>\n<p>Once the application completes launching, navigate to <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">http:\/\/localhost:8080<\/code>.<\/p>\n<p>You\u2019ll go through the Okta login and authentication process. You should see the Okta login screen.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/08\/okta-sign-in-a315c312a17af60f63b46a3d3bc12089717a3375682b29e6888a51951423b741.png\"><img decoding=\"async\" class=\"aligncenter wp-image-81092\" style=\"border: none;\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/08\/okta-sign-in-a315c312a17af60f63b46a3d3bc12089717a3375682b29e6888a51951423b741.png\" alt=\"\" width=\"820\" height=\"799\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/08\/okta-sign-in-a315c312a17af60f63b46a3d3bc12089717a3375682b29e6888a51951423b741.png 1162w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/08\/okta-sign-in-a315c312a17af60f63b46a3d3bc12089717a3375682b29e6888a51951423b741-300x292.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/08\/okta-sign-in-a315c312a17af60f63b46a3d3bc12089717a3375682b29e6888a51951423b741-768x748.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/08\/okta-sign-in-a315c312a17af60f63b46a3d3bc12089717a3375682b29e6888a51951423b741-1024x998.png 1024w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>After logging in, you\u2019ll see a page of text that contains your access token. Leave this page open and\/or copy this token somewhere where you can use it later.<\/p>\n<h2>Use the Access Token to Access the GraphQL Endpoint<\/h2>\n<p>First lets store the token value in a temporary shell variable:<\/p>\n<pre class=\"brush:bash; gutter: false\">TOKEN={accessTokenValue}<\/pre>\n<p>Then let\u2019s run the request again setting the authorization header. You\u2019ll need to run the following command from the <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">OktaGraphQL<\/code> directory.<\/p>\n<pre class=\"brush:bash; gutter: false\">http POST http:\/\/localhost:9000\/graphql\/ Authorization:\"Bearer $TOKEN\" &lt; json-requests\/post1-all-data.json<\/pre>\n<p>You should see these familiar results:<\/p>\n<pre class=\"brush:bash; gutter: false\">HTTP\/1.1 200 \r\nCache-Control: no-cache, no-store, max-age=0, must-revalidate\r\nContent-Length: 122\r\nContent-Type: application\/json;charset=UTF-8\r\nDate: Fri, 03 Aug 2018 22:22:00 GMT\r\nExpires: 0\r\nPragma: no-cache\r\nX-Content-Type-Options: nosniff\r\nX-Frame-Options: DENY\r\nX-XSS-Protection: 1; mode=block<\/pre>\n<pre class=\"brush:bash; gutter: false\">{\r\n    \"data\": {\r\n        \"post\": {\r\n            \"comments\": [\r\n                {\r\n                    \"id\": \"1\",\r\n                    \"text\": \"GraphQL is amazing!\"\r\n                }\r\n            ],\r\n            \"id\": \"1\",\r\n            \"text\": \"Okta + GraphQL is pretty sweet.\"\r\n        }\r\n    }\r\n}<\/pre>\n<h2>Learn More About Spring Boot, GraphQL, and Secure API Design<\/h2>\n<p>And that\u2019s it! GraphQL is obviously a pretty deep subject, and if you\u2019re coming from a traditional REST API background, you\u2019ll need to dig into it a little to shift paradigms and properly implement everything.<\/p>\n<p>In their docs, the GraphQL people make a point of repeatedly stating that <strong>GraphQL does not replace your business logic layer<\/strong>, but instead provides a data access query language and type schema that sits between your business logic layer and the outside world. Take a look at their <a href=\"http:\/\/graphql.github.io\/learn\/authorization\/\">docs on authorization<\/a> to get a feel for this.<\/p>\n<p>But as you can see, Okta\u2019s Spring Boot Starter makes securing a GraphQL endpoint incredibly simple. If you\u2019re interested in learning more about Spring Boot or GraphQL, please check out these related posts:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/07\/11\/build-react-graphql-api-user-authentication?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">Build a Health Tracking App with React, GraphQL, and User Authentication<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2017\/03\/21\/spring-boot-oauth?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">Get Started with Spring Boot, OAuth 2.0, and Okta<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/04\/02\/client-creds-with-spring-boot?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">Secure Server-to-Server Communication with Spring Boot and OAuth 2.0<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/07\/30\/10-ways-to-secure-spring-boot?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">10 Excellent Ways to Secure Your Spring Boot Application<\/a><\/li>\n<\/ul>\n<p>If you have any questions about this post, please add a comment below. For more awesome content, follow <a href=\"https:\/\/twitter.com\/oktadev\">@oktadev<\/a> on Twitter, like us <a href=\"https:\/\/www.facebook.com\/oktadevelopers\/\">on Facebook<\/a>, or subscribe to <a href=\"https:\/\/www.youtube.com\/channel\/UC5AMiWqFVFxF1q9Ya1FuZ_Q\">our YouTube channel<\/a>.<\/p>\n<p><span style=\"font-size: 20px;\"><b>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever.<\/b> Tired of building the same login screens over and over? <a href=\"https:\/\/developer.okta.com\/signup?utm_source=Java%20Code%20Geeks&#038;utm_medium=Content%20Syndication&#038;utm_campaign=secure%20api%20spring%20boot%20graphql\">Try the Okta API for hosted authentication, authorization, and multi-factor auth.<\/a><\/span><\/p>\n<p><a href=\"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\" target=\"_blank\" rel=\"noopener\" data-saferedirecturl=\"https:\/\/www.google.com\/url?hl=en&amp;q=https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql&amp;source=gmail&amp;ust=1535212388921000&amp;usg=AFQjCNE3jnudsP1FZYqm-B187x-KpB4msA?utm_source=Java%20Code%20Geeks&amp;utm_medium=Content%20Syndication&amp;utm_campaign=secure%20api%20spring%20boot%20graphql\">&#8216;Build a Secure API with Spring Boot and GraphQL&#8217;<\/a> was originally published on the Okta developer blog on August 16, 2018.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever. Tired of building the same login screens over and over? Try the Okta API for hosted authentication, authorization, and multi-factor auth. GraphQL is a data query language developed by Facebook in 2012 to solve a shortcoming of REST APIs and traditional database models. &hellip;<\/p>\n","protected":false},"author":49514,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[1458,30,854],"class_list":["post-81087","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-graphql","tag-spring","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Build a Secure API with Spring Boot and GraphQL - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn more about GraphQL? Then check out our article where we Build a Secure API with Spring Boot and GraphQL!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a Secure API with Spring Boot and GraphQL - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn more about GraphQL? Then check out our article where we Build a Secure API with Spring Boot and GraphQL!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2018-08-27T06:11:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-09-06T06:26:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrew Hughes\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrew Hughes\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/08\\\/build-a-secure-api-with-spring-boot-and-graphql.html\"},\"author\":{\"name\":\"Andrew Hughes\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0ded99ab51010abb68790f6189ce99d3\"},\"headline\":\"Build a Secure API with Spring Boot and GraphQL\",\"datePublished\":\"2018-08-27T06:11:35+00:00\",\"dateModified\":\"2018-09-06T06:26:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/08\\\/build-a-secure-api-with-spring-boot-and-graphql.html\"},\"wordCount\":2379,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"GraphQL\",\"Spring\",\"Spring Boot\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/08\\\/build-a-secure-api-with-spring-boot-and-graphql.html\",\"url\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql\",\"name\":\"Build a Secure API with Spring Boot and GraphQL - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2018-08-27T06:11:35+00:00\",\"dateModified\":\"2018-09-06T06:26:37+00:00\",\"description\":\"Interested to learn more about GraphQL? Then check out our article where we Build a Secure API with Spring Boot and GraphQL!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/08\\\/16\\\/secure-api-spring-boot-graphql#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Build a Secure API with Spring Boot and GraphQL\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0ded99ab51010abb68790f6189ce99d3\",\"name\":\"Andrew Hughes\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g\",\"caption\":\"Andrew Hughes\"},\"sameAs\":[\"https:\\\/\\\/developer.okta.com\\\/blog\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrew-hughes\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Build a Secure API with Spring Boot and GraphQL - Java Code Geeks","description":"Interested to learn more about GraphQL? Then check out our article where we Build a Secure API with Spring Boot and GraphQL!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql","og_locale":"en_US","og_type":"article","og_title":"Build a Secure API with Spring Boot and GraphQL - Java Code Geeks","og_description":"Interested to learn more about GraphQL? Then check out our article where we Build a Secure API with Spring Boot and GraphQL!","og_url":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-08-27T06:11:35+00:00","article_modified_time":"2018-09-06T06:26:37+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Andrew Hughes","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrew Hughes","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/08\/build-a-secure-api-with-spring-boot-and-graphql.html"},"author":{"name":"Andrew Hughes","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0ded99ab51010abb68790f6189ce99d3"},"headline":"Build a Secure API with Spring Boot and GraphQL","datePublished":"2018-08-27T06:11:35+00:00","dateModified":"2018-09-06T06:26:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/08\/build-a-secure-api-with-spring-boot-and-graphql.html"},"wordCount":2379,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["GraphQL","Spring","Spring Boot"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/08\/build-a-secure-api-with-spring-boot-and-graphql.html","url":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql","name":"Build a Secure API with Spring Boot and GraphQL - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#primaryimage"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2018-08-27T06:11:35+00:00","dateModified":"2018-09-06T06:26:37+00:00","description":"Interested to learn more about GraphQL? Then check out our article where we Build a Secure API with Spring Boot and GraphQL!","breadcrumb":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Build a Secure API with Spring Boot and GraphQL"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0ded99ab51010abb68790f6189ce99d3","name":"Andrew Hughes","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g","caption":"Andrew Hughes"},"sameAs":["https:\/\/developer.okta.com\/blog"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrew-hughes"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/81087","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/49514"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=81087"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/81087\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=81087"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=81087"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=81087"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}