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

Launching GitHub's GraphQL API

Launching GitHub's GraphQL API

Brooks Swinnerton

October 11, 2017
Tweet

More Decks by Brooks Swinnerton

Other Decks in Technology

Transcript

  1. { "login": "bswinnerton", "id": 934497, "avatar_url": "https://avatars1.githubusercontent.com/u/934497?v=4", "url": "https://api.github.com/users/bswinnerton", "html_url":

    "https://github.com/bswinnerton", "site_admin": true, "name": "Brooks Swinnerton", "location": "Brooklyn, NY", "email": "[email protected]", "bio": ":octocat:", "public_repos": 32, "public_gists": 55, "followers": 231, "following": 60, "created_at": "2011-07-23T17:44:47Z", "updated_at": "2017-10-02T17:38:48Z", "private_gists": 172, "total_private_repos": 9, "owned_private_repos": 8, "disk_usage": 87918, "collaborators": 7, "plan": { "name": "developer", "space": 976562499, "collaborators": 0, "private_repos": 9999 } } https://api.github.com/user GET
  2. { "login": "bswinnerton", "id": 934497, "avatar_url": "https://avatars1.githubusercontent.com/u/934497?v=4", "url": "https://api.github.com/users/bswinnerton", "html_url":

    "https://github.com/bswinnerton", "site_admin": true, "name": "Brooks Swinnerton", "location": "Brooklyn, NY", "email": "[email protected]", "bio": ":octocat:", "public_repos": 32, "public_gists": 55, "followers": 231, "following": 60, "created_at": "2011-07-23T17:44:47Z", "updated_at": "2017-10-02T17:38:48Z", "private_gists": 172, "total_private_repos": 9, "owned_private_repos": 8, "disk_usage": 87918, "collaborators": 7, "plan": { "name": "developer", "space": 976562499, "collaborators": 0, "private_repos": 9999 } } https://api.github.com/user GET
  3. { "login": "bswinnerton", "id": 934497, "name": "Brooks Swinnerton", "location": "Brooklyn,

    NY", "email": "[email protected]", "bio": ":octocat:", ... } https://api.github.com/user GET
  4. https://api.github.com/user GET { "login": "bswinnerton", "id": 934497, "name": "Brooks Swinnerton",

    "location": "Brooklyn, NY", "email": "[email protected]", "bio": ":octocat:", "public_repos": 32, "public_gists": 55, "private_gists": 172, "owned_private_repos": 8, ... }
  5. https://api.github.com/user GET { "login": "bswinnerton", "id": 934497, "name": "Brooks Swinnerton",

    "location": "Brooklyn, NY", "email": "[email protected]", "bio": ":octocat:", "public_repos": 32, "public_gists": 55, "private_gists": 172, "owned_private_repos": 8, "url": "https://api.github.com/users/bswinnerton", "gists_url": "https://api.github.com/users/bswinnerton/gists{/ gist_id}", "repos_url": "https://api.github.com/users/bswinnerton/repos", ... }
  6. https://api.github.com/user GET { "login": "bswinnerton", "id": 934497, "name": "Brooks Swinnerton",

    "location": "Brooklyn, NY", "email": "[email protected]", "bio": ":octocat:", "public_repos": 32, "public_gists": 55, "private_gists": 172, "owned_private_repos": 8, "url": "https://api.github.com/users/bswinnerton", "gists_url": "https://api.github.com/users/bswinnerton/gists{/ gist_id}", "repos_url": "https://api.github.com/users/bswinnerton/repos", ... }
  7. https://api.github.com/users/bswinnerton/repos GET [ { "id": 82398282, "name": "launchbar-github", "private": false,

    "description": "A LaunchBar action for GitHub", "language": "JavaScript", "homepage": "http://launchbar-github.com", "owner": { "login": "bswinnerton", "id": 934497, "url": "https://api.github.com/users/bswinnerton", ... }, "url": "https://api.github.com/repos/bswinnerton/launchbar-github", "issues_url": "https://api.github.com/repos/bswinnerton/launchbar-github/ issues{/number}" }, ... ]
  8. https://api.github.com/users/bswinnerton/repos GET [ { "id": 82398282, "name": "launchbar-github", "private": false,

    "description": "A LaunchBar action for GitHub", "language": "JavaScript", "homepage": "http://launchbar-github.com", "owner": { "login": "bswinnerton", "id": 934497, "url": "https://api.github.com/users/bswinnerton", ... }, "url": "https://api.github.com/repos/bswinnerton/launchbar-github", "issues_url": "https://api.github.com/repos/bswinnerton/launchbar-github/ issues{/number}" }, ... ]
  9. https://api.github.com/repos/bswinnerton/launchbar-github/issues GET [ { "id": 246489445, "number": 83, "title": "Error

    when viewing Gists of another user", "state": "open", "body": "I can't reproduce this in every case...", "user": { "login": "bswinnerton", "id": 934497, "url": "https://api.github.com/users/bswinnerton", ... }, "url": "https://api.github.com/repos/bswinnerton/launchbar-github/issues/ 83", "repository_url": "https://api.github.com/repos/bswinnerton/launchbar- github", ... }, ... ]
  10. { viewer { name email } } { "data": {

    "viewer": { "name": "Brooks Swinnerton", "email": "[email protected]" } } }
  11. https://api.github.com/graphql POST { user(login:"defunkt") { name bio } } {

    "data": { "user": { "name": "Chris Wanstrath", "bio": """ } } }
  12. { viewer { name email } } type RootQuery {

    viewer: User } type User { name: String email: String }
  13. { viewer { name email } } type RootQuery {

    viewer: User } type User { name: String email: String }
  14. { viewer { name email } } type RootQuery {

    viewer: User } type User { name: String email: String }
  15. type RootQuery { user(login: String): User } type User {

    name: String bio: String } { user(login:"defunkt") { name bio } }
  16. { user(login:"defunkt") { name bio } } type RootQuery {

    user(login: String): User } type User { name: String bio: String }
  17. type RootQuery { user(login: String): User } type User {

    name: String bio: String } { user(login:"defunkt") { name bio } }
  18. type RootQuery { user(login: String): User } type User {

    name: String bio: String } { user(login:"defunkt") { name bio } }
  19. { licenses { name nickname url } } type RootQuery

    { licenses: [License]! } type License { name: String! nickname: String url: URL! }
  20. { licenses { name nickname url } } type RootQuery

    { licenses: [License]! } type License { name: String! nickname: String url: URL! }
  21. { licenses { name nickname url } } type RootQuery

    { licenses: [License]! } type License { name: String! nickname: String url: URL! }
  22. { user(login: "defunkt") { name bio } user(login: "bswinnerton") {

    name bio } } { "data": { "user": { "name": "Chris Wanstrath", "bio": """ }, "user": { "name": "Brooks Swinnerton", "bio": "#$" } } }
  23. { user(login: "defunkt") { name bio } user(login: "bswinnerton") {

    name bio } } { "data": { "user": { "name": "Chris Wanstrath", "bio": """ }, "user": { "name": "Brooks Swinnerton", "bio": "#$" } } }
  24. { "data": { "chris": { "name": "Chris Wanstrath", "bio": """

    }, "brooks": { "name": "Brooks Swinnerton", "bio": "#$" } } }
  25. { "data": { "chris": { "name": "Chris Wanstrath", "bio": """

    }, "brooks": { "name": "Brooks Swinnerton", "bio": "#$" } } }
  26. { chris: user(login: "defunkt") { ...UserInfo } brooks: user(login: "bswinnerton")

    { ...UserInfo } } fragment UserInfo on User { name bio }
  27. { "data": { "user": { "name": "Chris Wanstrath", "bio": """

    } } } { "login": "defunkt" } query($login:String!) { user(login:$login) { name bio } }
  28. { viewer { repositories { totalCount } } } {

    "data": { "viewer": { "repositories": { "totalCount": 65 } } } }
  29. { viewer { repositories(first:2) { edges { node { name

    } } } } } { "data": { "viewer": { "repositories": { "edges": [ { "node": { "name": "nyc-restaurant-grades" } }, { "node": { "name": "launchbar-github" } } ] } } } }
  30. { viewer { repositories(first:2) { edges { cursor node {

    name } } } } } { "data": { "viewer": { "repositories": { "edges": [ { "cursor": "Y3Vyc29yOnYyOpHOA5rd9g==", "node": { "name": "nyc-restaurant-grades" } }, { "cursor": "Y3Vyc29yOnYyOpHOBOlMSg==", "node": { "name": "launchbar-github" } } ] } } } }
  31. { viewer { repositories(first:2) { edges { cursor node {

    name } } } } } { "data": { "viewer": { "repositories": { "edges": [ { "cursor": "Y3Vyc29yOnYyOpHOA5rd9g==", "node": { "name": "nyc-restaurant-grades" } }, { "cursor": "Y3Vyc29yOnYyOpHOBOlMSg==", "node": { "name": "launchbar-github" } } ] } } } }
  32. { viewer { repositories(first:2) { edges { cursor node {

    name } } } } } { "data": { "viewer": { "repositories": { "edges": [ { "cursor": "Y3Vyc29yOnYyOpHOA5rd9g==", "node": { "name": "nyc-restaurant-grades" } }, { "cursor": "Y3Vyc29yOnYyOpHOBOlMSg==", "node": { "name": "launchbar-github" } } ] } } } }
  33. { "data": { "viewer": { "repositories": { "edges": [ {

    "cursor": "Y3Vyc29yOnYyOpHOAIibww==", "node": { "name": "bswinnerton.github.io" } }, { "cursor": "Y3Vyc29yOnYyOpHOArDTpw==", "node": { "name": "dotfiles" } } ] } } } }
  34. March 20, 2016: Proposal submitted April 6, 2016: Proof of

    concept April 12, 2016: New team created September 4th, 2016: Early access May 22, 2017: API v4
  35. March 20, 2016: Proposal submitted April 6, 2016: Proof of

    concept April 12, 2016: New team created September 4th, 2016: Early access May 22, 2017: API v4
  36. March 20, 2016: Proposal submitted April 6, 2016: Proof of

    concept April 12, 2016: New team created September 4th, 2016: Early access May 22, 2017: API v4
  37. March 20, 2016: Proposal submitted April 6, 2016: Proof of

    concept April 12, 2016: New team created September 4th, 2016: Early access May 22, 2017: API v4
  38. March 20, 2016: Proposal submitted April 6, 2016: Proof of

    concept April 12, 2016: New team created September 4th, 2016: Early access May 22, 2017: API v4
  39. March 20, 2016: Proposal submitted April 6, 2016: Proof of

    concept April 12, 2016: New team created September 4th, 2016: Early access May 22, 2017: API v4 Today: 200 million queries/day
  40. { viewer { repositories(last:100) { edges { node { name

    issues(last:50) { edges { node { title } } } } } } } rateLimit(dryRun:true) { nodeCount } }
  41. { viewer { repositories(last:100) { edges { node { name

    issues(last:50) { edges { node { title } } } } } } } rateLimit(dryRun:true) { nodeCount } }
  42. { viewer { repositories(last:100) { edges { node { name

    issues(last:50) { edges { node { title } } } } } } } rateLimit(dryRun:true) { nodeCount } } { "data": { "rateLimit": { "nodeCount": 5100 } } }
  43. { viewer { repositories(last:100) { edges { node { name

    issues(last:50) { edges { node { title } } } } } } } rateLimit(dryRun:true) { cost } } { "data": { "rateLimit": { "cost": 1 } } }
  44. @result = GraphQL::Client.query(ProjectsQuery) <% @result.data.projects.each do |project| %> <h1><%= project.name

    %></h1> <% project.columns.each do |column| %> <p><%= column.name %></p> <p><%= column.cards.total_count %></p> <% column.cards.each do |card| %> <% card.title %> <p>Opened by <%= card.owner.login %></p> <% end %> <% end %> <% end %> Controller View