GraphQL is an API technology created by Facebook engineers in 2012 to try to solve the over-fetching of information problems that come with REST API implementations. Usually, when you create a REST API, on rare occasions, you define the list of fields or information that is important to the stakeholder; usually, you take care only of the input parameters, resources, and methods to consume the API independently of other aspects like security or result format.
GraphQL is used for a query language where the stakeholder can specify what information is fetched from under-layer services. This information is represented in a graph-like data structure. This data is defined in a strong type structure called Schema. This schema is composed of fields, types, arguments, directives, and operations.
At the same time, like other specifications, we have primitive types to define strings, numbers, or binary values. Additionally, we can define objects (and their interfaces) and other data collections like lists and enums. Until this point, maybe you’re thinking that it is a copy of Swagger or any other API specification language.
The power of GraphQL comes from the capability to choose the information that the client needs, but this capability is not only limited to using a subset of the field of one schema, also you can composite multiple queries in one operation. To define this behavior, GraphQL uses operations and functions. Those functions are called Resolvers or DataFetchers. They are tied to a set of input arguments and a return type.
Finally, we can find all the concepts that we defined previously in the GraphQL request. A GraphQL request is an HTTP request that usually uses the POST method with a JSON body where we define the graph queries (yes, we can composite a request with multiple resolvers) and its input arguments and expected fields. Also, the request can include http headers.
GraphQL APIs are agnostic, meaning that they are not tied to a specific programming language. For this example, we will use Java with a popular implementation developed by Netflix. Actually, GraphQL is one of Netflix’s biggest bets in its API architecture.
To use Netflix Domain Graph Service Framework (DGS) , you need Java 17 or Kotlin, and SpringBoot 3.x. After creating your Java application, you only need to add the DGS dependencies and define a schema and a resolver class.
GraphQL is designed to be a schema/documentations first API. It means that you need to have a schema document where you define the data types and operations before the code implementation. The schema could be split in multiple *.graphqls files, it helps to create reusable types that you share across java projects. At least you need one schema file in src/main/resources/schema/schema.graphqls path.
The resolver is a Java class annotated with @DgsComponent. This enables an endpoint, this is the equivalent to @RestController annotations of a REST API. Then you need to define java methods that will work as queries operations using @DgsQuery annotation. Optionally, each method can receive arguments using @InputArgument annotation and a DgsDataFetchingEnvironment. The return type is a POJO class without any special features.
Given that GraphQL APIs run over HTTP, you can use any HTTP client to consume it. For example, you can use curl, Postman, or some GraphQL client/library. If you are using DGS in your backend application, it enables by default a GUI for test proposal that you can access through your web browser at http://localhost:8080/graphiql.
Please keep in mind that the Request and Response section of the graphql interface parse and remove some details of the HTTP body.
A raw HTTP request looks like this:
GraphQL is a mature technology that big companies have adopted and it is widely used as the first API layer to build microservices for multiple proposals, mainly for web applications and mobile applications. In this article, we introduce a high level concepts and usage of this technology, however there are a lot of considerations to take care to improve the provider application performance. A correct implementation of resolver is the key to benefitting from GraphQL regardless of the programming language used to implement it.