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

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