Add GraphQL to Existing REST API Architecture

Kevin C Chen @ Squad UI

{ REST }
  • What's GraphQL and WHY?
  • Example
  • Challenges GraphQL would address
  • Ways to integrate
  • Q&A

What we will cover...

POLLS

Source: http://i.huffpost.com/gen/1311474/images/o-SCHOOLS-facebook.jpg

It 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.

You're already using it

(Facebook has billions daily active users)

GraphQL
A query language for APIs

GraphQL is designed and used at Facebook to request and deliver data to mobile and web apps since 2012.

Client   +   Server

Describe data requirements

Define API capabilities

Render UI

Data Provisioning

WHY?

Already got

{ REST API }

GraphQL makes everyone's life better

  • Client-side developer friendly with declarative data fetching. GraphQL gives clients the power to ask for what they need and get exactly that.

    ==> Address UI requirement with better efficiency
     
  • GraphQL enables the server-side developer to focus on describing the data that is available rather than customizing and optimizing specific endpoints.

    ==> Coherent API design with fewer API changes

Separation of Concerns

drift

applications

occurrences

details

computers

/software-inventory/drift/...

???

Endpoint entry

Group By X

Detail data associated with Y

List Y of Group X

occurrences

details

/​applications

/computers

/{sha256}/occurrences

/{hostID}/occurrences

UI driven REST API design

URL Method Operation
/software-inventory/drift/​applications POST List drift group by file hash
/software-inventory/drift/computers POST List drift group by computer
/software-inventory/drift/applications/{sha256}/occurrences POST Gets a list of the drift instances of the given hash
/software-inventory/drift/computers/{hostID}/occurrences POST Gets a list of the drift instances of the given computer
/software-inventory/drift/applications/{sha256}/details POST Gets details about a given drift occurrence

Customized REST API

Thinking in Graphs

Drift

Applications

Details

Computer

Policy A

Computer

Applications

Drift

Details

Base Policy

Computer

Applications

Drift

Details

Policy B

Computer

Applications

Drift

Details

query FirstFiveDriftDetailOfComputer{
  Computer(id:"15"){
    hostname
    policy {
      name
    }
    applications {
      name
      drifts(first:5, path: "/tmp") {
        sha256
        timestamp
        filename
      }
    }     
  }
}

Client issues request declaring data requirements

{
  "data": {
    "Computer": {
      "hostname": "MyServerX",
      "policy": {
        "name": "Server Policy"
      },
      "applications": [
        { "name": "Server Utility" },
        { "drifts": [
          {
            "sha256": "c6e5ec6ffa3d5a2dd7679306a8eac04fef2b7b9cDC743B4FBE2FD4446C7B62DBC9",
            "timestamp": 1512346092,
            "filename": "StrangeJava.jar"
          },
          {
            "sha256": "5F753829F6E736C06CCB1F4C443F5A01FC9C27DC743B4FBE2FD4446C7B62DBC9",
            "timestamp": 1512505883,
            "filename": "badScript.sh"
          }
        ]
       }       
     ]
    }
  }
}

Server issues response matching structure of declared data requirements

Query

mutation CreateAuditEvent($evt: Event!){
  createAuditEvent(event: $evt) {
    time
    severity
    description
  }
}

Client issues request declaring data requirements

{
  "data": {
    "createAuditEvent": {
      "time": 1512940114,
      "severity": "high",
      "description": "This is an event"
    }
  }
}

Server issues response matching structure of declared data requirements

{
  "evt": {
    "time": 1512940114,
    "severity": "high",
    "description": "This is an event"
  }
}

Variables

Mutation

Simplified REST API

URL Method Operation
/software-change POST Create a new drift
/software-change GET Get a list of all drift
/software-change/15 GET Fetch details on drift with ID 15
/software-change/15 PUT Update details on drift with ID 15
/software-change/15 DELETE Delete drift with ID 15

Decoupled from UI requirements

{ REST }

Versioning remains difficult

Evolve your API without versions

Everything is typed and everything you want to expose is part of a schema

Doesn't know what data the clients actually needs?

Lacks machine-readable metadata with out-of-date documentation

Documentation is a first-class citizen

Hampers productivity & product iterations with adjustments needed on both frontend & backend

Allow for rapid product iterations with both frontend and backend

Developer Experience

vs.

Return fixed data structure defined by Server resource

Return data structure in the form requested by Client

Thinking in Graph, human readable query

Challenging URL design with heavily nested relationship

Many HTTP requests with many endpoints 

1 HTTP requests with 1 endpoint

Vulnerable to Over- and Underfetching data

No more Over- and Underfetching

Technology Differences

{ REST }

vs.

GraphQL Integration

Incremental Adoption Phases

200x

SOAP

201x

REST

2017

REST + SOAP

2018

REST
+ GraphQL
for UI

201x

REST
+
GraphQL

for all Client

First questions people ask

  • As an API developer, is it helping me to reduce the amount of the work for porting the existing REST API?
     
  • Can I use this without rewriting my existing stuff?
     
  • Where do I start?

All Clients

REST + SOAP

SOAP

Server

REST

Phase #1 - Current API Model

  • All Client types access server resources via either REST API endpoint or SOAP API

API Clients

REST + GraphQL

GraphQL

Server

Phase #2 - Initial Adoption Variant 1

  • GraphQL Server is part of DSM responding to Client's queries
     
  • New Web App Clients (React SPA) make query via GraphQL
     
  • Non-UI related REST API can be decoupled from UI logic and UI requirement changes
     
  • Deprecate SOAP API

REST vNextGen

Common Business Logic

Web App
Clients

API Clients

REST + GraphQL

GraphQL

Server

REST vNextGen

  • Have an independent GraphQL Server (e.g. node.js) that could access and wrap the exist REST API and responding to Client's queries
     
  • Start with Web App client-side needs, fill in API bit by bit
     
  • New Web App Clients (React SPA) make query via GraphQL

Phase #2 - Initial Adoption Variant 2

Web App
Clients

API Clients

REST + GraphQL

Server

Automation Test Clients

Phase #3 - GraphQL as alternative API Variant 1

  • More Client type support
     

  • Consider making GraphQL API publicly available as an alternative to REST API
     

  • REST API phase out gradually if GraphQL becomes the mainstream API
     
  • Iterate and validate with customer with additional integration option that provides better dev experience

GraphQL

REST

Common Business Logic

Web App
Clients

API Clients

REST + GraphQL

Server

Automation Test Clients

Phase #3 - GraphQL as alternative API Variant 2

  • GraphQL is added in an non-disruptive way, the coverage continue to grow
     

  • Continue to support & expand REST API
     

  • New REST endpoints are backed by GraphQL
     

  • Iterate and validate with customer with additional integration option that provides better dev experience

GraphQL

REST

Common Business Logic

Web App
Clients

API Clients

REST + GraphQL

GraphQL

Server

REST vNextGen

Web App Clients

  • An non-intrusive addition into DSaaS by routing Web App Client traffic through GraphQL
     
  • Independent GraphQL Server  could scale up and down when necessary
     
  • GraphQL Server as an gateway for other data sources or µ-services
     
  • GraphQL can also facilitate communication & integration between µ-services

Phase #3 - DSaaS Variant 1

µ-service B

+ µ-services

ALB

µ-service A

API Clients

REST + GraphQL

GraphQL

Server

REST

Web App Clients

  • GraphQL Server is part of DSM and service the Web App Client requests routed by load balancer
     
  • Could consider making GraphQL endpoint availble to non-Web App Clients
  • Web App Client make query via GraphQL

Phase #3 - DSaaS Variant 2

µ-service B

+ µ-services

ALB

µ-service A

Common Business Logic

Apollo Stack

  • Apollo Client to bind data to your UI, for React, JavaScript, and native platforms
     
  • Apollo GraphQL Servers connects to one or more REST APIs, microservices, or databases
     
  • Community-focused built by the community, for the community

[Source: Apollo Stack]

GraphQL is here to help

  • As an API developer, is it helping me to reduce the amount of the work for porting the existing REST API?
    Ans: Yes. GraphQL will help take care of UI dependent APIs

     
  • Can I use this without rewriting my existing stuff?
    Ans: Yes. Existing REST APIs will continue to work with GraphQL

     
  • Where do I start?
    Ans: POC, tutorials, Apollo Stack

When a technology solves real problems...

industry will embrace it

Open Questions

  • Integration model and trade-offs?
     
  • Performance implications?
     
  • Improved documentation workflow?
     
  • Adoption roadmap: from now, towards the future?
     
  • How do we plan to sustainably grow and support the API stack into the future?
  • With GraphQL
     
    • Allows for rapid iterations on the frontend without any extra work on the server
       
    • Confidently support shipped clients as a system evolves
       
    • Incremental adoption is feasible with many options 

Key Takeaways

(REST API + GraphQL) + React =

Happy Customer + Happy Dev

References

Questions

?

Appendicies

What else does GraphQL provides?

  • Insightful Analytics on the Backend - DSaaS
  • Authentication
  • Validation
  • Rate limit - security
     
  • Subscriptions - real-time push-style updates - limited with Java
  • Filtering
  • Pagination

[Reference: GraphQL vs. REST]

Blog Example

  • Our blog has multiple posts
  • Each post has an owner
  • Each post may have multiple comments.
  • Each post may have multiple subscribers

Display the list of posts belong to its owner, with it comments and...

Business Requirement for Client / UI / Tool

URL Method Operation
/user/20/posts POST Create a post associated with User 20
/user/20/posts GET Fetch all posts created by User 20
/user/20/posts/15 GET Fetch post 15 created by User 20
​/user/20/posts/16 PUT Update post 16 created by User 20
​/user/20/posts/10 DELETE Delete post 10 created by User 20

User

Posts

Comments

Subscribers

Posts

Comments

Subscribers

/user/20

/user/20/posts

???

User

Posts

Comments

Subscribers

/user/20

/user/20/posts

???

# API Calls Comment
1 /user/20/posts
/posts/1/comments
/posts/1/subscribers
/posts/2/comments
/posts/2/subscribers
​would end up with tons of rountrip HTTP requests to get these data
2 ​/user/20/posts
​/user/20/posts/comments
​/user/20/posts/subscribers
very particular & customized, need to put together a query for these customized endpoints
3 ​/user/20/posts_with_comments
​/user/20/posts_with_subscribers
tightly coupled with very particular feature in our frontend, breaking RESTFUL conventions.
{
  User(id:"abc"){
    name
    posts {
      title
      comments {
        content
        timestamp
      }
      subscribers {
        name
      }
    }     
    followers(last:3){
      name
    }
  }
}

Client issues request declaring data requirements

{
  "data": {
    "User": {
      "name": "Mary",
      "posts": [
        { "title": "Learn GraphQL today" },
        { "comments": [
          {
            "content": "This is a very good blog post",
            "timestamp": 1512346092
          }
        ]
       },
       { "subscribers": [
          { "name": "John" },
          { "name": "Tom" }
        ]
       }
     ],
     "followers": [
        { "name": "John" },
        { "name": "Alice" },
        { "name": "Sarah" }
      ]
    }
  }
}

Server issues response matching structure of declared data requirements

[Source: Based on Learn GraphQL by KADIRA]

REST

SQL

S3

Web App

Mobile

Resolvers

Connectors

  •  A GraphQL query returns exactly what a client asks for and no more
     

  • Confidently support shipped clients as a system evolves
     

  • Strong typed query allowing the server to make guarantees about the response
     

  • No more time spent trying to figure out an API

Key Advantages

Tackling Real Problems

  • Want to decouple frontends and backends to speed up development
     
  • REST API has gotten so complicated that it's a significant drag on product development.
     
  • Moving to a microservices architecture
     
  • Have a mobile client and care about latency and bandwidth
     
  • Have more than one client (e.g. web + iOS/Android)

Solving REST API Challenges

  • Require multiple round trips between the client and server to render single views
     

  • Data Over-fetching - as the requirements change, payload grows monotonically, but old clients also receive this additional data
     

  • Versioning of API introduce complexity of the server with code duplication, spaghetti code and is hard to maintain 

Success!

"Overall we've been really pleased working with GraphQL. It was great to quickly integrate GraphQL with other services that allowed us to rapidly iterate on customer features, rather than non-user facing infrastructure. Head over to fabric.io to see it in action!"  

--- By Sam Neubardt, Software Engineer @ Fabric Blog June 7, 2016

Made with Slides.com