Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

One of the most significant paradigm changes over the last few years regarding client/server communication has been GraphQL, an open-source query language, and runtime for manipulating APIs. We can use it to request the exact data we need and therefore limit the number of requests we need.

Netflix created a Domain Graph Service Framework (DGS) server framework to make things even easier. In this quick tutorial, we’ll cover key features of the DGS Framework. We’ll see how to add this framework to our app and check how its basic annotations work. To learn more about GraphQL itself, check out our Introduction to GraphQL article.

2. Domain Graph Service Framework

Netflix DGS (Domain Graph Service) is a GraphQL server framework written in Kotlin and based on Spring Boot. It’s designed to have minimal external dependencies aside from the Spring framework.

The Netflix DGS framework uses an annotation-based GraphQL Java library built on top of Spring Boot. Besides the annotation-based programming model, it provides several useful features. It allows generating source code from GraphQL schemas. Let’s sum up some key features:

  • Annotation-based Spring Boot programming model
  • Test framework for writing query tests as unit tests
  • Gradle/Maven Code Generation plugin to create types from schema
  • Easy integration with GraphQL Federation
  • Integration with Spring Security
  • GraphQL subscriptions (WebSockets and SSE)
  • File uploads
  • Error handling
  • Many extension points

3. Configuration

Firstly, as the DGS framework is based on Spring Boot, let’s create a Spring Boot app. Then, let’s add the DGS dependency to our project:

<dependency>
    <groupId>com.netflix.graphql.dgs</groupId>
    <artifactId>graphql-dgs-spring-boot-starter</artifactId>
    <version>4.9.16</version>
</dependency>

4. Schema

4.1. Development Approaches

The DGS framework supports both development approaches – schema-first and code-first. But the recommended approach is schema-first, mainly because it’s easier to keep up with changes in the data model. Schema-first indicates that we first define the schema for the GraphQL service, and then we implement the code by matching the definitions in the schema. The framework picks up any schema files in the src/main/resources/schema folder by default.

4.2. Implementation

Let’s create a simple GraphQL schema for our example application using Schema Definition Language (SDL):

type Query {
    albums(titleFilter: String): [Album]
}

type Album {
    title: String
    artist: String
    recordNo: Int
}

This schema allows querying for a list of albums and, optionally, filtering by title.

5. Basic Annotation

Let’s start with creating an Album class corresponding to our schema:

public class Album {
    private final String title;
    private final String artist;
    private final Integer recordNo;

    public Album(String title, String artist, Integer recordNo) {
        this.title = title;
        this.recordNo = recordNo;
        this.artist = artist;
    }

    // standard getters
}

5.1. Data Fetcher

Data fetchers are responsible for returning data for a query. The @DgsQuery, @DgsMutation, and @DgsSubscription annotations are shorthands to define data fetchers on the Query, Mutation, and Subscription types. All mentioned annotations are equivalent to the @DgsData annotation. We can use one of these annotations on a Java method to make that method a data fetcher and define a type with a parameter.

5.2. Implementation

So, to define the DGS data fetcher, we need to create a query method in the @DgsComponent class. We want to query a list of Albums in our example, so let’s mark the method with @DgsQuery:

private final List<Album> albums = Arrays.asList(
  new Album("Rumours", "Fleetwood Mac", 20),
  new Album("What's Going On", "Marvin Gaye", 10), 
  new Album("Pet Sounds", "The Beach Boys", 12)
  );

@DgsQuery
public List<Album> albums(@InputArgument String titleFilter) {
    if (titleFilter == null) {
        return albums;
    }
    return albums.stream()
      .filter(s -> s.getTitle().contains(titleFilter))
      .collect(Collectors.toList());
}

We also marked arguments of the method with the annotation @InputArgument. This annotation will use the name of the method argument to match it with the name of an input argument sent in the query.

6. Code-Gen Plugin

DGS also comes with a code-gen plugin to generate Java or Kotlin code from GraphQL Schema. Code generation is typically integrated with the build.

The DGS Code Generation plugin is available for Gradle and Maven. The plugin generates code during our project’s build process based on our Domain Graph Service’s GraphQL schema file. The plugin can generate data types for types, input types, enums, and interfaces, sample data fetchers, and type-safe query API. There is also a DgsConstants class containing the names of types and fields.

7. Testing

A convenient way to query our API is GraphiQL. GraphiQL is a query editor that comes out of the box with the DGS framework. Let’s start our application on the default Spring Boot port and check the URL http://localhost:8080/graphiql. Let’s try the following query and test the result:

{
    albums{
        title
    }
}

Note that, unlike with REST, we have to specifically list which fields we want to be returned from our query. Let’s see the response:

{
  "data": {
    "albums": [
      {
        "title": "Rumours"
      },
      {
        "title": "What's Going On"
      },
      {
        "title": "Pet Sounds"
      }
    ]
  }
}

8. Conclusion

Domain Graph Service Framework is an easy and quite attractive way of using GraphQL. It uses higher-level building blocks to handle query execution and such. The DGS framework makes all this available with a convenient Spring Boot programming model. This framework has some useful features that we cover in the article.

We talked about configuring DGS in our app and looked at some of its basic annotations. Then, we wrote a simple application to check how to create data from the schema and query them. Finally, we tested our API by using GraphiQL. As always, the example can be found over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.