2. Agenda
● What is GraphQL
● GraphQL characteristics and syntax
● Advantages over REST
● GraphQL drawbacks
● GraphQL in Liveperson
● Demo
● Further reading
● Questions
3. Let’s start with an example
● Say you have an API for music albums and songs:
● And now you want to get all of an artist’s albums with their songs lists
Song:
{
“id” : 116
“artist”: “David Bowie”,
“name”: “Time”,
“album” : “Aladdin Sane”,
“duration”: “5:15”,
“trackNumber”: 6,
...
}
Album:
{
“id” : 321
“artist”: “David Bowie”,
“name”: “Aladdin Sane”,
“releaseYear”: 1973,
“songIDs”: [111,112,113,114,....],
...
}
4. Example continued
GET /artist/1
GET /album/321
GET /song/111
GET /song/112
…
…
GET /song/120
GET /album/322
GET /song/211
GET /song/212
…
…
GET /song/220
...
Requires many requests
Each request returns much more data than you
need
● Other option - ad-hoc API for album with
songs
○ But adding API per need might end up
with way too many APIs
○ And you’d still get more data than you
need
5. REST Limitations
● resource-centric: many endpoints
● The endpoints are often organized the way they’re stored in DB,
not the way they’re retrieved by clients
● large (and fixed) responses
● Getting a complete response requires multiple requests
● We would like to get on a single request
● ALL the data that we need, from several resources
● ONLY the data that we need - no large responses with redundant
fields
6. What is GraphQL
● A data query language
● Completely agnostic to the underlying storage or
programming language
● Invented and used by Facebook since 2012
● Open sourced on 2015
● Re-defines the client-server relations
● Moving the power to the client
● He decides what to fetch, not the server
8. What is GraphQL
Client request
album (artist: “David Bowie”
name: “Heroes”) {
releaseYear
songs {
trackNumber
name
duration
}
}
Query name
arguments
Selection set
to return
Schema
schema {
query: {
album(artist: String!
name: String!):Album
}
Album: {
id: ID
name: String
releaseYear: Integer
artist: String
songs: [Song]
}
Song: {
id: ID
name: String
duration: String
trackNumber: Integer
}
}
Response
{
"album": {
"releaseYear": 1977,
"songs": [
{
"trackNumber": 1,
"Name": "beauty and the beast",
"Duration": "3:32"
},
{
"trackNumber": 2,
"Name": "Joe the Lion",
"Duration": "3:05"
},
…
]
}
}
9. GraphQL Characteristics
● GraphQL describes what data to fetch rather than actual queries to a
database.
● A GraphQL server interprets these calls and then queries the storage
layer, using the schema and resolvers.
● Entirely agnostic to the storage layer, can be also used as a proxy
forward API calls.
● Contains introspection features to expose the server’s schema and
objects.
10. Resolvers
● The schema contains the objects the server returns.
● Each object can consist of scalar fields (int, string etc.) or other
objects.
● Each object in the schema should be provided with a resolver.
● The resolver is a piece of code that does the actual work - fetches
the results from the storage layer.
● GraphQL server will take care of combining the objects and returning
only the selection set fields.
11. Resolvers
● When running the query, album resolver will fetch the album
according to the provided artist and name
● Albums in DB contain song Ids - the song resolver will fetch the
songs according to the Ids
● GraphQL server will then combine the results and return only the
requested fields
● There are several solutions for batching and caching to make the
fetching more efficient
Schema
schema {
query: {
album(artist: String!
name: String!):Album
}
Album: {
id: ID
name: String
releaseYear: Integer
artist: String
songs: [Song]
}
Song: {
id: ID
name: String
duration: String
trackNumber: Integer
}
}
Songs Storage
Song:
{
“id” : 116
“artist”: “David Bowie”,
“name”: “Time”,
“album” : “Aladdin Sane”,
“duration”: “5:15”,
“trackNumber”: 6,
...
}
Albums Storage
Album:
{
“id” : 321
“artist”: “David Bowie”,
“name”: “Aladdin Sane”,
“releaseYear”: 1973,
“songIDs”: [111,112,113,114,....],
...
}
12. GraphQL Basic Syntax
● Two types of Operations
○ Query: read only fetch
○ Mutation: write and fetch
● Can contain arguments
● Selection Sets: a subset of the fields on an object.
○ Can be objects as well
○ Defines the returned object’s structure
{
getAlbum(artist: 123) {
name
releaseYear
songs {
name
duration
}
}
}
13. Mutations
● Mutations are yet another kind of queries
● By convention, we use query for read only operations, and mutation for
persist operations (create/update/delete/patch)
● Mutation also has a returned value, just like query
14. API Versioning in GraphQL
● When the client can’t control the returned data, any change can be a
breaking one
● Any change that is considered as a breaking one, requires a new API
version
● In contrast, GraphQL only returns the data that's explicitly requested
● New capabilities can be added via new new fields
○ Which will not be consumpt by the client until explicitly requested
● The common practice is to avoid changing existing fields, and serving a
versionless API.
● There’s a deprecation mechanism to handle obsolete fields
15. So Why choose GraphQL over REST?
● Single endpoint - easier to scale
● Tailored responses - client gets only what he wants
● Fewer round trips - can return several related resources together
● Backwards compatibility - the client decides the response structure,
knows exactly what to expect
● Introspective - GraphQL has a native and highly extensible schema
and type system
16. GraphQL drawbacks
● Coupling between entities is inherent - The schema needs to know all
types
● Still relatively new
● No clear best-practices/standards
● Frameworks and resources are less mature than REST or other
industry standards
17. GraphQL in Liveperson
● Audit Trail API is built using GraphQL
● We evaluate the option to build Account Config 2.0 using GraphQL
based APIs
19. Advanced Syntax - Fragments
● Fragments are aliases for a bundle of fields.
● Fields in fragments are added at the same level of invocation as
adjacent fields.
● Syntax- prefixed with ...
Query
{
album(id: 1) {
name
...customFields
}
}
fragment customFields on Album {
releaseYear
songs {
name
duration
}
}
Response
{
"album": {
"name": “heroes”,
"releaseYear": 1977,
"songs": [
{
"Name": "beauty and the beast",
"Duration": "3:32"
},
{
"Name": "Joe the Lion",
"Duration": "3:05"
},
…
]
}
}
20. Advanced Syntax - Directives
● Directives alter execution behavior and can be used to conditionally
include (@include) or exclude (@skip) fields.
Request
query getSong(fullDetails: Boolean id: Int) {
name
... @include(if: $fullDetails) {
duration
album
}
}
}
// response when $fullDetails resolves to false
{
"getSong": {
"name": "Time"
}
}
// response when $fullDetails resolves to true
{
"getSong": {
"name": "Time",
"album": "Aladdin Sane",
“duration”: “5:15”
}
}
21. Further reading
● https://github.com/chentsulin/awesome-graphql - github repo with
many links to tutorials, libraries in various languages, blogs, videos and
more
● http://graphql.org/learn
● https://www.graphqlhub.com - playground on various public GraphQL
API. good place to learn the syntax