Query Timeout
Query Size
app.use("*", (req, res, next) => {
const query = req.body.query;
if (query.length > 2500)
throw new Error("Query Size Limit");
return next();
});
Query Amount
import { GraphQLInputInt } from "graphql-input-number";
const amountLimit = GraphQLInputInt({
name: "amountLimit",
min: 1,
max: 150
});
type Company {
employees(first: amountLimit, after: String): [Person]
}
query {
miniServerDestroyer(name: "To The Enthusiastic") {
employees(first: 1000) { ... }
}
}
Query Depth
query {
serverDestroyer(name:"To The Unprepared") {
this{
that{
this{
that{
this{
that{
// 1 million times deeper
}
}
}
}
}
}
}
}
import depthLimitation from "graphql-depth-limit";
const depthLimit = depthLimitation(
10,
{ ignore: [/_trusted$/, "idontcare"] },
depths => console.log(depths)
);
app.use(
"/graphql",
graphqlHTTP({
schema: schema,
rootValue: resolvers,
validationRules: [depthLimit]
})
);
{
"errors": [
{
"message": "'serverDestroyer' exceeds max depth of 10",
"locations": [
{
...
}
]
}
]
}
Query Complexity
query {
UltimateServerDestroyer(name: "A safe place for any weary developer") {
DESTRUUCTIIOOONN(first: 150) { ... }
EXPLOOOSIIIOOONSSS(first: 150) {
BAAMM { ... }
POOWW(first: 150) { ... }
WAAMM { ... }
KABBOOOOOOOM(first: 150) { ... }
}
}
}
import { createComplexityLimitRule } from 'graphql-validation-complexity';
const complexityLimit = createComplexityLimitRule(1000, {
scalarCost: 1,
objectCost: 10, // Default is 0.
listFactor: 20, // Default is 10.
});
// Then use this rule with validate() or other validation APIs.
app.use(
"/graphql",
graphqlHTTP({
schema: schema,
rootValue: resolvers,
validationRules: [complexityLimit]
})
);
Conclusion