GraphQL for Gateways

and runtime

tech

● MIT-licensed

● Better Different approach to API design

“GraphQL” and its logo are ©2018 Facebook Inc.

Query Language: Intro

● SQL, Xpath, , etc ● Example schema:

Query Language: Example SQL

● Summarize the effort behind Stockfish

SELECT u.name, u.org, array_agg(pg.group_name) AS groups FROM project_group_rel pg LEFT JOIN group_user_rel gu ON gu.group_name = pg.group_name INNER JOIN users u ON u.name = gu.user_name WHERE project_name = 'Stockfish' GROUP BY u.name, u.org;

name | org | groups ------+------+------Ada | Cyberdyne Systems | {ML} Sally | Cyberdyne Systems | {UX,ML}

Query Language: Example GraphQL

● Summarize the effort behind Stockfish In: Out: { { projects(name: “Stockfish”) { ”project”: { “groups”: [ groups { { name ”name”: “ML”, users { name org } ”users”: [ } { } ”name”: “Ada”, } ”org”: “Cyberdyne Systems” }, { “name”: “Sally”, “org”: “Cyberdyne Systems” } ] }, { ”name”: “UX”, ”users”: [ { “name”: “Sally”, “org”: “Cyberdyne Systems”

/* … various closing brackets ... */ Query Language: Type System

● Server: type Project { type Query { name: String! project(name: String!): Project alignment: Alignment! projects(): [Project]! groups: [Group]! group(name: String!): Group } groups(): [Group]! type Group { user(name: String!): User name: String! users(): [User]! title: String! } projects: [Project]! users: [User]! } type User { name: String! org: String! groups: [Group]! } enum Alignment { lawful good neutral good ... etc }

Runtime: vs. REST

● REST GET /projects/Stockfish/groups /projects for $groupURL in groups: /projects/$name GET $groupURL/users /projects/$name/groups for $userURL in $users: /groups GET $userURL /groups/$name /groups/$name/users /users /users/$name /users/$name/groups

● GraphQL type Query { GET /graphql?query={ project(name: String!): Project projects(name: “Stockfish”) { projects(): [Project]! groups { group(name: String!): Group name groups(): [Group]! users { name org } user(name: String!): User } users(): [User]! } } }

Runtime: vs. REST

● REST GET /projects/Stockfish/groups /projects for $groupURL in groups: /projects/$name GET $groupURL/users /projects/$name/groups for $userURL in $users: /projects/$name/summary GET $userURL /groups /groups/$name /groups/$name/users ● GET /projects/Stockfish/summary /users ● GET /projects/Stockfish ?include=groups,users /users/$name /users/$name/groups

● GraphQL type Query { GET /graphql?query={ project(name: String!): Project projects(name: “Stockfish”) { projects(): [Project]! groups { group(name: String!): Group name groups(): [Group]! users { name org } user(name: String!): User } users(): [User]! } } }

Runtime: vs. REST

● REST GET /projects/Stockfish/groups /projects for $groupURL in groups: /projects/$name GET $groupURL/users /projects/$name/groups for $userURL in $users: /projects/$name/summary GET $userURL /projects/$name/related /groups /groups/$name ● GET /projects/Stockfish/summary /groups/$name/users ● GET /projects/Stockfish ?include=groups,users /users /users/$name ● GET /projects/Stockfish/related /users/$name/groups

● type Query { GraphQL project(name: String!): Project GET /graphql?query={ projects(): [Project]! projects(name: “Stockfish”) { group(name: String!): Group groups { groups(): [Group]! name user(name: String!): User users { name org } users(): [User]! projects { name } } } } } Agility & Expressiveness, at a price

● Pros ● Cons ● Responds well to ● Non-standard requirement change ● a e s t h e t i c ● Less dependency ● More latency between front- and ● “Production-izing” back-end teams more costly ● Supports multiple consumer types readily . ● Consistent ● Less latency