“Better API by Design” Why Choose GraphQL Over REST

When most software developers think of web APIs, they think of REST (REpresentational State Transfer). In REST, requests are sent to URLs for each request, and the results are received in a format appropriate for the application.

GraphQL, Meta’s web API system, is a different kind of API. In GraphQL, developers can specify exactly what data the application wants to get from the API by defining both requests and responses in a strictly typed query language. GraphQL is considered a more efficient, structured, and systematic alternative to REST.

ⓒ Getty Images Bank

In this article, we’ll explore the differences between GraphQL and REST, how they impact API design, and why GraphQL is often a better choice than REST for retrieving data from a server.

GraphQL vs. REST

In REST, requests are typically submitted via specially crafted URLs, with each request being sent to a different endpoint (e.g. /movie/2120, /director/5130).

GraphQL makes declarative requests for the data you are looking for using JSON-like queries, and all requests go to the same endpoint. The data you get back is determined by the schema used in the request. It is a standardized, self-describing way to request only the specific data you need. The query mechanism becomes much more flexible, using different schemas rather than different endpoint URL formats for different request types.

Many REST APIs also have a common specification Swaggerbut there is no rule that a REST API must be generated by Swagger. GraphQL basically provides a formal definition of an API. In this respect, GraphQL is similar to SQL. In a SQL-based data source, you connect to a common endpoint for all data requests, and the format of the request determines which records are returned. Also, although SQL has many implementations, the SQL query syntax is fairly consistent across these implementations.

GraphQL query

As mentioned earlier, GraphQL describes how the data to be retrieved is structured in queries and responses. Schema Or, let’s explain using data definitions. Anyone who has worked with an object-relational mapper (ORM) will feel familiar with GraphQL’s data schema definition. Let’s look at the following example.

type Movie {
id: ID
title: String
released: Date
director: Director
}

type Director {
id: ID
name: String
movies: (Movie)
}

Each element in the schema has a type definition. In GraphQL, Own type system for queriesThis system is used to validate the incoming schema and return data in a format that matches the definition.

Queries submitted to GraphQL are similarly defined by the schema.


type Query {
movie_title(title: String!): Movie
director(id: ID): Director
}

This query takes up to 2 parameters movie_title, directorReceive (received through title and ID respectively).

Next to the type !Indicates that the query is required, i.e., movies must be queried by title, and director is optional (used to narrow down the query).

The essential elements can also be used in the data schema. A query that retrieves movies by ID only is also possible, like this:

query GetMovieByID ($id: ID!) {
movie(id: $id) {
name
}
}

This query uses a separately defined variable ($id) to look up a movie by ID number and return its name. GraphQL queries can return individual fields as well as How to nest arrays of items within a fieldIt can also return related objects and their fields.

Variables for queries are passed in a separate section of the query using the following format:

{
“id”: 23
}

GraphQL Type

GraphQL’s query type system specifies many common scalar types, such as strings and integers. Most queries are structured around these types. However, the type system also includes several advanced types for more sophisticated queries, including:

  • interface Types can be used to create abstract types that have a predefined set of fields that can be implemented and reused in other types.
  • union Types allow one type of query to return different types of results across multiple types.
  • input Types can be used to pass entire objects of the same kind as above as parameters (provided that these objects are constructed from common scalar types that can be validated).

When dealing with interface or union objects Inline fragment and InstructionsYou must use it to return data based on conditions that the object type can specify.

Another type that can be returned from a query is optional. edges Returned in the field edge It is a type. At the edge nodes(data record), and an encoded string that provides contextual information about how to page forward and backward through that object. cursorsis included.

{
movie {
name
actors (first:5) {
edges {
cursor
node {
name
}
}
}
}
}

In this example movie The nodes return the names of the movies and actors. For each actor in the movie, you get a node containing the actor’s name, and a cursor that allows you to explore the actor’s “neighbors.”

Pagination using GraphQL

A common scenario when dealing with data sources is to request data page by page via a cursor. GraphQL Provides multiple pagination methodsdo.

When requesting records, you can specify not only the number of records to request and the starting offset, but also how to request consecutive pages. The example code in the above section is in parentheses. first:5 Returns only the first 5 actors associated with a particular movie, as specified in the parameters.

actors Behind first: You can add other keywords that describe how to retrieve the items following the clause. offset:can be used for simple offsets, but offsets may become obsolete when data is added or deleted.

For the most robust pagination, follow the instructions above. edge It is recommended to use a cursor that can be provided with the object currently being requested using a type. This will allow data to be inserted or deleted between pagination (e.g. Unique ID of the object Or you can create a non-breakable pagination mechanism by using a different unique property as the starting key index for another calculation.

Changing data using GraphQL mutations

In a REST API, you submit requests using POST, PATCH, and other HTTP verbs to change server-side data. In GraphQL, you use a specific query schema for changes, called a mutation query. This part is also SQL-based. UPDATE or DELETE It’s almost the same as using a query.

To change data, you submit GraphQL queries using a schema called a mutation schema.

mutation CreateMovie ($title: String!, $released: Date!) {
createMovie (title: $title, released: $released){
id
title
released
}
}

(submitted data)

{
“title”: “Seven Samurai”
“released”: “1950”
}

Any query, including mutation queries, can return data. Here createMovie The list of fields in the curly brackets following this request specifies what the server should return after the new record is created. Here id The values ​​of some fields are generated by the database, and the values ​​of other fields are submitted in a query.

Another thing to note is that the query and data types used to return data are by design different from those used to request data. Mutation queries need to validate the data they receive, so the types used for these queries are for this function. Similarly, the fields used in the returned query object are for display, not validation. The GraphQL object returned from the query may contain fields with circular references or other issues, which will make it unusable as query parameters.

Why GraphQL?

The primary reason to choose GraphQL over REST is the explicit, declarative nature of GraphQL queries. Having a formal definition of the query and the shape of the data it returns provides several other benefits, in addition to consistency across APIs and implementations.

API Evangelist Phil Sturgeonthis An article comparing GraphQL and RESTAs mentioned in , GraphQL’s field structure allows for more granular versioning of queries, since specific fields can be deprecated or brought back over time, unlike the way the entire API is versioned. You can still use a batch versioning approach in GraphQL, the key is that you don’t have to do it when you make changes.

Shaco Stubaillo, Engineering Manager at Apollo GraphQL, a developer of open source tools for GraphQL APIs, said: Another advantage of the GraphQL approachIt emphasizes self-documentation. “Every possible query, object, and field is provided with a name, description, and type information that can be queried from the server in a standard way,” says Stubail.

GraphQL’s self-documentation also provides a kind of introspective function: Use a query to return information about the query itselfIt can. So software using GraphQL queries can automatically infer fields without having to hardwire them to handle a specific set of fields.

It is not advisable to prefer GraphQL just because it is a newer technology and REST/Swagger is older. Author of The Design of Everyday API Arnaud Lore“GraphQL APIs, like REST APIs, should be built with a clear purpose and designed from an external perspective rather than an internal one,” he said.
editor@itworld.co.kr

Source: www.itworld.co.kr