GraphQL Accelerated
@mafintosh @matteocollina
GET /facebook-friends

[{
  "name": "matteo",
  "country": "italy",
  "..." // and 100s more
}, {
  ...
}]
    
GET /facebook-friends-names ?
GET /facebook-friends?filter=name ?
Nonstandard
GET /facebook-friends GET /facebook-likes
GET /facebook-friends-and-likes ?
GraphQL

# execute friends query    
friends(name: "mathias") {
  name
}
    

friends(name: "mathias") {
  # only return friend.name
  name
}
    

# define your types                 
type Friend {
  name: String
  country: String
  age: Int
}

type Query {
  friends (name: String): Friend
}
    

type Friend {
  name: String
  country: String
  age: Int
}

# define your query name/input/output
type Query {
  friends (name: String): Friend
}
    

friends(name: "mathias") {
  name
}
friends(name: "matteo") {
  name
  age
}
    

// also send { name: 'mathias' } as variables
// in the same request
query Run ($name: String) {
  friends(name: $name) {
    name
  }
}
    
GraphQL has a rich ecosystem
A popular community GraphQL framework is Apollo

const { ApolloServer, gql } = require('apollo-server')

const typeDefs = gql`
  type Query { hello: String }
`

const resolvers = {
  Query: { hello: () => 'world' }
}

const server = new ApolloServer({ typeDefs, resolvers })
server.listen()
    
Makes prototyping easy!
GraphQL comes at a cost
In the last few months, several customers felt GraphQL was underperforming compared to REST.

    $ clinic flame -- node express.js

    --- on another terminal

    $ autocannon -c 100 -d 5 \
      'http://localhost:3000/graphql?query={add\(x:2,y:2\)}'
    
On each and every request the server first has to parse the query to produce an Abstract Syntax Tree and then walk that to execute the query
Caching!
Experimental implementation
Uses an LRU to cache stable queries
npm install fastify-gql

const fastify = require('fastify')()

const schema = `
  type Query {
    add(x: Int, y: Int): Int
  }
`

const resolvers = {
  Query: {
    add: async (_, { x, y }) => x + y
  }
}

app.register(require('fastify-cors'))

app.register(require('fastify-gql'), {
  schema,
  resolvers
})

app.listen(3000)
    
We did additional performance analysis using clinic flame

Generated by the compiler

function executer () {
  return execute
  async function _query_ (_output) {
    const _res = await friends({ name: 'mathias' })
    _output.friends = _select(_res)
  }
  async function execute (input) {
    const _output = {
      friends: null
    }
    await _query_(_output)
    return { data: _output }
  }
}
async function execute (input) {
  const _output = {
    friends: null
  }
  await _query_(_output)
  return { data: _output }
}
function _select (data) {
  if (Array.isArray(data)) {
    const res = []
    for (var i = 0; i < data.length; i++) {
      const item = data[i]
      const val = {
        name: item.name
      }
      res.push(val)
    }
    return res
  }
  const val = {
    name: data.name
  }
  return val
}
    
Using our improvements GraphQL becomes very competitive to rolling your own stack
Check out our workshop: A new way to profile async activity in Node.js.

At 2:00pm today!
Thanks
@mafintosh @matteocollina