Type-graphql: Does it work with graphql-rate-limit?

Created on 2 Apr 2019  路  1Comment  路  Source: MichalLytek/type-graphql

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.

This must be added to the top of your 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"])
}
````

Question Solved

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) {

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();
});

}
````

>All comments

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();
});

}
````

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MichalLytek picture MichalLytek  路  3Comments

maplesteve picture maplesteve  路  3Comments

tongtwist picture tongtwist  路  3Comments

Asim13se picture Asim13se  路  3Comments

glentakahashi picture glentakahashi  路  3Comments