GraphQL

Kristoffer
Bra
brand

 

developer at

 

Building APIs for complex

[web] applications is not

easy..

How we often end up doing it

GraphQL to the rescue!

What?

A flexible, graph oriented 

querying language

[used by Relay]

Because we shouldn't have to care about what data different components the front end of our applications need when building the API.

Why?

A few essentials first..

Root call

The starting point of the query

Nodes

A data point in the graph. Could be a user, [event] incident or anything else your app knows of

Edges

Vertices in the graph, representing relations between nodes

Match(10012388) {
    ...
}

The root call

# Query
Match(10012388) {
    status,
    elapsed
}

# Response
{
    "10012388": {
        "status": "finished",
        "elapsed": 90
    }
}

Fetching properties

# Query
Match(10012388) {
    status,
    elapsed,
    homeTeam {
        edges {
            goals,
            node {
                Participant {
                    name
                }
            }
        }
    }
}

Exploring the graph

# Response
{
    "10012388": {
        "status": "finished",
        "elapsed": 90,
        "homeTeam": [{
            "goals": 0,
            "node": {
                "name": "Haugesund"
            }
        }]
    }
}

So what about the GraphQL backend?

What we "know"

  • FB is releasing a spec and a reference implementation
  • Anything beyond that is up to you
  • GraphQL queries can be mapped to any type of data backend
  • The GraphQL schema allows for validation and early errors when performing invalid operations
  • Response structure match the request structure
  • You can implement the node types you want – they are not predefined

GraphQL translates nicely to graph databases

[like Neo4j]

GraphQL

MATCH (m:Match {id:10012388})
RETURN {
    status: m.status,
    elapsed: m.elapsed
};
Match(10012388) {
    status,
    elapsed
}

Cypher

GraphQL

MATCH 
(m:Match {id:10012388}),
(m)-[h:HOMETEAM]->(ht:Participant)
RETURN 
{
    homeTeam: {
        goals: h.goals,
	name: ht.name
    },
    status: m.status,
    elapsed: m.elapsed
};
Match(10012388) {
    status,
    elapsed,
    homeTeam {
        edges {
            goals,
            node {
                Participant {
                    name
                }
            }
        }
    }
}

Cypher

Challenges

  • Securing the API against "dangerous" operations
  • Possible data leakages when the user is able to explore the graph at will
  • Implementing cursors/pagination in a meaningful way
  • Caching/purging

GraphQL

By Kristoffer Brabrand

GraphQL

Meetup talk on GraphQL

  • 1,448