INTRO:

Problem: Traditional RESTful web services are not so efficient in some use case:

  1. Sometimes we want to fetch part of an entity’s data. But web service only returns a complete set of data.
  2. Sometimes we want to fetch many related entities. But web service only accesses a single entity. So we have to make many round trips.
  3. If web service (endpoint, resources’ schema) changes, client code has to change as well.

And vice-versa, if the client requires a different set of data, we should change web service to support that, or at least to improve the outcome.

GraphQL solution:

  1. Allows clients to define the structure of the data required, and exactly the same structure of the data is returned from the server. Therefore it prevents the excessively large amounts of data from being returned.
  2. GraphQL is not dealing with dedicated resources. Instead, everything is regarded as a graph and connected.

You can combine different entities in one query and you are able to specify which attributes should be included in the response on every level.

  1. Single endpoint.

Client controls the query part – the query matches exactly the response. You do not need to read the documentation or run the request to know the response structure. Webservice and client can be developed parallel and independently at some extends.

About GraphQL: (more details)

  1. GraphQL is an open-source data query and manipulation language, and a runtime for fulfilling queries with existing data.
  2. Developed by Facebook.
  3. On 9th February 2018, the Schema Definition Language (SDL) was made part of the specification

DETAILS

1. Server

We need to install a GraphQL server to serve data “graphQL way”. It’s available for multiple languages, including Haskell, JavaScript, Python,[10] Ruby, Java, C#, Scala, Go, Elixir,[11] Erlang, PHP, R, and Clojure
  1. PHP: https://github.com/webonyx/graphql-php or https://github.com/leocavalcante/siler
  2. Nodejs: https://github.com/graphql/graphql-js/ or https://github.com/graphql/express-graphql (for working with express.js)
Schema:
  1. In order to describe the data that available to be queried, in the server above, we need to define our schema (types system).
  2. GraphQL has its own language to write Schemas: The Schema Definition Language (SDL). It’s language-agnostic, so you can use the same set of definition in GraphQL server written by PHP, Nodejs, Python…
  3. If you want to quickly build & test a schema with Nodejs, go to this in-browser GraphQL server playground
  4. Schema SDL example:
# hero is an object type
 type hero {
 ID: ID! # ! mean server will always return a non-null value for ID and name when fetching hero
 name: String! # ID and name are fields of scalar type
 appearsIn: [movie]! # these fields return a non-null list of movie objects
 }
 # movie is an object type
 type movie {
 ID: ID! # ID is a special scalar type
 name: String!
 character(OrderOfAppearance: Int): [hero] # id argument for nested fields
 }
 # one query object type is required for a schema, that describe what data can be fetched from client
 type queryRootType {
 # Get one hero item
 hero(id: ID!): hero # accept id argument
 # Get all hero items
 allHeros: [hero!]!
 #get movie
 movie(id: ID!): [movie]
 }
 # one mutation object type, optional for a schema, that describes what data can be sent from the client
 type mutationRootType {
 addHero(id: ID!, name: String!, appearsIn: movie): hero! # this's the required field
 removeHero(id: ID!): hero!
 }
 # only one schema definition for each schema
 schema {
 query: queryRootType
 mutation: mutationRootType
 }
In the server above, write “resolver” to map schema types to actually code that gets data.

Please see PHP tutorial here

Recommendation:
  1. GraphQL is typically served over HTTP via a single endpoint which expresses the full set of capabilities of the service
  2. Return JSON (with gzip)

2. Clients:

There are many clients writing in many languages.

Below is some examples using curl, in order to show the most basic form of GraphQL query:

  1. Search a single hero by id:
     curl <your-endpoint> -d '{"query": "query { hero(id: 1) }" }'
  2. Fetch all hero names:
     curl <your-endpoint> -d '{"query": "query { allHeros{name} }" }'
  3. There are special types “__schema” and “__type” that enable introspection of the schema:
     curl <your-endpoint> -d '{"query": "query { __schema{types{kind, name, possibleTypes{name}}}}" }'
    
     curl <your-endpoint> -d '{"query": "query { __type(name:\"hero\"){name, fields{name} } }" }
  4. Allows send variables in “variables” field of our payload:
     curl <your-endpoint> -d '{"query": "query($id:ID) { hero(id: $id) }", "variables": {"id":1} }'

Check out our demo here

Comment down below if you have any question or contact us via email for free consultation. Don’t forget to share & subscribe to our blog!

Chuong Nguyen           

References

https://medium.com/codingthesmartway-com-blog/rest-vs-graphql-418eac2e3083

https://en.wikipedia.org/wiki/GraphQL

https://graphql.org

https://blog.apollographql.com/three-ways-to-represent-your-graphql-schema-a41f4175100d

https://facebook.github.io/graphql/draft/

 

 

Share with us your business goals and product ideas, we will support you to develop, scale and succeed together.