GraphQL with JavaScript

GraphQL with JavaScript

My GraphQL presentation from JSTalks

7a0e72a6f55811246bb5d9a946fd2e49?s=128

Radoslav Stankov

November 15, 2015
Tweet

Transcript

  1. Implementing GraphQL with
 JavaScript Radoslav Stankov 21/10/2015

  2. Radoslav Stankov @rstankov http://rstankov.com
 http://blog.rstankov.com http://github.com/rstankov

  3. None
  4. None
  5. None
  6. None
  7. None
  8. None
  9. 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 }
  10. None
  11. None
  12. GET /api/users/1 { id: 1, name: 'User Name', handle: 'user_name',

    avatar_url: 'assets.producthunt.com/uuid' }
  13. Rest Client Rest Server

  14. Rest Client Rest Server /api/posts?date=2015-10-31

  15. Rest Client Rest Server /api/posts?date=2015-10-31 /api/users/{x} (for X users)

  16. Rest Client Rest Server /api/posts?date=2015-10-31 /api/users/{x} (for X users)

  17. …approach 2

  18. 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' } }
  19. None
  20. None
  21. None
  22. None
  23. None
  24. None
  25. 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' }] }
  26. None
  27. None
  28. None
  29. 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', }] }
  30. None
  31. None
  32. …approach 3

  33. None
  34. Rest Client Rest Server

  35. Rest Client Rest Server endpoint 1 feature 1

  36. Rest Client Rest Server endpoint 1 feature 1 endpoint 2

    feature 2
  37. Rest Client Rest Server endpoint 1 feature 1 endpoint 2

    feature 2 endpoint 3 feature 3
  38. Rest Client Rest Server endpoint 1 feature 1 endpoint 2

    feature 2 endpoint 3 feature 3 endpoint N feature N
  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. { 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' }] }
  46. { id title tagline votes_count hunter { id avatar_url }

    makers { id avatar_url } }
  47. None
  48. GET /graphql Request Body Response Body

  49. 
 query { post(id: 1){ id title tagline votes_count hunter

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

    { id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body
  51. 
 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 } ] } } }
  52. It’s that simple

  53. 
 https://facebook.github.io/graphql


  54. 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.
  55. Architecture 
 GraphQL Library
 (Per-Language)
 
 Type
 Definitions
 
 Application


    Code

  56. GraphQL • Single endpoint • Not just a library •

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

    bloat • Documentation • Ad Hoc Endpoints • Structure issues
  58. Code var RootQueryType = new GraphQLObjectType({ name: 'RootQueryType', fields: {

    post: { type: PostType, description: 'Find post by id', args: { id: { description: 'Post id' type: new GraphQLNonNull(GraphQLInt) } }, resolve: function(_, params) { return data.posts.find(params.id); } }, });
  59. Code var PostType = new GraphQLObjectType({ name: 'Post', fields: function()

    { return { id: { type: GraphQLInt, }, title: { type: GraphQLString, }, user: { type: UserType, description: "Creator of the post", resolve: function(post) { return data.users.find(post.user_id); } }, }; } });
  60. Code var [TYPE] = new GraphQLObjectType({ name: [NAME],
 description: [DESCRIPTION],

    fields: function() { return { [FIELD_NAME]: { description: [DESCRIPTION], deprecation: [DEPRECATION MARKER], type: [TYPE],
 args: [LIST OF FIELD ARGUMENT],
 resolve: [FUNCTION] }, } } });
  61. Code var PostType = new GraphQLObjectType({ name: 'Post', fields: function()

    { return { id: { type: GraphQLInt,
 resolve: function(post) { return post.id; } }, user: { type: UserType, resolve: function(post) { return data.users.find(post.user_id); } }, }; } });
  62. Code var PostType = new GraphQLObjectType({ name: 'Post', fields: function()

    { return { id: { type: GraphQLInt }, user: { type: UserType, resolve: function(post) { return data.users.find(post.user_id); } }, }; } });
  63. 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 } ] } } }
  64. Mutation 
 mutation { createUser(name: "Rado") { id } }

    { "data": { "createSpeaker": { "id": 2 } } }
  65. Code var RootMutationType = new GraphQLObjectType({ name: 'RootMutationType', fields: {

    createPost: { type: PostType, args: { title: { type: new GraphQLNonNull(GraphQLString) }, tagline: { type: new GraphQLNonNull(GraphQLString) }, user_id: { type: new GraphQLNonNull(GraphQLInt) }, }, resolve: function(_, params) { if (!data.users.find(params.user_id)) { throw "Invalid user id - " + params.user_id; } return data.posts.create(params); }, }, }, });
  66. 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" } } } ] },
  67. { id hunter: { id name
 small_avatar_url: avatar_url(size: 100)
 big_avatar_url:

    avatar_url(size: 400) } } Cool tricks
  68. Code var UserType = new GraphQLObjectType({ name: 'User', fields: function()

    { return { // ... some field definitions ... picture: { type: GraphQLString, args: { size: { type: GraphQLInt }, }, resolve: function(user, params) { var size = params.size || 400; return 'file.example.com/' + user.picture_uuid + "?size=" + size; } }, }; } });
  69. query withFragments { user(id: 4) { friends(first: 10) { ...friendFields

    } mutualFriends(first: 10) { ...friendFields } } } fragment friendFields on User { id name profilePic(size: 50) } Cool tricks
  70. 
 https://facebook.github.io/react


  71. 
 https://facebook.github.io/relay


  72. None
  73. PostContainer = Relay.createContainer(Post, { fragments: { post: () => Relay.QL`

    fragment on Post { id title tagline votes_count } `, }, }); Relay
  74. Demo

  75. Issues • New, just a draft specification • Mutations are

    weird • Best practices and solutions • Large datasets
  76. None
  77. https://speakerdeck.com/rstankov/introduction-to-graphql

  78. https://github.com/rstankov/talks-code

  79. None
  80. None
  81. @rstankov Thanks :)

  82. Questions?