Sean Robertson

Sean Robertson

1553749248

How to build GraphQL APIs with Kotlin, Spring Boot, and MongoDB?

#graphql #kotlin #spring-boot #mongodb

What is GEEK

Buddha Community

Zachary Palmer

1553749387

Learn how to build modern APIs with Kotlin, the flexible programming language that can run on JVMs.

In this article, you will learn how to build GraphQL APIs with Kotlin, Spring Boot, and MongoDB. Also, as you wouldn’t want to publish insecure APIs, you will learn how to integrate Auth0 in your stack. You can find the final code developed throughout the article in this GitHub repository.

Prerequisites

Before proceeding, there are some tools you need to ensure you have on your machine to be able to follow the article seamlessly. They include:

  • JDK: This is the Java Platform, Standard Edition Development Kit. Normally, this environment is used for developing Java applications but, since Kotlin runs on the JVM (just like Java), you need it. You can download JDK from here.
  • IntelliJ IDEA: This is an IDE (Integrated Development Environment) built by JetBrains and used for developing Java and Kotlin applications. They have both the paid version and the free (community) version. You can download the IDE right here.
  • MongoDB: A document-oriented database that stores data in a Binary JSON (BSON) format. One of the advantages of this database is that you don’t need a predefined schema (as such, you have maximum flexibility when it comes to change this schema over time). If you don’t have it, you can follow this manual to install MongoDB.

Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.## What You Will Build

In this article, you will build a GraphQL API that performs some basic CRUD (Create, Retrieve, Update, and Delete) operations. The API will focus on snacks and reviews. Users (or client applications) will be able to use your API to list snacks and their reviews. However, beyond querying the API, they will also be able to update these snacks by issuing GraphQL mutations to create, update, and delete records in your database.

Scaffolding Your Kotlin and Spring Boot Project

Spring Boot has an initializer tool that helps you bootstrap (or scaffold) your applications faster. So, open the initializer and fill in the options to put your project together:

  • JDK: This is the Java Platform, Standard Edition Development Kit. Normally, this environment is used for developing Java applications but, since Kotlin runs on the JVM (just like Java), you need it. You can download JDK from here.
  • IntelliJ IDEA: This is an IDE (Integrated Development Environment) built by JetBrains and used for developing Java and Kotlin applications. They have both the paid version and the free (community) version. You can download the IDE right here.
  • MongoDB: A document-oriented database that stores data in a Binary JSON (BSON) format. One of the advantages of this database is that you don’t need a predefined schema (as such, you have maximum flexibility when it comes to change this schema over time). If you don’t have it, you can follow this manual to install MongoDB.

Here, you are generating a Gradle project with Kotlin and Spring Boot 2.1.3. The group name for the app (or the main package, if you prefer) is com.auth0 while the artifact name is kotlin-graphql. After filling in these options, use the “search dependencies to add” field to include Web and MongoDB.

The Web dependency is a starter dependency for building web applications while MongoDB is a dependency to aid your database operations.

After adding these dependencies, click on the Generate Project button. This will download a zipped file that contains your project. Extract the project from this file, and use IntelliJ (or your preferred IDE) to open it.

Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
Next, you will have to include some dependencies to help you add a GraphQL API in your Spring Boot and Kotlin application. To add these dependencies, open your build.gradle file and update it as follows:

// ./build.gradle

// ...

dependencies {
    // ...
    implementation 'com.graphql-java:graphql-spring-boot-starter:5.0.2'
    implementation 'com.graphql-java:graphiql-spring-boot-starter:5.0.2'
    implementation 'com.graphql-java:graphql-java-tools:5.2.4'
}

// ...


Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
After that, open the application.properties file located in the ./src/main/resources/ directory and add the following properties:

server.port=9000
spring.data.mongodb.database=kotlin-graphql
spring.data.mongodb.port=27017


Here, you are defining which port your API will use to listen to requests (9000 in this case), and you are defining some MongoDB connection properties (you might need to add some more, depending on your MongoDB installation). With that in place, you are ready to start developing your application.

Creating Entities to Persist on MongoDB

An entity is a term often associated with a model class that is persisted on databases. Since you are dealing with APIs to perform CRUD operations, you will need to persist data that will be consumed later. In this section, you will define entities that you’ll use in the course of building your API.

First, create a new package called entity inside the com.auth0.kotlingraphql one. You will keep all the entities you need here in this package. Next, create a new class called Snack inside this package and add the following code to it:

// ./src/main/kotlin/com/auth0/kotlingraphql/entity/Snack.kt

package com.auth0.kotlingraphql.entity;

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document

@Document(collection = "snack")
data class Snack(
        var name: String,
        var amount: Float
) {
    @Id
    var id: String = ""

    @Transient
    var reviews: List<Review> = ArrayList()
}


Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
This class is a model of a single Snack that you will store in your database. Each snack has a name, an amount, an id (a unique identifier), and reviews. The reviews variable will hold all the reviews associated with a particular snack.

You will use this model when storing snacks to the database, hence the use of the @Document annotation. The name of the collection is specified using the collection variable in the annotation. If you do not specify this property, Spring Boot will automatically use the class name.

The id variable is annotated with @Id to tell MongoDB that this variable will hold the unique identifier for the entity. The @Transient annotation, on reviews, means this variable will not be persisted to the database (you will make the Review class persist the association).

Next, create another class called Review (still under the entity package) and add this snippet:

// ./src/main/kotlin/com/auth0/kotlingraphql/entity/Review.kt

package com.auth0.kotlingraphql.entity

import org.springframework.data.mongodb.core.mapping.Document

@Document(collection = "reviews")
data class Review(
        var snackId: String,
        var rating: Int,
        var text: String
)


The approach used here is similar to the one used to create Snack. In this case, you are defining a class that represents a single review.

Creating Mongo Repositories

According to the official Spring documentation:

Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
In other others, a repository is a class responsible for some form of data storage, retrieval, and manipulation. In this section, you will create repositories to match the two entities you created earlier.

First, create a new package called repository (again inside the com.auth0.kotlingraphql one) and, inside this package, create a Kotlin interface called SnackRepository. To this interface, add the following code:

// ./src/main/kotlin/com/auth0/kotlingraphql/repository/SnackRepository.kt

package com.auth0.kotlingraphql.repository

import com.auth0.kotlingraphql.entity.Snack
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.stereotype.Repository

@Repository
interface SnackRepository : MongoRepository<Snack, String>


The interface you have just created extends MongoRepository to take advantages of its predefined methods. Some of these methods include: findAll, saveAll, and findById.

The MongoRepository interface takes in two parameter types, Snack and String. The first parameter (Snack) is the data type that will be managed by the repository while the second parameter (String) is the data type of the id property. As you can imagine, you need String here since this is the data type for the id variable in the Snack entity.

The @Repository annotation is used to indicate that the class is a repository. Although creating the SnackRepository without the @Repository annotation still works as expected, the annotation has the following benefits:

  • JDK: This is the Java Platform, Standard Edition Development Kit. Normally, this environment is used for developing Java applications but, since Kotlin runs on the JVM (just like Java), you need it. You can download JDK from here.
  • IntelliJ IDEA: This is an IDE (Integrated Development Environment) built by JetBrains and used for developing Java and Kotlin applications. They have both the paid version and the free (community) version. You can download the IDE right here.
  • MongoDB: A document-oriented database that stores data in a Binary JSON (BSON) format. One of the advantages of this database is that you don’t need a predefined schema (as such, you have maximum flexibility when it comes to change this schema over time). If you don’t have it, you can follow this manual to install MongoDB.

Next, you will create another Kotlin interface named ReviewRepository (still in the repository package) and add this:

// ./src/main/kotlin/com/auth0/kotlingraphql/repository/ReviewRepository.kt

package com.auth0.kotlingraphql.repository

import com.auth0.kotlingraphql.entity.Review
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.stereotype.Repository

@Repository
interface ReviewRepository : MongoRepository<Review, String>


This is very similar to the first repository created. The difference is that you will manage instances of Review with this new repository (hence <Review, String>).

Defining Your GraphQL Schema

Unlike REST APIs, where you have to declare endpoints based on the resources they return, in GraphQL, you need to define a schema. This schema is used to:

  • JDK: This is the Java Platform, Standard Edition Development Kit. Normally, this environment is used for developing Java applications but, since Kotlin runs on the JVM (just like Java), you need it. You can download JDK from here.
  • IntelliJ IDEA: This is an IDE (Integrated Development Environment) built by JetBrains and used for developing Java and Kotlin applications. They have both the paid version and the free (community) version. You can download the IDE right here.
  • MongoDB: A document-oriented database that stores data in a Binary JSON (BSON) format. One of the advantages of this database is that you don’t need a predefined schema (as such, you have maximum flexibility when it comes to change this schema over time). If you don’t have it, you can follow this manual to install MongoDB.

While you have POST, GET, PUT, and others as request methods in a REST API, for GraphQL, you have just Query (equivalent of GET in REST) and Mutation (equivalent of PUT, POST, PATCH and DELETE in REST). In this section, you will now learn how to define a GraphQL schema for your Spring Boot and Kotlin application.

Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
For starters, create a new file called snack.graphqls in the ./src/main/resources/ directory and add this code to it:

type Query {
    snacks: [Snack]
}

type Snack {
    id: ID!
    name: String
    amount: Float
    reviews: [Review]
}

type Mutation {
    newSnack(name: String!, amount: Float!) : Snack!
    deleteSnack(id: ID!) : Boolean
    updateSnack(id:ID!, amount: Float!) : Snack!
}


In this file, you declared three types with their respective fields. The Query type is a standard type used by a client to request data. This type has a field called snacks that returns a Snack list. The Snack type here mimics the snack entity you created earlier. The Mutation type is another standard type that a client application will use to add, update, or delete data.

Now, still in the ./src/main/resources/ directory, create another file called review.graphqls and add this code to it:

extend type Query {
    reviews(snackId: ID!): [Review]
}

type Review {
    snackId: ID!
    rating: Int
    text: String!
}

extend type Mutation {
    newReview(snackId: ID!, rating: Int, text:String!) : Review!
}


In this file, the keyword extend is attached to the Query and Mutation to extend the types declared in the other file. Everything else is similar to the other schema you defined.

Defining Your GraphQL Resolvers

A resolver is a function that provides a value for a field or a type declared in your schema. In other words, a GraphQL resolver is responsible for translating your data into the schema you are using. As such, now, you have to create corresponding Kotlin functions for the fields you declared in the last section: snacks, newSnack, deleteSnack, updateSnack, reviews, newReview.

So, the first thing you will do is to create a package called resolvers inside the main package (i.e., inside com.auth0.kotlingraphql). Then, you will create a class called SnackQueryResolver inside this new package. After creating this class, add the following code to it:

// .src/main/kotlin/com/auth0/kotlingraphql/resolvers/SnackQueryResolver.kt

package com.auth0.kotlingraphql.resolvers

import com.auth0.kotlingraphql.entity.Review
import com.auth0.kotlingraphql.entity.Snack
import com.auth0.kotlingraphql.repository.SnackRepository
import com.coxautodev.graphql.tools.GraphQLQueryResolver
import org.springframework.data.mongodb.core.MongoOperations
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import org.springframework.stereotype.Component

@Component
class SnackQueryResolver(val snackRepository: SnackRepository,
                         private val mongoOperations: MongoOperations) : GraphQLQueryResolver {
    fun snacks(): List<Snack> {
        val list = snackRepository.findAll()
        for (item in list) {
            item.reviews = getReviews(snackId = item.id)
        }
        return list
    }

    private fun getReviews(snackId: String): List<Review> {
        val query = Query()
        query.addCriteria(Criteria.where("snackId").`is`(snackId))
        return mongoOperations.find(query, Review::class.java)
    }
}


You are creating this class to support the queries defined in the snack.graphqls file, hence the name SnackQueryResolver. The class implements an interface (GraphQLQueryResolver) provided by the GraphQL dependency you added earlier to your project. The class is also annotated with @Component to configure it as a Spring component (meaning that Spring will automatically detect this class for dependency injection).

Remember that the query type in the snack.graphqls looks like this:

type Query {
    snacks: [Snack]
}


As such, the SnackQueryResolver class contains one public function named snacks which returns a list of snacks. Notice that the field name corresponds to the function name. This is important because, otherwise, Spring wouldn’t know that you want this function to resolve the snacks query.

In the snacks function, the snackRepository is used to findAll() the snacks from the database. Then, for each snack, all the reviews are fetched alongside.

The next class you should create is called SnackMutationResolver. Create it inside the resolvers package then add the following code to it:

// .src/main/kotlin/com/auth0/kotlingraphql/resolvers/SnackMutationResolver.kt

package com.auth0.kotlingraphql.resolvers

import com.auth0.kotlingraphql.entity.Snack
import com.auth0.kotlingraphql.repository.SnackRepository
import com.coxautodev.graphql.tools.GraphQLMutationResolver
import org.springframework.stereotype.Component
import java.util.*

@Component
class SnackMutationResolver (private val snackRepository: SnackRepository): GraphQLMutationResolver {
    fun newSnack(name: String, amount: Float): Snack {
        val snack = Snack(name, amount)
        snack.id = UUID.randomUUID().toString()
        snackRepository.save(snack)
        return snack
    }

    fun deleteSnack(id:String): Boolean {
        snackRepository.deleteById(id)
        return true
    }

    fun updateSnack(id:String, amount:Float): Snack {
        val snack = snackRepository.findById(id)
        snack.ifPresent {
            it.amount = amount
            snackRepository.save(it)
        }
        return snack.get()
    }
}


You are creating this class to resolve the mutations defined in the snack.graphqls file. As such, you have the following functions in this class:

  • JDK: This is the Java Platform, Standard Edition Development Kit. Normally, this environment is used for developing Java applications but, since Kotlin runs on the JVM (just like Java), you need it. You can download JDK from here.
  • IntelliJ IDEA: This is an IDE (Integrated Development Environment) built by JetBrains and used for developing Java and Kotlin applications. They have both the paid version and the free (community) version. You can download the IDE right here.
  • MongoDB: A document-oriented database that stores data in a Binary JSON (BSON) format. One of the advantages of this database is that you don’t need a predefined schema (as such, you have maximum flexibility when it comes to change this schema over time). If you don’t have it, you can follow this manual to install MongoDB.

Next, you will create resolvers for the review.graphqls schema. So, create another class inside the resolvers package named ReviewQueryResolver and add this code to it:

// .src/main/kotlin/com/auth0/kotlingraphql/resolvers/ReviewQueryResolver.kt

package com.auth0.kotlingraphql.resolvers

import com.auth0.kotlingraphql.entity.Review
import com.coxautodev.graphql.tools.GraphQLQueryResolver
import org.springframework.data.mongodb.core.MongoOperations
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import org.springframework.stereotype.Component

@Component
class ReviewQueryResolver(val mongoOperations: MongoOperations) : GraphQLQueryResolver {
    fun reviews(snackId: String): List<Review> {
        val query = Query()
        query.addCriteria(Criteria.where("snackId").`is`(snackId))
        return mongoOperations.find(query, Review::class.java)
    }
}


The ReviewQueryResolver class handles the reviews property defined in the review.graphqls file. As such, this class contains only one function, reviews, which returns a list of reviews from the database depending on the snackId passed in.

Finally, you will create the last class in this section (still in the resolvers package). You will call it ReviewMutationResolver and add this code to it:

// .src/main/kotlin/com/auth0/kotlingraphql/resolvers/ReviewMutationResolver.kt

package com.auth0.kotlingraphql.resolvers

import com.coxautodev.graphql.tools.GraphQLMutationResolver
import com.auth0.kotlingraphql.entity.Review
import com.auth0.kotlingraphql.repository.ReviewRepository
import org.springframework.stereotype.Component

@Component
class ReviewMutationResolver (private val reviewRepository: ReviewRepository): GraphQLMutationResolver {
    fun newReview(snackId: String, rating: Int, text:String): Review {
        val review = Review(snackId, rating, text)
        reviewRepository.save(review)
        return review
    }
}


The resolver here is for the mutation field in the review.graphqls file. In this function, a new review is added to the database using a snack id, rating value and text.

Running Your App

With the resolvers you’ve just created, anytime a client application constructs a query, your functions will be able to provide the results for the requested fields. As such, you are ready to take your app for a spin. To run your Spring Boot and Kotlin application, you have two alternatives. You can either use the play button that is (most likely) available in your IDE, or you can use a terminal to issue the following command from project root:

./gradlew bootRun


Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
After your application is up and running, open http://localhost:9000/graphiql on your browser. There, you will see a GraphiQL client app that you can use to test your API.

On that application, you can use a mutation to add a newSnack. To see this in action, copy and paste the following code into the left-hand side panel and click on the play button (or hit Ctrl + Enter in your keyboard):

mutation {
  newSnack(name: "French Fries", amount: 40.5) {
    id
    name
    amount
  }
}


If everything runs as expected, you will get the following result back:

{
  "data": {
    "newSnack": {
      "id": "da84885b-b160-4c09-a5ea-3484bac4d5f9",
      "name": "French Fries",
      "amount": 40.5
    }
  }
}


You just created a new snack. Awesome, right? Now, you can create a review for this snack:

mutation {
    newReview(snackId:"SNACK_ID",
    text: "Awesome snack!", rating:5 
    ){
        snackId, text, rating
    }
}


Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
Running this command will result in the following response:

{
  "data": {
    "newReview": {
      "snackId": "da84885b-b160-4c09-a5ea-3484bac4d5f9",
      "text": "Awesome snack!",
      "rating": 5
    }
  }
}


Now, to fetch the snacks and reviews persisted in your database, you can issue the following query:

query {
  snacks {
    name,
    reviews {
      text, rating
    }
  }
}


Running this query will get you back a response similar to this:

{
  "data": {
    "snacks": [
      {
        "name": "French Fries",
        "reviews": [
          {
            "text": "Awesome snack!",
            "rating": 5
          }
        ]
      }
    ]
  }
}


This is the beauty of GraphQL. With just one query you can decide what is the exact format you need for the result.

Securing Spring Boot, Kotlin, and GraphQL APIs with Auth0

As expected, your GraphQL API is working perfectly. However, you need to add a little more spice to it. For example, you probably don’t want to allow unauthenticated users to consume your API, right? One easy way to fix this is to integrate your app with Auth0.

So, if you don’t have an Auth0 account yet, now is a good time to create a free one. Then, after signing up (or signing in), head to the APIs section of your Auth0 dashboard and click on the Create API button. Then, fill in the form that Auth0 shows as follows:

  • JDK: This is the Java Platform, Standard Edition Development Kit. Normally, this environment is used for developing Java applications but, since Kotlin runs on the JVM (just like Java), you need it. You can download JDK from here.
  • IntelliJ IDEA: This is an IDE (Integrated Development Environment) built by JetBrains and used for developing Java and Kotlin applications. They have both the paid version and the free (community) version. You can download the IDE right here.
  • MongoDB: A document-oriented database that stores data in a Binary JSON (BSON) format. One of the advantages of this database is that you don’t need a predefined schema (as such, you have maximum flexibility when it comes to change this schema over time). If you don’t have it, you can follow this manual to install MongoDB.

Then, click on the create button to finish the process and head back to your project. There, open your build.gradle file and add the Spring OAuth2 dependency:

// ...

dependencies {
  // ...
  implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.1.3.RELEASE'
}

// ...


Next, open the application.properties file (located in the kotlingraphql/src/main/resources/ directory) and add these two properties:

# ...
security.oauth2.resource.id=<YOUR-AUTH0-API-IDENTIFIER>
security.oauth2.resource.jwk.keySetUri=https://<YOUR-AUTH0-DOMAIN>/.well-known/jwks.json


Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
Now, create a new class called SecurityConfig inside the com.auth0.kotlingraphql package and add the following code to it:

// .src/main/kotlin/com/auth0/kotlingraphql/SecurityConfig.kt

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer

@Configuration
@EnableResourceServer
class SecurityConfig : ResourceServerConfigurerAdapter() {

    @Value("\${security.oauth2.resource.id}")
    private lateinit var resourceId: String

    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {
        http.authorizeRequests()
            .mvcMatchers("/graphql").authenticated()
            .anyRequest().permitAll()
    }

    @Throws(Exception::class)
    override fun configure(resources: ResourceServerSecurityConfigurer) {
        resources.resourceId(resourceId)
    }
}


Spring Boot will automatically detect this class and configure the integration with Auth0 for you (by using the properties you defined above). Also, as you can see in the code, this class will ensure that any request to /graphql is authenticated() and that other requests (like to the GraphiQL client app) are permitted (permitAll()).

Note: If you use Eclipse or NetBeans, apparently, you are covered. JetBrains (the creator of Kotlin and of IntelliJ IDEA) maintains plugins for both these IDEs (here and here). However, we haven’t tested these plugins and can’t guarantee they will work as expected.
With that in place, stop the running instance of your app (which is still insecure) then rerun it (remember, you can also use your IDE to run it):

./gradlew bootRun


After running your API, open the GraphiQL client tool, and you will see that you get an error instantaneously. This happens because this tool issues a query (without authentication) right after loading and because your API is secured now.

To be able to issue requests again to your API, you will need an access token. The process of getting a token will depend on what type of client you are dealing with. This is out of scope here but, if you are dealing with a SPA application (like those created with React, Angular, and Vue.js), you can use the [auth0-js](https://auth0.com/docs/libraries/auth0js/v9 "auth0-js") NPM library. If you are dealing with some other type of client (e.g., regular web application or native application), check the Auth0’s docs for more info.

Nevertheless, to see the whole thing in action, you can head back to your Auth0 Dashboard, open the API you created before, and move to the Test section. On this section, you will see a button called Copy Token that will provide you a temporary token that you can use to test your API.

After clicking on this button, Auth0 will move the token to your clipboard, and you will be able to use it to issue requests. However, as the GraphiQL tool does not have a place to configure the access token on the request, you will need another client. For example, you can use Postman (a popular HTTP graphical client) or you can use curl (a command-line program) to issue requests with headers.

No matter what HTTP client you choose, you will have to configure it to use a header called Authorization with a value that looks like Bearer <YOUR-TOKEN>. Note that you will have to replace <YOUR-TOKEN> with the token you copied from the Auth0 dashboard.

For example, if you are using curl, you can issue a query request to your GraphQL API as follows:

# set a local variable with the token
TOKEN=<YOUR-TOKEN>

# issue the query request
curl -X POST -H 'Authorization: Bearer '$TOKEN -H 'Content-Type: application/json' -d '{
  "query": "{ snacks { name } }"
}' http://localhost:9000/graphql


Done! You have just finished securing your Kotlin and GraphQL API with Auth0. How cool was that?

Troubleshooting

If you encounter an OAuth2 Spring error creating a bean with name [springSecurityFilterChain](https://stackoverflow.com/questions/47866963/oauth2-spring-error-creating-bean-with-name-springsecurityfilterchain "springSecurityFilterChain") error, you will have to add these dependencies to your build.gradle file:

// ./build.gradle

// ...

dependencies {
    // ...
    implementation 'javax.xml.bind:jaxb-api:2.3.0'
    implementation 'com.sun.xml.bind:jaxb-core:2.3.0'
    implementation 'com.sun.xml.bind:jaxb-impl:2.3.0'
    implementation 'javax.activation:activation:1.1.1'
}

// ...


After adding these new dependencies, sync your Gradle files and try running your app again. If you still have trouble, ping us on the comments box below.

Learn More

The Modern GraphQL Bootcamp (Advanced Node.js)

NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

GraphQL with React: The Complete Developers Guide

GraphQL API with AWS and Use with React

Developing and Securing GraphQL APIs with Laravel

An introduction GraphQL with AWS AppSync

Getting started with GraphQL and TypeScript

*Originally published by Idorenyin Obong at *https://auth0.com

Spring Boot Authorization Tutorial: Secure an API (Java)

Learn how to use Spring Boot, Java, and Auth0 to secure a feature-complete API. Learn how to use Auth0 to implement authorization in Spring Boot.

Learn how to secure an API with the world’s most popular Java framework and Auth0.

So far, you’ve built an API that allows anyone to read and write data. It’s time to tighten the security, so only users with the menu-admin role can create, update, and delete menu items.

Authentication vs. Authorization

To know what a user can do, you first need to know who the user is. This is known as authentication. It is often done by asking for a set of credentials, such as username & password. Once verified, the client gets information about the identity and access of the user.

To implement these Identity and Access Management (IAM) tasks easily, you can use OAuth 2.0, an authorization framework, and OpenID Connect (OIDC), a simple identity layer on top of it.

OAuth encapsulates access information in an access token. In turn, OpenID Connect encapsulates identity information in an ID token. The authentication server can send these two tokens to the client application initiating the process. When the user requests a protected API endpoint, it must send the access token along with the request.

You won’t have to worry about implementing OAuth, OpenID Connect, or an authentication server. Instead, you’ll use Auth0.

Auth0 is a flexible, drop-in solution to add authentication and authorization services to your applications. Your team and organization can avoid the cost, time, and risk that comes with building your own solution. Also, there are tons of docs and SDKs for you to get started and integrate Auth0 in your stack easily.

#spring boot authorization tutorial: secure an api (java) #spring boot #api (java) #authorization #spring boot authorization tutorial #api

Quartz Scheduler using Rest API with Spring Boot and MongoDB

This article demonstrates how to implement and manage Quartz Scheduler using Rest API with Spring Boot and MongoDB

Introduction

Quartz is a job scheduling library that can be integrated into a wide variety of Java applications. Quartz is generally used for enterprise-class applications to support process workflow, system management actions and to provide timely services within the applications And quartz supports clustering.

MongoDB is a cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas. MongoDB is developed by MongoDB Inc. and licensed under the Server Side Public License.

#spring-boot #quartz #quartz-scheduler #rest-api #mongodb #quartz scheduler using rest api with spring boot and mongodb

Maryse  Reinger

Maryse Reinger

1625802780

Spring Data MongoDB Delete Operation |Spring Boot+Spring Data MongoDb+MongoTemplate Delete

Spring Data MongoDB - Delete document | Spring Data MongoDB Delete Operation | Spring Boot MongoDB Delete

Hello and namaste everyone,

Today, we are learning how to delete a document in spring data mongodb. We are using mongoTemplate to delete the document. Spring Data MongoDB provides different functions to delete the document. we will understand the difference between these functions and their usage.

#springDataMongoDb #springDataMongodbDelete #mongoTemplate #springBooot #javaMongodb #smartyetchFizz

Email at: smartytechfizz@gmail.om
Follow on Instagram: https://www.instagram.com/smartytechfizz/

#spring data mongodb #mongodb #spring boot #spring data mongodb #mongotemplate delete

Top 10 API Security Threats Every API Team Should Know

As more and more data is exposed via APIs either as API-first companies or for the explosion of single page apps/JAMStack, API security can no longer be an afterthought. The hard part about APIs is that it provides direct access to large amounts of data while bypassing browser precautions. Instead of worrying about SQL injection and XSS issues, you should be concerned about the bad actor who was able to paginate through all your customer records and their data.

Typical prevention mechanisms like Captchas and browser fingerprinting won’t work since APIs by design need to handle a very large number of API accesses even by a single customer. So where do you start? The first thing is to put yourself in the shoes of a hacker and then instrument your APIs to detect and block common attacks along with unknown unknowns for zero-day exploits. Some of these are on the OWASP Security API list, but not all.

Insecure pagination and resource limits

Most APIs provide access to resources that are lists of entities such as /users or /widgets. A client such as a browser would typically filter and paginate through this list to limit the number items returned to a client like so:

First Call: GET /items?skip=0&take=10 
Second Call: GET /items?skip=10&take=10

However, if that entity has any PII or other information, then a hacker could scrape that endpoint to get a dump of all entities in your database. This could be most dangerous if those entities accidently exposed PII or other sensitive information, but could also be dangerous in providing competitors or others with adoption and usage stats for your business or provide scammers with a way to get large email lists. See how Venmo data was scraped

A naive protection mechanism would be to check the take count and throw an error if greater than 100 or 1000. The problem with this is two-fold:

  1. For data APIs, legitimate customers may need to fetch and sync a large number of records such as via cron jobs. Artificially small pagination limits can force your API to be very chatty decreasing overall throughput. Max limits are to ensure memory and scalability requirements are met (and prevent certain DDoS attacks), not to guarantee security.
  2. This offers zero protection to a hacker that writes a simple script that sleeps a random delay between repeated accesses.
skip = 0
while True:    response = requests.post('https://api.acmeinc.com/widgets?take=10&skip=' + skip),                      headers={'Authorization': 'Bearer' + ' ' + sys.argv[1]})    print("Fetched 10 items")    sleep(randint(100,1000))    skip += 10

How to secure against pagination attacks

To secure against pagination attacks, you should track how many items of a single resource are accessed within a certain time period for each user or API key rather than just at the request level. By tracking API resource access at the user level, you can block a user or API key once they hit a threshold such as “touched 1,000,000 items in a one hour period”. This is dependent on your API use case and can even be dependent on their subscription with you. Like a Captcha, this can slow down the speed that a hacker can exploit your API, like a Captcha if they have to create a new user account manually to create a new API key.

Insecure API key generation

Most APIs are protected by some sort of API key or JWT (JSON Web Token). This provides a natural way to track and protect your API as API security tools can detect abnormal API behavior and block access to an API key automatically. However, hackers will want to outsmart these mechanisms by generating and using a large pool of API keys from a large number of users just like a web hacker would use a large pool of IP addresses to circumvent DDoS protection.

How to secure against API key pools

The easiest way to secure against these types of attacks is by requiring a human to sign up for your service and generate API keys. Bot traffic can be prevented with things like Captcha and 2-Factor Authentication. Unless there is a legitimate business case, new users who sign up for your service should not have the ability to generate API keys programmatically. Instead, only trusted customers should have the ability to generate API keys programmatically. Go one step further and ensure any anomaly detection for abnormal behavior is done at the user and account level, not just for each API key.

Accidental key exposure

APIs are used in a way that increases the probability credentials are leaked:

  1. APIs are expected to be accessed over indefinite time periods, which increases the probability that a hacker obtains a valid API key that’s not expired. You save that API key in a server environment variable and forget about it. This is a drastic contrast to a user logging into an interactive website where the session expires after a short duration.
  2. The consumer of an API has direct access to the credentials such as when debugging via Postman or CURL. It only takes a single developer to accidently copy/pastes the CURL command containing the API key into a public forum like in GitHub Issues or Stack Overflow.
  3. API keys are usually bearer tokens without requiring any other identifying information. APIs cannot leverage things like one-time use tokens or 2-factor authentication.

If a key is exposed due to user error, one may think you as the API provider has any blame. However, security is all about reducing surface area and risk. Treat your customer data as if it’s your own and help them by adding guards that prevent accidental key exposure.

How to prevent accidental key exposure

The easiest way to prevent key exposure is by leveraging two tokens rather than one. A refresh token is stored as an environment variable and can only be used to generate short lived access tokens. Unlike the refresh token, these short lived tokens can access the resources, but are time limited such as in hours or days.

The customer will store the refresh token with other API keys. Then your SDK will generate access tokens on SDK init or when the last access token expires. If a CURL command gets pasted into a GitHub issue, then a hacker would need to use it within hours reducing the attack vector (unless it was the actual refresh token which is low probability)

Exposure to DDoS attacks

APIs open up entirely new business models where customers can access your API platform programmatically. However, this can make DDoS protection tricky. Most DDoS protection is designed to absorb and reject a large number of requests from bad actors during DDoS attacks but still need to let the good ones through. This requires fingerprinting the HTTP requests to check against what looks like bot traffic. This is much harder for API products as all traffic looks like bot traffic and is not coming from a browser where things like cookies are present.

Stopping DDoS attacks

The magical part about APIs is almost every access requires an API Key. If a request doesn’t have an API key, you can automatically reject it which is lightweight on your servers (Ensure authentication is short circuited very early before later middleware like request JSON parsing). So then how do you handle authenticated requests? The easiest is to leverage rate limit counters for each API key such as to handle X requests per minute and reject those above the threshold with a 429 HTTP response. There are a variety of algorithms to do this such as leaky bucket and fixed window counters.

Incorrect server security

APIs are no different than web servers when it comes to good server hygiene. Data can be leaked due to misconfigured SSL certificate or allowing non-HTTPS traffic. For modern applications, there is very little reason to accept non-HTTPS requests, but a customer could mistakenly issue a non HTTP request from their application or CURL exposing the API key. APIs do not have the protection of a browser so things like HSTS or redirect to HTTPS offer no protection.

How to ensure proper SSL

Test your SSL implementation over at Qualys SSL Test or similar tool. You should also block all non-HTTP requests which can be done within your load balancer. You should also remove any HTTP headers scrub any error messages that leak implementation details. If your API is used only by your own apps or can only be accessed server-side, then review Authoritative guide to Cross-Origin Resource Sharing for REST APIs

Incorrect caching headers

APIs provide access to dynamic data that’s scoped to each API key. Any caching implementation should have the ability to scope to an API key to prevent cross-pollution. Even if you don’t cache anything in your infrastructure, you could expose your customers to security holes. If a customer with a proxy server was using multiple API keys such as one for development and one for production, then they could see cross-pollinated data.

#api management #api security #api best practices #api providers #security analytics #api management policies #api access tokens #api access #api security risks #api access keys