Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to GraphQL

Introduction to GraphQL

My OpenFest presentation about GraphQL.

(Video: https://www.youtube.com/watch?v=-dAI5tSSPGA)

Radoslav Stankov

October 08, 2015
Tweet

More Decks by Radoslav Stankov

Other Decks in Programming

Transcript

  1. GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post

    headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter_id: 1 }
  2. GET /api/users/1 { id: 1, name: 'User Name', handle: 'user_name',

    avatar_url: 'assets.producthunt.com/uuid' }
  3. GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post

    headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter: { id: 1, name: 'User Name', handle: 'user_name', avatar_url: 'assets.producthunt.com/uuid' } }
  4. GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post

    headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter: { id: 1, name: 'User Name', handle: 'user_name', avatar_url: 'assets.producthunt.com/uuid' }, makers: [{ id: 2, name: 'Second User', handle: 'second_user', avatar_url: 'assets.producthunt.com/uuid' }] }
  5. GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post

    headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter: { id: 1, name: 'User Name', handle: 'user_name', avatar_url: 'assets.producthunt.com/uuid' }, makers: [{ id: 2, name: 'Second User', handle: 'second_user', avatar_url: 'assets.producthunt.com/uuid' }], platform: [{ name: 'iPhone', }, { name: 'Mac', }, { name: 'Web', }] }
  6. Rest Client Rest Server endpoint 1 feature 1 endpoint 2

    feature 2 endpoint 3 feature 3 endpoint N feature N
  7. { id: 1, title: "Post title", tagline: "Post headline", votes_count:

    1, hunter: { id: 1, avatar_url: 'assets.producthunt.com/uuid' }, makers: [{ id: 2, avatar_url: 'assets.producthunt.com/uuid' }] }
  8. 
 query { post(id: 1){ id title tagline votes_count hunter

    { id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body
  9. 
 query { post(id: 1){ id title tagline votes_count hunter

    { id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body
  10. 
 query { post(id: 1){ id title tagline votes_count hunter

    { id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body { "data": { "post": { "id": 1, "title": "title", "tagline": "tagline", "votes_count": 0, "hunter": { "id": 1, "avatar_url": "assets.producthu }, "makers": [ { "id": 1, "avatar_url": "assets.product } ] } } }
  11. GraphQL is a query language created by Facebook in 2012

    which provides a common interface between the client and the server for data fetching and manipulations. The client asks for various data from the GraphQL server via queries.
  12. GraphQL • Single endpoint • Not just a library •

    Application-Layer Protocol • Server agnostic • Strongly-typed • Client-specified queries • Hierarchical
  13. Tries to solve • N+1 API queries • API response

    bloat • Documentation • Ad Hoc Endpoints • Structure issues
  14. QueryType = GraphQL::ObjectType.define do name 'Query' description 'The query root

    for this schema' field :post do type PostType description 'The post' argument :id, types.Int, 'Post id' resolve -> (obj, args, context) do Post.find args['id'] end end end Ruby Example
  15. PostType = GraphQL::ObjectType.define do name 'Post' field :id, types.Int field

    :title, types.String field :tagline, types.String field :votes_count, types.Int field :comments_count, types.Int field :thumbnail_url, types.String field :hunter do type -> { UserType } resolve -> (obj, args, context) do obj.user end end field :makers do type -> { types[UserType] } resolve -> (obj, args, context) do obj.makers end end end Ruby Example
  16. Query 
 query { post(id: 1){ id title tagline votes_count

    hunter { id avatar_url } makers { id avatar_url } } } { "data": { "post": { "id": 1, "title": "title", "tagline": "tagline", "votes_count": 0, "hunter": { "id": 1, "avatar_url": "assets.producthun }, "makers": [ { "id": 1, "avatar_url": "assets.producth } ] } } }
  17. Mutation 
 mutation { createUser(name: "Rado") { id } }

    { "data": { "createSpeaker": { "id": 2 } } }
  18. Documentation 
 query { __schema { types { name fields

    { name type { name kind ofType { name kind } } } } } } { "data": { "__schema": { "types": [ { "name": "Query", "fields": [ { "name": "user", "type": { "name": "Non-Null", "kind": "NON_NULL", "ofType": { "name": "User", "kind": "OBJECT" } } }, { "name": "post", "type": { "name": "Non-Null", "kind": "NON_NULL", "ofType": { "name": "Post", "kind": "OBJECT" } } } ] },
  19. query withFragments { user(id: 4) { friends(first: 10) { ...friendFields

    } mutualFriends(first: 10) { ...friendFields } } } fragment friendFields on User { id name profilePic(size: 50) } Cool tricks
  20. PostContainer = Relay.createContainer(Post, { fragments: { post: () => Relay.QL`

    fragment on Post { id title tagline votes_count } `, }, }); Relay
  21. Issues • New, just a draft specification • Mutations are

    weird • Best practices and solutions • Large datasets