Date post: | 05-Apr-2017 |
Category: |
Software |
Upload: | liveperson |
View: | 118 times |
Download: | 0 times |
GraphQL Intro
Nir Levy, Jan 17
Agenda
●What is GraphQL●GraphQL characteristics and syntax●Advantages over REST●GraphQL drawbacks●GraphQL in Liveperson●Demo●Further reading●Questions
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,....], ...}
Example continuedGET /artist/1 GET /album/321 GET /song/111GET /song/112……GET /song/120GET /album/322 GET /song/211GET /song/212……GET /song/220...
Requires many requestsEach 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
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
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
Who uses GraphQL
What is GraphQL
Client request
album (artist: “David Bowie” name: “Heroes”) { releaseYear songs { trackNumber name duration }}
Query name
arguments
Selection set to return
Schemaschema { 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" }, …
] }}
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.
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.
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,....], ...}
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 } }}
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
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
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
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
GraphQL in Liveperson
●Audit Trail API is built using GraphQL
●We evaluate the option to build Account Config 2.0 using GraphQL based APIs
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" }, … ] }}
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” }}
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
Questions
Thank You