{ REST }
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.
Describe data requirements
Define API capabilities
Render UI
Data Provisioning
WHY?
Already got
{ REST API }
[Reference: REST 2.0 Is Here and Its Name Is GraphQL]
[Reference: REST 2.0 Is Here and Its Name Is GraphQL]
[Reference: The GraphQL stack: How everything fits together]
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
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 |
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
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
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
{ REST }
200x
SOAP
201x
REST
2017
REST + SOAP
2018
REST
+ GraphQL
for UI
201x
REST
+
GraphQL
for all Client
All Clients
REST + SOAP
SOAP
Server
REST
Phase #1 - Current API Model
API Clients
REST + GraphQL
GraphQL
Server
Phase #2 - Initial Adoption Variant 1
REST vNextGen
Common Business Logic
Web App
Clients
API Clients
REST + GraphQL
GraphQL
Server
REST vNextGen
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
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
GraphQL
REST
Common Business Logic
Web App
Clients
API Clients
REST + GraphQL
GraphQL
Server
REST vNextGen
Web App Clients
Phase #3 - DSaaS Variant 1
µ-service B
+ µ-services
ALB
µ-service A
API Clients
REST + GraphQL
GraphQL
Server
REST
Web App Clients
Phase #3 - DSaaS Variant 2
µ-service B
+ µ-services
ALB
µ-service A
Common Business Logic
[Source: Apollo Stack]
Happy Customer + Happy Dev
[Ref:How to GraphQL]
[Reference: GraphQL vs. REST]
Display the list of posts belong to its owner, with it comments and...
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
[Reference: Why GraphQL is the future]
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