Rate Limiting with GraphQL Yoga

17 Oct 2022

directive @rateLimit(
  max: Int
  window: String
  message: String
) on FIELD_DEFINITION

type Query {
  episodes: [Episode!]!
    @rateLimit(window: "60s", max: 3, message: "Rate limit exceeded!")
}
type Episode {
  title: String!
}
interface UserContext {
  user?: User;
}

const context = async ({ request }): Promise<UserContext> => {
  const userId = request.headers.get("authorization") ?? null;
  const user = users.find((user) => user.id === userId);

  return {
    user,
  };
};

const server = createServer<{}, UserContext>({
  schema: {
    typeDefs,
    resolvers,
  },
  plugins: [
    useRateLimiter({
      identifyFn: (context: any) => context?.user?.id ?? null,
      onRateLimitError(event) {
        throw new GraphQLYogaError(event.error);
      },
    }),
  ],
  context,
});