5 interesting things you probably shouldn't do with GraphQL
A.K.A. Those are bad practices / antipaterns
If you have high blood pressure and/or care about best practices, leave now!
!
!
On the menu tonight
- Function based vs Graph/Circular object
- Queries are Async, Mutations are Sync
- Parameter chaining / context hoarding
- Live resolvers with subscriptions
- Dataloaders to share logic/data
Traditional GraphQL resolvers
Function based resolvers

Traditional GraphQL resolvers
Function based resolvers

query {
authors{
id
name
}
}
{
id: 0,
name: 'Arthur',
tweets: () => getTweets([0,1])
},
{
id:1,
name: 'Bob',
tweets: () => getTweets([2)]
}
Traditional GraphQL resolvers
Function based resolvers

query {
authors{
id
name
tweets{
id
text
}
}
{
id: 0,
name: 'Arthur',
tweets: () => getTweets([0,1])
},
{
id:1,
name: 'Bob',
tweets: () => getTweets([2)]
}
{
id: 0,
text: 'Hello world',
author: () => getUser(0)
},
{
id:1,
text: 'Another one',
author: () => getUser(1)
}
{
id: 2,
text: 'Hello world',
author: () => getUser(1)
}
GraphQL
Circular Objects

query {
authors{
id
name
}
{
id: 0,
name: 'Arthur',
tweets: [ { id: 0, text:'Hello World', author:{...}},
{ id: 1, text: 'Another One', author:{...}]
},
{
id:1,
name: 'Bob',
tweets: [ { id: 2, text:'Hello World', author:{...}}]
},
GraphQL
Graph / Circular Objects

query {
authors{
id
name
tweets{
id
text
}
}
{
id: 0,
name: 'Arthur',
tweets: [ { id: 0, text:'Hello World', author:{...}},
{ id: 1, text: 'Another One', author:{...}]
},
{
id:1,
name: 'Bob',
tweets: [ { id: 2, text:'Hello World', author:{...}}]
},
GraphQL
Graph / Circular Objects
- Super fast to resolve deeply nested structures
- Easy to type / build static objects
- Less verbose resolvers
- Need to maintain sync between database and memory
- Most likely need to pull from the database on startup (serverless will kill you)
- Memory cost money and databases are designed to handle that kind of datafetching
- Prepare yourself for distributed backend horror stories and out of sync servers
Queries are Async, Mutations are Sync
Queries are Async, Mutations are Sync
- base for the next trick
- use (fake) queries and mutations in the same request
- Be prepared to face confused coworkers
- GraphQL doesn't document itself
- No frontend libraries will understand you (bye bye Apollo and gqless)
- "WTF are you doing there?"
Parameter chaining & context hoarding
Parameter chaining & context hoarding
- Get backend powers in your frontend
- Cache expensive database queries
- Reduce the number of roundtrips
- Might fail halfway, your UI needs to prepare for it
- Must be comfortable with each mutation resolvers, people might not go through your flow if they have a choice.
- Harder to secure
Live resolvers with subscriptions
Live resolvers with subscriptions
- Get data ASAP
- upgrade to websocket your communications
- Required data might be "missing"
- websockets still not 100% there (gateway timeouts, offline handling, ...)
- Way more code for your Frontend
Dataloaders to share logic/data
Dataloaders to share logic/data
- Closest to best practices of all the tips (prevent N+1s database calls)
- speeds everything up
- Easy to get wrong (mismatch input/return)
- Do not do Auth/autorization in them
- More verbose, especially if you want to keep passing the context/parameters down the line
deck
By pookmook
deck
- 117