Easy tutorial of GraphQL compared with REST API
Tags: graphql, restapi, backend
Published: 2024-03-25 11:33:14

You will see the word of "GraphQL" on the requirements of recent JDs on job hunting platforms. We've used REST API as a mainstream of standerds in modern Web API development. But a lot of companies had started to use GraphQL for some specific advantage against REST API. This article contributes to learn GraphQL by comparison with REST API.

# Endpoint

## REST API
It should representive the resource and be expressed as noun and plural. And create endpoints as many as the number of resources

`https://localhost:8080/customers`
`https://localhost:8080/products`

Frequently you use path parameters when specify the entity in the collection

`https://localhost:8080/products/123`

Append slash(/) when you wanna express hierarchical relationship of resources.

`https://localhost:8080/products/123/orders`

## GraphQL
It has only one endpoint `/graphql`

`https://localhost:8080/graphql`

# CRUD

## REST API
It represents CRUD by the HTTP method

|CRUD|HTTP Method|endpoint|
| --- | --- | --- |
| Read | GET | /customers/123 |
| Create | POST | /customers |
| Update | PUT(PATCH) | /customers/123 |
| Delete | DELETE | /customers/123 |

## GraphQL
It only have the comception of Query(fetch) and Mutation(update)

|Operation|CRUD|HTTP Method|endpoint|
| --- | --- | --- | --- |
| Query | Read | POST | /graphql |
| Mutation | Create, Update, Delete | POST | /graphql |

Then how can you distinguish the operations in mutation? The answer is `schema` and `resolver`. You will define functions to read/update. 
`schema` is a kind of interface. You will define the mapping of the functions for CRUD.

### schema.js
```    
   type Query {
        getProduct(id: String): Product
    }
    type Mutation {
        createProduct(input: ProductInput): Product
        updateProduct(input: ProductInput): Product
        deleteProduct(id: String): String
    }

```

`resolver` is the implementation for schema. It's an example written in Javascript.

### resolver.js
```
const resolvers = {
  getProduct: ({ id }) => {
    ...
  },
  createProduct: ({ input }) => {
    ...
  },
  updateProduct: ({ input }) => {
    ...
  },
  deleteProduct: ({ id }) => {
    ...
  },
};
```

# Parameters

## REST API
Generally you may spacify the parameters below.

### query parameter
Especially for additional configurations like filter, pagenation ...

`https://localhost:8080/products?page=3`

### path parameter
Mainly to specify each entity on the collection of resources.

`https://localhost:8080/products/123`

### request body
To update resource and in JSON format.

```
{
  "id": 123,
  "name": "Water Bottle",
  "price": 11.99,
  "stock": 100
}
```

## GraphQL
You will specify every thing on a query, including operation, function in resolver and data structure. You can control which parameter it should return as a response.

```
Query {
  // resolver and request parameters
  getProduct(id: 123): {
    // response parameters
    name,
    price
  }
}
```

```
Mutation {
  // resolver
  updateProduct(
    // requrest parameters
    input:{
      id: 123,
      name: "Water Bottle",
      price: 11.99,
      stock: 100
    }
  ) {
    // response parameters
    name,
    price
  }
}
```

You will define the data structure in `schema`.

```
    type Product {
        id: ID,
        name: String,
        price: Float,
        stock: Int,
    }
```

Those parameters will be sent to as JSON, but as a "String" formated parameter in JSON, unlikely REST API

```
POST /graphql HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer <access_token>

{
  "query": "query { ... }", <- Like this
  "variables": { ... },
  "operationName": "MyQuery"
}
```

# Library

## REST API
REST API is a specification. You can implement without libraries.

## GraphQL
Usually, you use a library to implement because it needs complex task like analysing queries, defining schema and generating response.

[Libraries for GraphQL](https://graphql.org/code/)

# Version management

## REST API
You will add the version information on endpoints if necessary.

`https://localhost:8080/v1/customers`

## GraphQL
Don't need to manage. You'll just change `schema` to modify the interface.

# Stateless
REST API and GraphQL are both stateless. Each request is independent and doesn't influence the subsequent requests.

# When to use

## REST API
- The data structure needs to be hierarchic.
- Able to express simple CRUD operations to specific resource.
- Heavier traffic.
- More simple design on server side.

## GraphQL
- The data structure is complex.
- Fetch from multiple resources.
- Lighter traffic.
- More complex design on server side.

# Conclution
In conclusion, both REST API and GraphQL have their strengths and weaknesses, and choosing between them depends on various factors such as the complexity of data requirements, traffic volume, and design preferences. 

REST API, with its hierarchical data structure and straightforward CRUD operations, is suitable for scenarios where simplicity and scalability are key. It excels in scenarios where the data can be easily represented as resources and standard HTTP methods suffice for CRUD operations. However, it may lead to over-fetching or under-fetching of data in certain situations, and managing multiple versions of endpoints can become cumbersome.

On the other hand, GraphQL shines in situations where the data structure is complex and the client needs flexibility in fetching data from multiple resources. It allows clients to request only the data they need, reducing over-fetching and under-fetching, and providing a more efficient way to interact with data APIs. However, GraphQL comes with a learning curve and requires a more complex design on the server side to define schemas and resolvers.

Ultimately, the choice between REST API and GraphQL depends on the specific requirements of the project, the skillset of the development team, and the desired trade-offs between simplicity and flexibility. Each has its place in modern web development, and understanding their strengths and weaknesses is crucial in making informed decisions for building robust and efficient APIs.