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. Introduction
    to
    GraphQL
    Radoslav Stankov 08/10/2015

    View full-size slide

  2. Radoslav Stankov
    @rstankov

    http://rstankov.com

    http://blog.rstankov.com

    http://github.com/rstankov

    View full-size slide

  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
    }

    View full-size slide

  4. GET /api/users/1
    {
    id: 1,
    name: 'User Name',
    handle: 'user_name',
    avatar_url: 'assets.producthunt.com/uuid'
    }

    View full-size slide

  5. Rest Client
    Rest Server

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. …approach 2

    View full-size slide

  10. 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'
    }
    }

    View full-size slide

  11. 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'
    }]
    }

    View full-size slide

  12. 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',
    }]
    }

    View full-size slide

  13. …approach 3

    View full-size slide

  14. Rest Client
    Rest Server

    View full-size slide

  15. Rest Client
    Rest Server
    endpoint 1
    feature 1

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  18. Rest Client
    Rest Server
    endpoint 1
    feature 1
    endpoint 2
    feature 2
    endpoint 3
    feature 3
    endpoint N
    feature N

    View full-size slide

  19. {
    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'
    }]
    }

    View full-size slide

  20. {
    id
    title
    tagline
    votes_count
    hunter {
    id
    avatar_url
    }
    makers {
    id
    avatar_url
    }
    }

    View full-size slide

  21. GET /graphql
    Request Body Response Body

    View full-size slide


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

    View full-size slide


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

    View full-size slide


  24. 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
    }
    ]
    }
    }
    }

    View full-size slide

  25. It’s that simple

    View full-size slide


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


    View full-size slide

  27. 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.

    View full-size slide

  28. Architecture

    GraphQL Library

    (Per-Language)


    Type

    Definitions


    Application

    Code


    View full-size slide

  29. GraphQL
    • Single endpoint
    • Not just a library
    • Application-Layer Protocol
    • Server agnostic
    • Strongly-typed
    • Client-specified queries
    • Hierarchical

    View full-size slide

  30. Tries to solve
    • N+1 API queries
    • API response bloat
    • Documentation
    • Ad Hoc Endpoints
    • Structure issues

    View full-size slide

  31. 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

    View full-size slide

  32. 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

    View full-size slide

  33. 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
    }
    ]
    }
    }
    }

    View full-size slide

  34. Mutation

    mutation {
    createUser(name: "Rado") {
    id
    }
    }
    {
    "data": {
    "createSpeaker": {
    "id": 2
    }
    }
    }

    View full-size slide

  35. 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"
    }
    }
    }
    ]
    },

    View full-size slide

  36. {
    id
    hunter: {
    id
    name

    small_avatar_url: avatar_url(size: 100)

    big_avatar_url: avatar_url(size: 400)
    }
    }
    Cool tricks

    View full-size slide

  37. query withFragments {
    user(id: 4) {
    friends(first: 10) {
    ...friendFields
    }
    mutualFriends(first: 10) {
    ...friendFields
    }
    }
    }
    fragment friendFields on User {
    id
    name
    profilePic(size: 50)
    }
    Cool tricks

    View full-size slide


  38. https://facebook.github.io/react


    View full-size slide


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


    View full-size slide

  40. PostContainer = Relay.createContainer(Post, {
    fragments: {
    post: () => Relay.QL`
    fragment on Post {
    id
    title
    tagline
    votes_count
    }
    `,
    },
    });
    Relay

    View full-size slide

  41. Issues
    • New, just a draft specification
    • Mutations are weird
    • Best practices and solutions
    • Large datasets

    View full-size slide

  42. https://speakerdeck.com/rstankov/introduction-to-graphql

    View full-size slide

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

    View full-size slide

  44. @rstankov
    Thanks :)

    View full-size slide