I want to use graphql-rate-limit https://github.com/teamplanes/graphql-rate-limit with this library.
But I'm stuck at step 3 in the Usage instructions. It requires me to update the GraphQL Schema, but I don't need to do this in type-graphql so I'm not sure if type-graphql can work with graphql-rate-limit.
Is there any way to add a custom directive like this to queries or mutations in resolvers?
Instructions:
````
Use in your GraphQL Schema.
directive @rateLimit(
max: Int,
window: String,
message: String,
identityArgs: [String],
arrayLengthField: String
) on FIELD_DEFINITION
type Query {
# Limit queries to getThings to 10 per minute.
getThings: [Thing] @rateLimit(max: 10, window: "6s")
}
type Query {
# Limit attempts to login with a particular email to 10 per 2 hours.
login(email: String!, password: String!): String @rateLimit(max: 10, window: "2h", identityArgs: ["email"])
}
````
Nevermind. I have made a middleware to do the same thing. It uses redis to keep track of the numbers.
````
export default function RateLimit({window, max, limitByVariables, errorMessage}: RateLimitArgs) {
return UseMiddleware(async ({ info:{variableValues, fieldName} , context}: ResolverData<GqlContext>, next) => {
const redis = DBUtil.redis();
const visitorKey = context.user ? "user:"+context.user.id: "ip:"+context.ip;
const variableKey = limitByVariables &&
JSON.stringify(variableValues)
.replace(/[^a-zA-Z0-9,]/g,"")
.trim();
const key:string = ["limit", fieldName, variableKey, visitorKey].join(":");
const oldRecord = await redis.getAsync(key);
if(oldRecord) {
if(parseInt(oldRecord) > max){
throw new Error(errorMessage)
}else {
await redis.incrAsync(key)
}
}else{
await redis.setAsync(key, "1", 'EX', window);
}
return next();
});
}
````
Most helpful comment
Nevermind. I have made a middleware to do the same thing. It uses redis to keep track of the numbers.
````
export default function RateLimit({window, max, limitByVariables, errorMessage}: RateLimitArgs) {
}
````