spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.5k stars 3.31k forks source link

Add a different way to retrieve configuration for Rate Limiting #582

Open spencergibb opened 5 years ago

spencergibb commented 5 years ago

Currently, it is per route, but there are stories where it could be based on information in the request (such as host or header).

spencergibb commented 5 years ago

/cc @ryanjbaxter @ciberkleid

EstebanDugueperoux2 commented 4 years ago

Hello,

I'm interested by this use case. In my case, I have a KeyResolver which use OAuth2 to get a client-id identifying an API consumer. And I would like to be able to define rate limits by client-id.

Instead of having a routeId specific rate limit configuration like:

spring:
  cloud:
    gateway:
      routes:
        - id: custody-securities
          uri: lb://custody-securities
          predicates:
            - Path=/gateway/custody-securities/api/v1/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                # Global rate limit for this API
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 10

we could have something like that:

spring:
  cloud:
    gateway:
      routes:
        - id: custody-securities
          uri: lb://custody-securities
          predicates:
            - Path=/gateway/custody-securities/api/v1/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                # Global rate limit for this API
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 10
          metadata:
            # Specific rate limit for this API for specified client-id
            specific-rate-limits:
              - 4db4a537-6333-450c-a943-03f154fbaa23: oauth2ClientIDKeyResolver
                args:
                  redis-rate-limiter.replenishRate: 2
                  redis-rate-limiter.burstCapacity: 2
              - de38b391-4852-49b9-9ac9-b293e59f216f: oauth2ClientIDKeyResolver
                args:
                  redis-rate-limiter.replenishRate: 5
                  redis-rate-limiter.burstCapacity: 5

With a global rate limiting configuration as usual and some client-id specific rate limiting configurations stored in metadata, which allows to store complex structure in opposite to args attribute.

From these metadata, algorithm could load a specific rate limiting configuration from a keyResolver value. In this case oauth2ClientIDKeyResolver resolver will be used and if a corresponding entry exists in configuration map, this specific rate limiting configuration would be used, instead the global one would be used.

What do you think about this strategy?

spencergibb commented 4 years ago

I want some kind of interface that users can implement. Putting keys in configuration for specific clients isn't going to scale well.

reetik-raj commented 3 years ago

@spencergibb @EstebanDugueperoux2 we have a similar use case for our company where we want rate limiting on routes based on clients. Would love to know if any workaround has been found. Personally, I couldn't find anything similar yet.