Try Vaadin's Visual View Builder for seamless collaboration, prototype sharing, and code generation.
Blog

Consuming GraphQL APIs from Java applications

By  
Viktor Lukashov
Viktor Lukashov
·
On Jan 31, 2023 2:29:05 PM
·

GraphQL has become a common alternative to REST as a way to provide data to modern web applications. They both solve the same problem, but GraphQL comes with a different set of trade-offs. It is designed to answer challenges pertinent to larger organizations, such as inter-team communication and development velocity.

Unlike REST, GraphQL puts more flexibility – and more work – into the hands of API client developers. And yet Java developers have the tools that make creating GraphQL clients easy and straightforward.

GraphQL vs. REST

REST is a widely used method for building APIs. There are established patterns and libraries to consume REST APIs from a Java application. They work very well, but REST is not a silver bullet. It has its pros and cons, and in a number of cases GraphQL is a better tool for the job.

For example, reasons to choose GraphQL over REST may be;

  • Clients have varying data needs, and they do not map well to REST endpoints. With GraphQL, the client can affect what gets returned from the server.
  • The server and the client are built by different teams.
  • There is a need for an API federation layer.
  • The client needs to get notified when data changes on the server side.

Let's take a look at the architecture of the example application:

GraphQL is a natural fit for the API gateway architecture pattern. The GraphQL server decouples client applications from the APIs and data sources and allows changing them independently. For example, if your Vaadin application directly calls multiple REST endpoints, swapping those to a GraphQL layer simplifies your Vaadin app significantly because all the "data combination" logic happens in the GraphQL API gateway rather than in the UI application.

Consider the case for adding one or more REST APIs. They can be added to the GraphQL schema without any changes to the client application.

Accessing a service using Spring GraphQL client

The Spring framework includes a simple but fully functional GraphQL client, based on the WebClient that you might have used for raw REST endpoints. Given a GraphQL API URL, you can create a client for it with a couple of lines of code:

@Value("${graphqlApiUrl}")
private String graphqlApiUrl;

GraphQlClient client;

@PostConstruct
void init() {
   WebClient wc = WebClient.create(graphqlApiUrl);
   client = HttpGraphQlClient.create(wc);
}

Creating a GraphQL client

The Spring GraphQL client provides a fluent API allowing to prepare requests with or without variables, and deserialise responses into pure Java objects. 

public LocationDTO findIpDetails(String ipOrDomainName) {
   String document = """
       query ipQuery($ip: String!) {
         ipApi_location(ip: $ip) {
           ip
           city
           country
           countryCode
           isp
           lat
           lon
         }
       }
   """;

   return client.document(document)
           .variable("ip", ipOrDomainName)
           .retrieve("ipApi_location")
           .toEntity(LocationDTO.class)
           .block();
}

Making a GraphQL API call

Check out the full source code of the example on GitHub.

Other approaches for Java to fetch data from a GraphQL service

While the approach by Spring’s GraphQL client is a nice combination of simplicity and features, in some cases, you might want to have more or less features. Here are a couple of alternatives you might want to check out.

  • SmallRye GraphQL Client, which implements Eclipse MicroProfile API. It contains two ways to access services; dynamic, which is similar in nature to Spring’s solution, and typesafe, that gives you a really natural Java API, but requires more coding. For the typesafe approach, there is an experimental generator that might be worth checking if you have a large GraphQL API that you plan to use a lot from your Java application.
  • graphql-java-generator does pretty much what you would expect based on its name: creates Java API based on GraphQL schema. It has a module for generating client API, that might be handy in large applications.
  • Sometimes less is more. If you are about to consume just a fraction of your GraphQL API, you might be better off without a special GraphQL library. GraphQL is finally just an HTTP request that you can issue using JDKs URL class or a generic HTTP library like Apache HttpClient

GraphQL servers

It’s important to keep in mind that using a GraphQL API client is very different from implementing a GraphQL service. The latter is a more complex task and it requires much more effort than shown in this post. While there are Java libraries for creating GraphQL services available for example in Spring and Quarkus, the best solution is to skip that part altogether. It is similar in complexity to implementing your own database server, and there is a very narrow set of use cases where “rolling your own” makes sense. Instead, we recommend looking into GraphQL service providers, such as StepZen.

Summary

GraphQL and REST are both solutions to similar problems, offering different trade-offs. The key reasons to choose GraphQL are the improved performance for users and a better development velocity for engineering teams. Java developers have an easy way to create a client for a GraphQL API, as demonstrated by the linked example. Creating a GraphQL server in Java is also possible, but we recommend using one of the existing GraphQL API hosting providers instead of “rolling your own”.

Viktor Lukashov
Viktor Lukashov
After 15+ years as engineer, architect, product manager and trainer Viktor is now building the next generation of developer tools for the StepZen GraphQL platform. When his passion for tech lets him go, you'll find Viktor chasing another passion - rock climbing.
Other posts by Viktor Lukashov