Intro to GraphQL

Intro to GraphQL

2021, Jan 03    

GraphQL is a query language for your API that allows clients to request exactly the data they need, and nothing more. It was developed and open-sourced by Facebook in 2015 and has since become a popular alternative to REST (Representational State Transfer) APIs.

One of the main features of GraphQL is the ability to specify exactly what data is needed in a single request. With REST APIs, the server determines the structure of the data that is returned, and the client must make multiple requests to retrieve all the data it needs. With GraphQL, the client can specify exactly which fields it wants to retrieve in a single request, making it more efficient and flexible.

Another feature of GraphQL is the ability to request nested data. With REST APIs, the client must make separate requests for each level of nested data, which can result in a large number of requests and a slower response time. With GraphQL, the client can request nested data in a single request, reducing the number of requests and improving performance.

GraphQL also has a strong type system that allows the server to describe the data it can provide and the client to specify what data it needs. This helps to ensure that the client only receives the data it needs and can prevent errors caused by requesting data that is not available.

When is it a good option to use GraphQL?

When you need more flexibility in the data that is returned from the API. With GraphQL, the client can specify exactly which fields it wants, allowing it to retrieve only the data it needs. This can be useful when building client applications that need to display data in different ways or when the data model is constantly changing.

When you need to retrieve nested data in a single request. GraphQL’s ability to request nested data can greatly improve performance compared to making multiple requests with a REST API.

When you have a large number of API endpoints. With GraphQL, the client can request all the data it needs in a single request, rather than making multiple requests to different endpoints. This can simplify the API and reduce the number of requests that need to be made.

Overall, GraphQL is a powerful tool for building APIs that is particularly well-suited for situations where flexibility and performance are important considerations.

Small tutorial for a hello world

Here is an example of how to use GraphQL in a Spring Boot application as the server and a ReactJS app using TypeScript as the client:

Add the GraphQL dependency to your Spring Boot project. You can do this by adding the following line to your pom.xml file:


<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-spring-boot-starter</artifactId>
    <version>5.0.2</version>
</dependency>

Define your GraphQL schema. This is a file that defines the types and queries available in your GraphQL API. For example:

type Query {
hello: String
}

schema {
query: Query
}

Create a GraphQL resolver. This is a class that implements the logic for each of the queries defined in your schema. For example:


@Component
public class Query implements GraphQLQueryResolver {
    public String hello() {
        return "Hello, World!";
    }
}

Add a GraphQL endpoint to your Spring Boot application. You can do this by creating a GraphQLController class that exposes a /graphql endpoint and uses the GraphQL class from the graphql-java library to execute queries. For example:


@RestController
public class GraphQLController {
    private final GraphQL graphQL;

    public GraphQLController(GraphQL graphQL) {
        this.graphQL = graphQL;
    }

    @PostMapping("/graphql")
    public Map<String, Object> graphql(@RequestBody Map<String, String> request) {
        ExecutionResult result = graphQL.execute(ExecutionInput
                .newExecutionInput()
                .query(request.get("query"))
                .operationName(request.get("operationName"))
                .variables(request.get("variables")).build());

        return result.toSpecification();

    }
}

On the client side, you can use a GraphQL client library like apollo-client to make GraphQL queries to your server. To install apollo-client, run the following command in your ReactJS project:

npm install apollo-client @apollo/client graphql

Define your GraphQL queries and mutations as TypeScript interfaces. For example:

export interface HelloQuery {
hello: string;
}

export const HELLO_QUERY = gql`
query HelloQuery {
hello
}
`;

Use the useQuery hook from @apollo/client to execute your GraphQL queries. For example:

import {useQuery} from '@apollo/client';
import {HELLO_QUERY, HelloQuery} from './queries';

function Hello() {
    const {data, loading, error} = useQuery<HelloQuery>(HELLO_QUERY);

    if (loading) {
        return <p>Loading...</p>;
    }

    if (error) {
        return <p>Error :(</p>
    }
    return <p>{data.hello}</p>;
}

Use the useMutation hook from @apollo/client to execute your GraphQL mutations. For example:

import {useMutation} from '@apollo/client';
import {ADD_TODO_MUTATION, AddTodoMutation, TodosQuery} from './mutations';

function AddTodoForm() {
    const [addTodo, {loading, error}] = useMutation<AddTodoMutation>(ADD_TODO_MUTATION);

    const handleSubmit = (event: FormEvent) => {
        event.preventDefault();

        const form = event.target as HTMLFormElement;
        const input = form.elements.namedItem('text') as HTMLInputElement;

        addTodo({
            variables: {text: input.value},
            update: (cache, {data}) => {
                const todos = cache.readQuery<TodosQuery>({query: TODOS_QUERY});
                cache.writeQuery({
                    query: TODOS_QUERY,
                    data: {todos: todos.concat([data.addTodo])},
                });
            },
        });

        input.value = '';

    };

    return (
        <form onSubmit={handleSubmit}>
            <input type="text" name="text"/>
            <button type="submit" disabled={loading}>
                Add Todo
            </button>
            {error && <p>Error :(</p>}
        </form>
    );
}

That’s it! These are just a few examples of how you can use GraphQL in a Spring Boot application as the server and a ReactJS app using TypeScript as the client. There are many other features and techniques that you can use to build more complex and powerful GraphQL APIs and clients.