All Projects → ravangen → Graphql Rate Limit

ravangen / Graphql Rate Limit

Licence: mit
🚦 Fixed window rate limiting middleware for GraphQL. Use to limit repeated requests to queries and mutations.

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Graphql Rate Limit

Portara
Portara directive is a rate limiter / throttler for GraphQL
Stars: ✭ 158 (-7.6%)
Mutual labels:  graphql, rate-limiter
Api.xiaoduyu.com
🐟小度鱼 - 年轻人的交流社区 https://www.xiaoduyu.com
Stars: ✭ 168 (-1.75%)
Mutual labels:  graphql
Vendure
A headless GraphQL ecommerce framework for the modern web
Stars: ✭ 2,961 (+1631.58%)
Mutual labels:  graphql
Express Graphql Example
Example project how to use Express and GraphQL
Stars: ✭ 163 (-4.68%)
Mutual labels:  graphql
Graphql Builder
GraphQL client library for Clojure and ClojureScript
Stars: ✭ 163 (-4.68%)
Mutual labels:  graphql
Graphql Spring Boot Starter
Spring boot starter for GraphQL
Stars: ✭ 166 (-2.92%)
Mutual labels:  graphql
Cms Mobile
A flutter project for amfoss cms
Stars: ✭ 162 (-5.26%)
Mutual labels:  graphql
Swifthub
GitHub iOS client in RxSwift and MVVM-C clean architecture
Stars: ✭ 2,330 (+1262.57%)
Mutual labels:  graphql
Graphql Toolkit
A set of utils for faster development of GraphQL tools
Stars: ✭ 169 (-1.17%)
Mutual labels:  graphql
Graphql Landscape
🌄Landscape for the GraphQL ecosystem
Stars: ✭ 163 (-4.68%)
Mutual labels:  graphql
Graphql Transform Federation
Convert your existing GraphQL schema into a federated schema
Stars: ✭ 163 (-4.68%)
Mutual labels:  graphql
Express Graphql Typescript Boilerplate
A starter kit for building amazing GraphQL API's with TypeScript and express by @w3tecch
Stars: ✭ 163 (-4.68%)
Mutual labels:  graphql
Wxapp Graphql
📱A GraphQL client for 微信小程序
Stars: ✭ 167 (-2.34%)
Mutual labels:  graphql
Examples
Examples of Mock Service Worker usage with various frameworks and libraries.
Stars: ✭ 163 (-4.68%)
Mutual labels:  graphql
Graphpack
☄️ A minimalistic zero-config GraphQL server.
Stars: ✭ 1,994 (+1066.08%)
Mutual labels:  graphql
Wp Graphql Gutenberg
Query gutenberg blocks with wp-graphql
Stars: ✭ 158 (-7.6%)
Mutual labels:  graphql
Workshops
Workshops organized to introduce students to security, AI, AR/VR, hardware and software
Stars: ✭ 162 (-5.26%)
Mutual labels:  graphql
Cppgraphqlgen
C++ GraphQL schema service generator
Stars: ✭ 166 (-2.92%)
Mutual labels:  graphql
Awesome Graphql
Awesome list of GraphQL
Stars: ✭ 13,020 (+7514.04%)
Mutual labels:  graphql
Graphql Errors
Simple error handler for GraphQL Ruby ❗️
Stars: ✭ 170 (-0.58%)
Mutual labels:  graphql

GraphQL Rate Limit

CircleCI Codecov npm Version npm Downloads Dependency Status Development Dependency Status

Fixed window rate limiting directive for GraphQL. Use to limit repeated requests to queries and mutations.

Features

  • 👨‍💻 Identification: Distinguish requests using resolver data
  • 🎯 Per-Object or Per-Field: Limit by objects and specific fields
  • 📦 Storage: Supports multiple data store choices (Redis, process Memory, ...)
  • ♾️ Throttles: Define any number of limits per field
  • 😍 TypeScript: Written in and exports type definitions

Install

yarn add graphql-rate-limit-directive

How it works

GraphQL Rate Limit wraps resolvers, ensuring an action is permitted before it is invoked. A client is allocated a maximum of n operations for every fixed size time window. Once the client has performed n operations, they must wait.

Usage

Step 1: Include directive type definition

Include createRateLimitTypeDef() as part of the schema's type definitions.

const schema = makeExecutableSchema({
  typeDefs: [createRateLimitTypeDef(), typeDefs],
  ...
});

Step 2: Include directive implementation

Include createRateLimitDirective() as part of the schema's directives. This implementes the @rateLimit functionality.

const schema = makeExecutableSchema({
  schemaDirectives: {
    rateLimit: createRateLimitDirective(),
  },
  ...
});

Step 3: Attach directive to field or object

Attach @rateLimit directive. Argument limit is number of allow operations per duration. Argument duration is the length of the fixed window (in seconds).

# Apply rate limiting to all fields of 'Query'
# Allow at most 60 queries per field within a minute
type Query @rateLimit(limit: 60, duration: 60) {
  ...
}

Overrides

When the directive is applied to a object, it rate limits each of its fields. A rate limit on a field will override a limit imposed by its parent type.

# Apply default rate limiting to all fields of 'Query'
type Query @rateLimit(limit: 60, duration: 60) {
  books: [Book!]

  authors: [Author!]

  # Override behaviour imposed from 'Query' object on this field to have different limit
  quote: String @rateLimit(limit: 1, duration: 60)
}

Example

Additional, advanced examples are available in the examples folder:

  • Context: isolating operations between users
  • Points: customize the cost of a field resolution
  • Redis: share state in a distrubuted environment
  • Multiple: applying multiple rate limits on the same field
  • onLimit Error: custom error raised
  • onLimit Object: custom result instead of default resolution
const { ApolloServer, gql } = require('apollo-server');
const {
  createRateLimitDirective,
  createRateLimitTypeDef,
} = require('graphql-rate-limit-directive');

const typeDefs = gql`
  # Apply default rate limiting to all fields of 'Query'
  type Query @rateLimit {
    books: [Book!]

    # Override behaviour imposed from 'Query' object on this field to have a custom limit
    quote: String @rateLimit(limit: 1)
  }

  type Book {
    # For each 'Book' where this field is requested, rate limit
    title: String @rateLimit(limit: 72000, duration: 3600)

    # No limits are applied
    author: String
  }
`;

const resolvers = {
  Query: {
    books: () => [
      {
        title: 'A Game of Thrones',
        author: 'George R. R. Martin',
      },
      {
        title: 'The Hobbit',
        author: 'J. R. R. Tolkien',
      },
    ],
    quote: () =>
      'The future is something which everyone reaches at the rate of sixty minutes an hour, whatever he does, whoever he is. ― C.S. Lewis',
  },
};

const server = new ApolloServer({
  typeDefs: [createRateLimitTypeDef(), typeDefs],
  resolvers,
  schemaDirectives: {
    rateLimit: createRateLimitDirective(),
  },
});
server
  .listen()
  .then(({ url }) => {
    console.log(`🚀  Server ready at ${url}`);
  })
  .catch(error => {
    console.error(error);
  });

API

createRateLimitDirective(options?)

Create an implementation of a rate limit directive.

options

Configure rate limit behaviour.

It is common to specify at least keyGenerator and limiterClass.

keyGenerator

Constructs a key to represent an operation on a field.

A key is generated to identify each request for each field being rate limited. To ensure isolation, the key is recommended to be unique per field. Supports both synchronous and asynchronous functions.

By default, it does not provide user or client independent rate limiting. See defaultKeyGenerator and context example.

WARNING: Inside a generator function, consider accessing the GraphQL context or memoizing any expensive calls (HTTP, database, ...) as the functions is run for each rate limited field.

limiterClass

An implementation of a limiter.

Storage implementations are provided by rate-limiter-flexible.

Supports Redis, process Memory, Cluster or PM2, Memcached, MongoDB, MySQL, PostgreSQL to control requests rate in single process or distributed environment.

Memory store is the default but not recommended for production as it does not share state with other servers or processes. See Redis example for use in a distributed environment.

limiterOptions

Configuration to apply to created limiters.

WARNING: If providing the keyPrefix option, consider using directive's name as part of the prefix to ensure isolation between different directives.

pointsCalculator

Calculate the number of points to consume.

Default with defaultPointsCalculator is to cost one point.

  • A positve number reduces the remaining points for consumption for one duration.
  • A zero skips consuming points (like a whitelist).
  • A negative number increases the available points for consumption for one duration.
onLimit

Behaviour when limit is exceeded.

Throw an error or return an object describing a reached limit and when it will reset. Default is to throw an error using defaultOnLimit. See error example and object example.

createRateLimitTypeDef(directiveName?)

Create a GraphQL directive type definition.

graphql-js >= 14 requires you to define your directives in your schema, before you attempt to use them. This generates the directive to be placed in your schema type definitions.

directiveName

Name of the directive to create.

defaultKeyGenerator(directiveArgs, obj, args, context, info)

Get a value to uniquely identify a field in a schema.

A field is identified by the key ${info.parentType}.${info.fieldName}. This does not provide user or client independent rate limiting. User A could consume all the capacity and starve out User B.

This function can be used in conjunction with context information to ensure user/client isolation. See context example.

directiveArgs

The arguments defined in the schema for the directive.

obj

The previous result returned from the resolver on the parent field.

args

The arguments provided to the field in the GraphQL operation.

context

Contains per-request state shared by all resolvers in a particular operation.

info

Holds field-specific information relevant to the current operation as well as the schema details.

defaultPointsCalculator(directiveArgs, obj, args, context, info)

Calculate the number of points to consume.

Cost one point.

directiveArgs

The arguments defined in the schema for the directive.

obj

The previous result returned from the resolver on the parent field.

args

The arguments provided to the field in the GraphQL operation.

context

Contains per-request state shared by all resolvers in a particular operation.

info

Holds field-specific information relevant to the current operation as well as the schema details.

defaultOnLimit(resource, directiveArgs, obj, args, context, info)

Raise a rate limit error when there are too many requests.

Throws a GraphQLError with message Too many requests, please try again in N seconds.

resource

The current rate limit information for this field.

directiveArgs

The arguments defined in the schema for the directive.

obj

The previous result returned from the resolver on the parent field.

args

The arguments provided to the field in the GraphQL operation.

context

Contains per-request state shared by all resolvers in a particular operation.

info

Holds field-specific information relevant to the current operation as well as the schema details.

Contributions

Contributions, issues and feature requests are very welcome.

If you are using this package and fixed a bug for yourself, please consider submitting a PR!

License

MIT © Robert Van Gennip

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].