graphql in an age of rest
TRANSCRIPT
GraphQL in an Age of RESTYos Riady yos.io
goo.gl/prnEnz
A step-by-step walkthrough of building a GraphQL server
Drawbacks to building Web APIs with REST
Background REST GraphQL Code Next Steps
An overview of GraphQL, with examples
Further learning, future improvements, and conclusion
The current state of Web APIs
A step-by-step walkthrough of building a GraphQL server
Drawbacks to building Web APIs with REST
Background REST GraphQL Code Next Steps
An overview of GraphQL, with examples
Further learning, future improvements, and conclusion
The current state of Web APIs
Introduction to REST
Separate your API to logical resources. Map actions to HTTP methods and URIs.
● GET /posts - Retrieves a list of posts
● GET /posts/12 - Retrieves a specific post
● POST /posts - Creates a new post
● PUT /posts/12 - Updates post #12
● PATCH /posts/12 - Partially updates post #12
● DELETE /posts/12 - Deletes post #12
A HackerNews-like Data Model
author_idpost_idbody
Comment
author_idtitleurlpublished_atvotes
Post
namejoined_at
UserPOST /postsGET /posts/1PUT /posts/1DELETE /posts/1GET /posts/1/authorGET /posts/1/comments
POST /usersGET /users/1PUT /users/1DELETE /users/1GET /users/1/postsGET /users/1/comments
POST /commentsGET /comments/1PUT /comments/1DELETE /comments/1
Retrieve a list of posts
GET /posts
{ “posts”: [{ “id”: 1 “author_id”: 101, “title”: “GraphQL in an Age of REST”, “body”: “lorem ipsum”, “votes”: 342, “published_at”: “2016-10-11T16:53:28+00:00” }, ... ]}
Retrieve a list of posts
GET /posts
GET /users/101
{ “user”: { “id”: 101 “name”: “yosriady”, “joined_at”: “2015-10-11T16:53:28+00:00” }}
There are many cases where an API consumer needs to load data related to the resource being requested.
GET /posts/1?embed=author.name
{ “post”: { “id”: 1
... “author”: { “name”: “yosriady” } }}
Solution: Autoload related resources
Another Problem: Over-fetching of data
APIs often return a huge JSON object with many fields, even when we only use a handful.
Solution: Clients should be able to specify the fields they only need.
GET /posts/1?fields=title,link,published_at
Problem: Custom Endpoints
/posts_with_everything_i_need
/posts_with_everything_i_need_with_author_v2
/posts_with_everything_for_samsung_smart_tv
/tightly_coupled_endpoint_for_a_specific_client
Whoa! We end up with a lot of endpoints.
Problem: How will users learn our API?
● Users○ API consumers○ Developers from other teams○ New hires
● Documentation must cover:○ What resources does the API manage?○ What actions can I perform?○ Endpoint parameters
■ Required■ Optional ■ Attribute Types
● API Specification languages○ OpenAPI (fka Swagger)○ API Blueprint○ JSON Schema
● Third-party services● Benefits
○ Auto-generated documentation○ Auto-generated Server stubs○ Auto-generated Client code
Solution: API Specifications
Summary: Drawbacks of REST
APIs need to be documented well enough for consumers to be able to discover and learn it on their own.
Documentation
/tightly_coupled_endpoint_for_a_specific_client
REST APIs are rigid. Over-fetching. Custom endpoints lead to bloat.
Custom endpoints
GET /posts/1
GET /comments/1001
GET /comments/1002
Getting the data you need can require multiple REST calls away.
Multiple round trips
A step-by-step walkthrough of building a GraphQL server
Drawbacks to building Web APIs with REST
Background REST GraphQL Code Next Steps
An overview of GraphQL, with examples
Further learning, future improvements, and conclusion
The current state of Web APIs
Introduction to GraphQL
● A declarative (1) query language, (2) type system, and (3) runtime for client applications to fetch and mutate data.
● Devised to solve some of the problems with REST○ Originally used by the Facebook Product team
● Data store independent● Language and platform independent
Queries have the same shape as its result
Here is a (1) GraphQL Query and its response:
{
post(id: 1) {
title
url
author {
name
}
}
}
{
"post": {
"title": "GraphQL in an Age of REST",
"url”: “http://yos.io”,
“author”: {
“name”: “yosriady”
}
}
}
Power to the client instead of the server
The client specifies what data it needs, and the server does only what is necessary to return that data.
goo.gl/nV3WJE goo.gl/nV3WJE
Schema Language
type Post { title: String! author: User! comments:[Comment]!}
type Query { post(id: Int): Post posts: Post}
Types
● Scalar types○ Boolean○ Int○ Float○ String○ Custom types i.e. Date
● Enums● Lists● Interfaces● Unions
Summary: Benefits of GraphQL
API playgroundClient-side validationSelf-documenting
Introspective
Adapts to different requirements for different clients
Client-specified
Query from multiple data sources in a single network request.
Single round trip
A step-by-step walkthrough of building a GraphQL server
Drawbacks to building Web APIs with REST
Background REST GraphQL Code Next Steps
An overview of GraphQL, with examples
Further learning, future improvements, and conclusion
The current state of Web APIs
Preamble
A GraphQL service is created by providing (a) the schema and (b) resolver functions.
● We’ll use○ Node.js + Express○ express-graphql
Preamble
● Bindings are available for all major languages○ Javascript○ Ruby○ PHP○ Python○ Java○ C/C++○ Go
○ Scala○ .NET○ Elixir○ Haskell○ SQL○ Lua○ Elm○ Clojure
A GraphQL Schema Definition
const User = new GraphQLObjectType({ name: 'User', fields: () => ({ id: { type: GraphQLInt }, name: { type: GraphQLString } })});
Creates links between data sources and GraphQL fields
posts(id){ return request(`https://api.blog.io/posts/${id}`);}
posts(id){ return sql.raw('SELECT * FROM posts WHERE id = %s',id);}
posts(id){ return DB.Posts.getById(id);}
GraphQL Resolvers
A step-by-step walkthrough of building a GraphQL server
Drawbacks to building Web APIs with REST
Background REST GraphQL Code Next Steps
An overview of GraphQL, with examples
Further learning, future improvements, and conclusion
The current state of Web APIs
● Give GraphQL a try, especially if ○ Your product is an API○ You have many clients with flexible requirements
● Features not covered in this talk○ Aliases,○ Fragments,○ Variables,○ Directives, etc.
● Best practices still emerging
In Closing
meetup.com/API-Craft-Singapore
Appendix 0: Differences from REST
● A single endpoint `/graphql`● Only HTTP verbs GET and POST are used
○ GET for queries○ POST for mutations
● Support for other transport layers○ MQTT for IOT domains
Appendix 1: Versioning
“We encourage GraphQL endpoints to take an add-only approach to schema evolution over time instead of changing existing fields.”
GraphQL takes a strong opinion on avoiding versioning by providing the tools for the continuous evolution of a GraphQL schema.