REST

Why need to choose GraphQL over REST/OData in a Web API Application development

Posted on Updated on

Problem

  • Need to have single HTTP endpoint for managing CRUD operation and performing custom actions.
  • Need to have meta data about available services and its data contracts.
  • Need to fetch linked resources(domain objects) of application in single call, helps to avoid multiple custom endpoints and round trips.
  • Need to have backward compatibility for services and its data contracts.
  • Need to have custom query capability with filtering, sorting, pagination and selection set for targeted domain objects.
  • Need to go away from a SOAP web services.

Solution

One of the solution to resolve above problems is GraphQL specification which open sourced by Facebook. GraphQL is an application layer query language which helps the client application to fetch or mutate(update/delete/insert) the application domain objects. As a web api application need to support Command Query Responsibility Segregation for many reasons.

To understand the GraphQL in simple words, Let us compare a RDBMS terminology with GraphQL,

  • RDBMS gives single endpoint for a database server, GraphQL also advocate the single endpoint irrespective of underlying transport protocol like HTTP, UDP, FTP etc…
  • RDBMS has schema which contains tables and store procedures. Same way GraphQL also defines schema, instead of tables it proposes Type System which helps to define data contract etc..
  • Like Store procedure it has queries and based on what type of operation it perform on server, their are two types one which is used to read or fetch the data known as “query” and other which is used to update or change the data known as “mutation”.
  • Like SQL is query language for RDBMS, GraphQL has Graph query language which is like JSON without value.
  • RDBMS is having normalized data model with relationships using foreign keys, here we need to define product data model in graph manner irrespective of how we store it.

To know more about GraphQL please go through its specification.

The implementation architecture overview of GraphQL in an application is as shown below:

  • GraphQL server endpoint which is a simple HTTP endpoint which accepts HTTP Post request with GraphQL message as a payload.
  • It resolves the query depends on its type (either mutation or query) and produce the response in JSON format using underlying infrastructure of Business Logic and Data Access Layer.
  • Any type of a client application can communicate with GraphQL server endpoint over HTTP.
  • GraphQL also publishes its meta data through introspection queries.
  • GraphiQL is Html5 and Javascript based IDE which helps to fetch and explore meta data about services.
  • It is also used as test harness, for generating and evaluating GraphQL queries and mutation.

Why GraphQL over OData and REST

Choose the GraphQL over OData and REST, because of following reasons:

  • Need to support the linked resource, To give an example , let say In university we have a students which belongs to department, We need to get student details along with department details, To achieve same thing need to make multiple calls to server if we are using OData or REST.
  • Another case like a client application wants to get student’s course details, to fulfill this demand, need to define custom REST or OData endpoint, GraphQL avoids the need of such custom endpoint, as we define a product data model as a graph, so that get the data as link exist between the nodes of graph.
  • To support the backward compatibility of services and data contract, Using OData or REST need to maintain URL or DataContract versing also need to do message routing in some cases. But using GraphQL we don’t need to do it. As client knows what data it is consuming using GraphQL request and from single GraphQL endpoint.
  • OData apply convention for data fetching as compare to REST, same thing is done in GraphQL using Type System, Arguments and Selection Sets.
  • In OData meta data is published in EDM format and REST is struggling to define the meta data standard as WADL or Swagger and many more. Here GraphQL is published meta data in defined format through introspection api and also provided document explorer for it.
  • WS-Trust, WS-Federation and WS-Security is already addressed by OAuth 2.0 and Open Id Connect 1.0 for API so one can use it for GraphQL as well.

Samples GraphQL queries and mutations(commands)

1. Sample request to get student by id from a graphql endpoint as shown below:

Request:

    POST http://your-grapghql-hosting/api/graphql? HTTP/1.1     
    {
        "query": "query($id: Long!){
                student(id: $id) 
                {
                  status
                  gender 
                  name 
                  { 
                    title      
                    firstName      
                    lastName    
                  }  
                }
         }",
        "variables": "{\"id\":1}"
    }

Response:

    HTTP/1.1 200 OK

    {
      "data": {
        "student": {
          "status": "Active",
          "gender": "Mail",
          "name": {
            "title": null,
            "firstName": "Vinayak",
            "lastName": "Bhadage"
          }
        }
      }
    }

2. Get student details along with department as linked resource

Reuqest

    POST http://your-grapghql-hosting/api/graphql? HTTP/1.1     
    {
        "query":"query($id: Long!){
                studentWithDepartment: student(id: $id) 
                {
                      status
                      gender 
                      name 
                      { 
                        title      
                        firstName      
                        lastName    
                      }  

                      department {
                              name
                              id
                        }
                      }
                }",
        "variables":"{\"id\":1}"
     }

Response

HTTP/1.1 200 OK 
{
  "data": {
    "studentWithDepartment": {
      "status": "Active",
      "gender": "Mail",
      "name": {
        "title": null,
        "firstName": "Vinayak",
        "lastName": "Bhadage"
      },
      "department": {
        "name": "Computer Engineering",
        "id": 1
      }
    }
  }
}

3. Create studnet using mutation(command) GraphQL Queries

Reuqest

POST http://your-grapghql-hosting/api/graphql? HTTP/1.1 
{
    "query":"mutation newStudent($input:StudentInput!){
          createStudent(studentInput:$input)  {   
              id    
              gender    
              status    
              profileImage    
              department{      
                  id      
                  name    
            } 
          }
      }",
      "variables":"{\"input\": {status:\"Active\", gender:\"Male\",departmentId:1,profileImage:\"hello\"}}"
 }

Response

HTTP/1.1 200 OK 
{
  "data": {
    "createStudnet": {
      "id": 15557393526030336,
      "gender": "Male",
      "status": "Active",
      "profileImage": "hello",
      "organization": {
        "id": 1,
        "name": "Root"
      }
    }
  }
}

Conclusion

GraphQL helps to keep Web API application more robust, extensible, updo the date documentation of services and backword compatible without breaking Web API consumers.

References:

  1. graphql-a-data-query-language
  2. graphql-dotnet
  3. graphiql IDE and Documentation
  4. graphql specification