Learn and understand GraphQL API architecture

2020年08月28日 710Browse 0Like 0Comments

The official definition of GraphQL: A query language for your API.

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

My underdtanding of GraphQL

The initial impression of GraphQL to me is that it is one type of SQL language for images, however, this is completely wrong after I read the docs, and I get a better understanding of it by doing some practice.

  • It's not used for picture/images queries, it is just a new open-source data query and manipulation language for APIs, originally developed by facebook. Most of developers know the popular REST API, and there are also other types of API specifications like JSONAPI, SOAP as well. GraphQL query language is used by clients to query data from a GraphQL API service.
  • It's a API query language, not a database query language like SQL. Thus, it doesn't mean that the client uses GraphQL to query data from a database, it queries data from the GraphQL service.
  • It's also a runtime, this means GraphQL can play a role as a server-side service layer for executing the client queries, by using a type system defined for the data. In fact, it isn't tied to any specific database or storage engine and is instead backed by the existing code and data at the backend. It works at the API layer which uses data from other sources(this can be multiple micro-services, other REST APIs or a database, etc.). To understand it by anology to REST here, we can consider it as a powerful form of single endpoint REST API service which wraps all the REST endpoints into one super endpoint. When fetching data from a backend database, the GraphQL service will use SQL to query the database as well. Similarly, as providing service for a query language, there are also concepts like schema and models used by GraphQL service. The following picture shows one form of GraphQL service is used.

  • What does Graph mean here? This reflects the data queried from a GraphQL API service is organized by graph relationship at backend, which is more visualized for the front-end developers to understand. With GraphQL, we model our business domain as a graph by defining a schema; within the schema, we define different types of nodes and how they connect/relate to one another.

Queries Usage Analogy to SQL

As they are both query languages, we can use GraphQL to query data from a GraphQL service(Objects in schema) by anology the jobs SQL does to query from a database(tables in schema), they both use fields/keys to select data, the difference is that: a GraphQL query is declarative, we just ask for and get what we need, while a SQL query is imperative, it may need more detailed and complex steps to get specific data especially for joint queries;

# select multiple fields from a table
SELECT id, name FROM hero;




#
# select fields on Objects
query{
  hero{
    id
    name
  }
}
# condition query
SELECT name FROM droid WHERE id = 1000;


#
query{
  droid(id: "1000") {
    name
  }
}
# joint query from multiple tables
# not fully equivalent to GraphQL

SELECT friend.name FROM friends
JOIN hero ON friend.id = hero.id


#
query{
  hero{
    name
    friends{
      name
    }
  }
}
# insert a row into table with return
INSERT INTO books(name, genre, authorID)
VALUES("Game of Thrones", "Magic, "5f4b2cf89859364c254b3ba5");
SELECT books.name, books.genre, authors.name
FROM books
JOIN authors
ON books.authorId = authors.id
WHERE authorId = "5f4b2cf89859364c254b3ba5";

#
mutation{
  AddBook(name:"Game of Thrones", genre: "Magic", authorId: "5f4b2cf89859364c254b3ba5")
  {
    name
    genre
     author{
       name
    }
  }
}

Comparision to REST

Main advantages compared to using REST API.

  • GraphQL lets developlers replace multiple REST requests with a single call to fetch the data user specifies; we only need one single endpoint;
  • It avoids data overfetching: what get exactly what we request, no redundant data. We know that when using the REST API, we usually only use part of the items in the returned data, many unused items are retuned from the response;
  • It brings more convinience and flexibility to separate front-end/back-end development job, as these two sides can work separately based on the pre-defined schema, it uses the introspecption system to provide schema definitioin information, and when the backend changes the API service, the front-end doesn't change code as much as when using REST, for example, the GraphQL way doesn't need to create new requests at least.
Item GraphQL REST
API Endpoints Single: resource data organized and fetched by types and fields, not by endpoints, access the full capabilities of data from a single endpoint, based on schema and models, more aggregated Multiple: resource data organized and differentiated by URLs(endpoints), resource oriented, more discrete
Type System Yes, strong typing, server-side validation supported No
Over Fetching No: Accurate.
Query, Mutate or Subscript from Selected fields of types
Yes
Request by URI(endpoint with parameters) and HTTP verbs: may result in overfetching data and multiple requests, data always need to be re-assembled by front-end developers
Multi Resources in single query Yes No: Need to send multiple requests
Request Behavior Less: Query, Mutation, Subscription More: GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS...
Cachable Yes No
Complexity Complex: we need to have a picture of the whole graph, data objects may have connections to others Simple: understand API by endpoint; data from different URIs is isolated
Abstraction Level
Thinking Pattern
Objects/Classes, more higher, closer to business logic level Function, more narrow, or single business feature view
Forward Compatibility Yes No

GraphQL Client Queries and GraphQL Server Service

GraphQL Query Language: to define queries at client-side

When we say GraphQL is a API query language, this is actually talking about when we use GraphQL queries at the client side to request data from a GraphQL API service. GraphQL query language is basically about selecting fields on objects from the Graph API service, it defines the rules how to construct a query. There are 3 types of queries clients can send: query(fetch data), mutation(change/update data), subscription(push data to clients from server).

GraphQL Schema Language: to define schema and types at server-side

While talking about the GraphQL service, this involes using its own Schema Definition Language(SDL), the GraphQL schema language to define a type system with schemas and queries resolvers to serve client queries and process data at the backend. Every GraphQL service uses this type language to describe the set of possible data clients can query, this allows us to talk about GraphQL schemas in a language-agnostic way.

  1. Three Built-in Request types
  • query: required. There should be 1 query in the schema at least.
  • mutation: on demand. Use the input parameters to update data. the parameters must defined as input, not type. return is needed after mutation
  • subscription: on demand.
  1. Other basic GraphQL types: Scalar Types, Enumeration Types, Lists and Non-Null, Interfaces, Union Types and Input Types

  2. User defined Object Types and Fields: These Object types are user-customised types at business logic level, their fields types are set from the basic GraphQL types, or other user-defined Object types.

  3. Resolvers: The resolve function serving for queries. The client queries will not succeed without the corresponding function. Each query(query/mutation) has its own resolve function. When the raw data is stored in a database, the resolve fuction will query data from it no matter using SQL directly or other database APIs.

Client and Server Libraries

As GraphQL is not a exclusive programming language, we can implement both sides in different programming languages. They are many client and server libraries implemented by different programming languages. We can find a list here. A popular fullstack JavaScript library is Apollo.

Popular Javascript Libraries are:

  • Fullstack solution: Apollo Client for different frameworks(React, Vue, Ember), Apollo Server
  • Client side: GraphQL.js, FetchQL.js
  • Server side: graphql + express-graphql: graphql lib is used to create GraphQL schemas; express-graphql is a GraphQL express Middleware, using schemas defined by graphql to create GraphQL service along with the express server, it provides a server-side-rendered GUI named GraphiQL for editing and testing GraphQL queries and mutations.

Reference

Sunflower

Stay hungry stay foolish

Comments