Skip to content
Menu
Rohit Naik Kundaikar
  • Home
  • Contact
Rohit Naik Kundaikar

Moving beyond REST to GraphQL

Posted on November 27, 2020December 10, 2020 by Rohit Naik Kundaikar

GraphQL in simple terms is a querying language for your API that lets the client i.e UI query on the data fetched by the API.

GraphQL is not tied to any database it is instead linked to your API data, which API might have fetched from the database. Thus Graphql could easily be integrated with your existing API service. If you still have doubts in understanding what is GraphQL then the last section of this post would clear it.

Below are some of the advantages of using GraphQL API

  • Ask for what you need, get exactly that: Send a GraphQL query to your API and get exactly which fields you need, nothing more and nothing less, unlike REST where you would give all the fields.
  • Get many resources in a single request: Unlike REST APIs which requires loading from multiple URLs, GraphQL APIs get all the data your app needs in a single request. Thus apps using GraphQL can be quicker even on slow mobile network connections.
  • Evolve your API without versions: Add new fields and types to your GraphQL API without impacting existing queries.

All that being said let’s get into the coding aspect. In this post, you will see how you can set up GraphQL in a Springboot project. For demonstration, we would be creating a spring boot application that gives users details.

Step 1 : Schema & Type

In your spring boot project create a GraphQL file in the resource directory. Define an entity or type called “User” and add all the fields that the API could possibly send.

Next, provide a query. Queries in GraphQL are like endpoints in REST API.

In our example, we would write two GraphQL queries one would fetch all users while other would fetch a specific user.

schema.graphql

type User {
    name: String
    address: String
    id: String
    age: Int
}

type Query {
allUsers: [User]
user(id: String): User
}

schema {
query: Query
}

Step 2 : Datafetcher & Service

Datafetchers job is to get the data from the application and send it to GraphQL service which then maps datafetchers classes with the queries defined in the schema.

Each query is linked to a particular dataFetcher class for ex in our demo “allUsers” query is linked to AllUsersDataFetcher class and “user” query is linked to UserDataFetcher class.

GraphQL service exposes one public function “getGraphQL()” that is used by the controllers class to execute the POST request query sent by UI and returns the query result.

@Service
public class GraphqlService {

    @Value("classpath:users.graphql")
    Resource resource;

    @Autowired
    AllUsersDataFetcher allUsersDataFetcher;

    @Autowired
    UserDataFetcher userDataFetcher;

    private GraphQL graphQL;

    @PostConstruct
    private void GraphqlService() throws IOException {
        File schemaFile = resource.getFile();
        TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(schemaFile);
        RuntimeWiring wiring = buildRuntimeWiring();
        GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeRegistry, wiring);
        graphQL = GraphQL.<em>newGraphQL</em>(schema).build();
    }
    
    private RuntimeWiring buildRuntimeWiring() {
        return RuntimeWiring.<em>newRuntimeWiring</em>()
                .type("Query", typeWiring -> typeWiring
                        .dataFetcher("allUsers", allUsersDataFetcher)
                        .dataFetcher("user", userDataFetcher)
                )
                .build();
    }
    
    public GraphQL getGraphQL() {
        return graphQL;
    }
}
@Component
public class UserDataFetcher implements DataFetcher {
    @Override
    public Object get(DataFetchingEnvironment environment) {
        Users u1 = new Users();
        Users u2 = new Users();
        // Query the database and set the users object
        // For this example lets hardcode the output
        u1.setAddress("at home");
        u1.setAge(32);
        u1.setId("1");
        u1.setName("Duck");
        u2.setAddress("at home");
        u2.setAge(12);
        u2.setId("2");
        u2.setName("Bear");
        String id = environment.getArgument("id");

        return (id == "1") ? u1 : u2;
    }
@Component
public class AllUsersDataFetcher implements DataFetcher {
    @Override
    public Object get(DataFetchingEnvironment environment) {
        List<Users> users = new ArrayList<>();
        // Query the database and set the users object
        // For this example lets hardcode the output
        Users u1 = new Users();
        Users u2 = new Users();
        u1.setAddress("at home");
        u1.setAge(32);
        u1.setId("1");
        u1.setName("Duck");
        u2.setAddress("at home");
        u2.setAge(12);
        u2.setId("2");
        u2.setName("Bear");
        users.add(u1);
        users.add(u2);
        return users;
    }
}

Step 3 : Endpoint

One endpoint for your entire project, how fascinating. Yes, there is just one endpoint for the entire application. You can execute all the queries against a single “/graphql” endpoint.

Note unlike REST API, GraphQL doesn’t support GET, DELETE or PUT request, it works on POST request only and beside you really don’t need them in GraphQL implementation. Since to GET or DELETE all that you would need to do is write a DELETE or GET query.

Below is Controller class that exposes “/graphql” endpoint, it receives Query as RequestBody which is then passed to GraphQL Service. Service then executes the query and return the query result.

@RestController
public class UsersController implements UsersControllerInterface {

@Autowired
GraphqlService graphqlService;

@PostMapping("/graphql")
@Override
public ResponseEntity<Object> getAllUsers(@RequestBody String query) {
      ExecutionResult execute = graphqlService.getGraphQL().execute(query);
      return new ResponseEntity<>(execute, HttpStatus.<em>OK</em>);
  }
}

Step 4 : Execute Query

Make a simple POST request to the “graphql” endpoint and pass the query that you want to execute, along with fields that you would like to receive in return.

In the below screenshot you would see we are executing “allUsers” query and asking for name, age, and address field only and that is exactly what you get.

Thus avoiding over fetching of data and also the need to create a separate API in case of REST approach.

Single Query Execution

Generally in applications, you would see there are many API calls that are made upon the page load thus consuming more network and server resources.

With help of GraphQL implementation, you can minimize network and server resources consumption by combining all these initial API calls into a single call and achieve better performance.

In the below request we are executing both “allUsers” and “user” query in a single request and getting output together.

Multiple Query Execution

Hope this was helpful in shedding some light on GraphQL implementation.

As always you can find the source code for this project at my GitHub repo https://github.com/thatsrohitnaik/Springboot-GraphQL

Happy Coding !!

API, GraphQL, Java, Spring Boot

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Typescript Guide – Part 1
  • Vite Micro Frontend
  • React Best Practice: Part 2
  • React Best Practices: Part 1
  • Redux Toolkit

Recent Comments

    Archives

    • August 2024
    • January 2024
    • September 2021
    • July 2021
    • June 2021
    • May 2021
    • April 2021
    • December 2020
    • November 2020
    • October 2020
    • September 2020

    Categories

    • Angular
    • API
    • Best Practice
    • Compiler
    • Context
    • DevOps
    • Docker
    • FAANG
    • Forms
    • GraphQL
    • Java
    • Javascript
    • Machine Learning
    • MobX
    • Python
    • ReactJS
    • Redux Toolkit
    • Spring Boot
    • Typescript
    • Uncategorized
    • Vite
    • Webpack
    ©2025 Rohit Naik Kundaikar | Powered by WordPress & Superb Themes