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

Build Scalable APIs using GraphQL and Serverless

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for TechMasters TechMasters
September 28, 2018

Build Scalable APIs using GraphQL and Serverless

By Simona Cotin - Microsoft

Presented at Functions 2018 / ServerlessDays Toronto

https://functions.events/2018/toronto/simona-cotin/

Avatar for TechMasters

TechMasters

September 28, 2018
Tweet

More Decks by TechMasters

Other Decks in Programming

Transcript

  1. @simona_cotin https://facebook.com/user/id/events 1 { 2 "name": "ServerlessDays", 3 "location": "Toronto",

    4 "organiser": “Ahmad Nassri", 5 "size": "300", 6 "attendees": [ 7 { 8 "name": “Maxime", 9 "company": "Microsoft", 10 "role": “Durable Functions Chef" 11 } 12 ], 13 "..." 14 }
  2. @simona_cotin https://facebook.com/user/id/friends-suggestions 1 { 2 "firstname": "Peggy", 3 "lastname": "Rayzis",

    4 "profile_pic": "some_url", 5 “mutual_friends”: [] 6 } 1 { 2 "mutual_friends": [ 3 { 4 "name": "Mike Watson", 5 "company": "Apollo", 6 "role": "Apollo Chef", 7 "..." 8 } 9 ] 10 } https://facebook.com/user/id/mutual-friends
  3. @simona_cotin 1 query { 2 user(id: "101") { 3 firstname

    4 lastname 5 events { 6 count 7 } 8 friends_suggestions { 9 name 10 mutual_friends { 11 count 12 } 13 } 14 } 15 } https://facebook.com/graphql 1 { 2 "data": { 3 "user": { 4 "firstname": "Simona", 5 "lastname": "Cotin", 6 "events": { 7 "count": "4" 8 }, 9 "friends_suggestions": { 10 "name": "Zachary Deptawa", 11 "mutual_friends": { 12 "count": "12" 13 } 14 } 15 } 16 } 17 }
  4. @simona_cotin const { buildSchema } = require('graphql'); const typeDefs =

    buildSchema(` type Team { id: ID! name: String points: Int } type Query { teams: [Team] } type Mutation { incrementPoints(id: ID!): Team } `);
  5. @simona_cotin type People { id: ID! name: String avatar: URL

    } type Team { id: ID! name: String points: Int people: [People] }
  6. @simona_cotin 1 query { 2 teams { 3 name 4

    points 5 } 6 } 1 { 2 "data": { 3 "teams": [ 4 { 5 "name": "red", 6 "points": 232 7 }, 8 { 9 "name": "green", 10 "points": 255 11 } 12 ] 13 } 14 }
  7. @simona_cotin 1 mutation { 2 incrementPoints(id:2) { 3 id 4

    name 5 points 6 } 7 } 1 { 2 "data": { 3 "incrementPoints": { 4 "id": "2", 5 "name": "green", 6 "points": 256 7 } 8 } 9 }
  8. @simona_cotin const root = { teams: (obj, args, context) =>

    { return axios .get('https://graphqlvoting.azurewebsites.net/ api/score') .then(res => res.data); }, incrementPoints: (obj, args, context) => { return axios .get(`https://graphqlvoting.azurewebsites.net/ api/score/${obj.id}`) .then(res => res.data); } };
  9. @simona_cotin module.exports = async function(context, req) { const body =

    req.body; await graphql( schema, body.query, root, null, body.variables, body.operationName ).then(response => { context.res = { body: response }; }); };
  10. @simona_cotin { "bindings": [ { "authLevel": "anonymous", "type": "httpTrigger", "direction":

    "in", "name": "req", "methods": ["get", "post"], "route": "graphql" }, { "type": "http", "direction": "out", "name": "res" } ] }
  11. @simona_cotin { "$schema": "http://json.schemastore.org/proxies", "proxies": { "proxy1": { "matchCondition": {

    "methods": ["GET"], "route": "/api/graphiql" }, "backendUri": "https:// graphqlvoting.blob.core.windows.net/static/index.html" } } }
  12. @simona_cotin Photo by Charles Deluvio on Unsplash –Max Stoiber https://blog.apollographql.com/securing-your-graphql-api-from-

    malicious-queries-16130a324a6b “With GraphQL you can query exactly what you want whenever you want. That is amazing for working with an API, but also has complex security implications.”
  13. @simona_cotin query { teams { name points people { name

    avatar friends { name shared_events { name location } } } ... } }
  14. @simona_cotin query { teams { name points people { name

    avatar friends { name shared_events { name location } } } ... } }
  15. @simona_cotin query evil { teams { people { friends {

    people { friends { people { friends ... } } } } } } }
  16. @simona_cotin validationRules: [ depthLimit(10) ] { "errors": [ { "message":

    "'evil' exceeds maximum operation depth of 10", "locations": [ { "line": 13, "column": 25 } ] } ] }
  17. @simona_cotin const MAX_ALLOWED = 100; if (first > MAX_ALLOWED) {

    throw new Error(`${query} exceeds maximum operation amount of 100`); } { "errors": [ { "message": "'evil' exceeds maximum operation amount of 100", .. } ] }
  18. @simona_cotin Azure Functions Azure Functions Proxies GraphQL Github GraphQL API

    Awesome Graphql https://aka.ms/azure-functions https://aka.ms/az-proxies https://aka.ms/graphql https://aka.ms/gihub-api https://aka.ms/awesome-graphql