Giter Club home page Giter Club logo

rate-limiter-javaee's Introduction

rate limiter javaee

Enterprise rate limiter for javaee web applications, based on rate-limiter-web-core.

We believe that rate limiting should be as simple as:

@Rate(10) // 10 permits per second for all methods in this class
@Path("/api")
public class GreetingResource {

  @Rate(permits=10, when="web.request.user.role=GUEST")
  @GET @Path("/smile")
  public String smile() {
    return ":)";
  }

  @Rate(permits=1, when="jvm.memory.available<1gb")
  @GET @Path("/greet")
  public String greet(@QueryParam("who") String who) {
    return "Hello " + who;
  }
}

Please first read the rate-limiter-web-core documentation.

To add a dependency on rate-limiter-javaee using Maven, use the following:

        <dependency>
            <groupId>io.github.poshjosh</groupId>
            <artifactId>rate-limiter-javaee</artifactId>
            <version>0.7.0</version> 
        </dependency>

Usage

1. Implement RateLimitProperties

public class RateLimitPropertiesImpl implements RateLimitProperties {

    // If not using annotations, return an empty list
    @Override 
    public List<String> getResourcePackages() {
        return Collections.singletonList("com.myapplicatioon.web.rest");
    }

    // If not using properties, return an empty map
    @Override 
    public Map<String, Rates> getRateLimitConfigs() {
        // Accept only 2 tasks per second
        return Collections.singletonMap("task_queue", Rates.of(Rate.ofSeconds(2)));
    }
}

2. Extend RateLimitingDynamicFeature

This way a rate limiter will be created an automatically applied based on rate limiter related properties and annotations.

@javax.ws.rs.ext.Provider
public class DynamicFeatureImpl extends RateLimitingDynamicFeature {

    @javax.inject.Inject 
    public DynamicFeatureImpl(RateLimitProperties properties) {
        super(properties);
    }
}

At this point, your application is ready to enjoy the benefits of rate limiting.

3. Annotate classes and/or methods.

@Path("/api")
class MyResource {

  // Only 25 calls per second for users in role GUEST
  @Rate(25)
  @RateCondition("web.request.user.role=GUEST")
  @GET
  @Path("/greet")
  @Produces("text/plain")
  String greet(String name) {
    return "Hello " + name;
  }
}

Fine-grained configuration of rate limiting

Configure rate limiting as described in the rate-limiter-web-core documentation.

When you configure rate limiting using properties, you could:

  • Rate limit a class from properties by using the class ID.

  • Rate limit a method from properties by using the method ID.

public class RateLimitPropertiesImpl implements RateLimitProperties {
  @Override
  public Map<String, Rates> getRateLimitConfigs() {
    
    Map<String, Rates> ratesMap = new HashMap<>();
    
    // Rate limit a class
    ratesMap.put(RateId.of(MyResource.class), Rates.of(Rate.ofMinutes(10)));
    
    // Rate limit a method
    ratesMap.put(RateId.of(MyResource.class.getMethod("greet", String.class)), Rates.of(Rate.ofMinutes(10)));
    
    return ratesMap;
  }
}

Expression Language

The expression language allows us to write expressive rate conditions, e.g:

@RateCondition("web.request.user.role=GUEST")

@RateCondition("jvm.memory.free<1GB")

format example description
LHS=RHS web.request.header=X-RateLimit-Limit true, when the X-RateLimit-Limit header exists
LHS={key=val} web.request.parameter={limited=true} true, when request parameter limited equals true
LHS=[AlB] web.request.user.role=[GUESTlRESTRICTED] true, when the user role is either GUEST or RESTRICTED
LHS=[A&B] web.request.user.role=[GUEST&RESTRICTED] true, when the user role is either GUEST and RESTRICTED
LHS={key=[AlB]} web.request.header={name=[val_0lval_1]} true, when either val_0 or val_1 is set a header
LHS={key=[A&B]} web.request.header={name=[val_0&val_1]} true, when both val_0 and val_1 are set as headers

Note: | represents OR, while & represents AND

A rich set of conditions may be expressed as detailed in the web specification.

Manually create and use a RateLimiter

Usually, you are provided with appropriate RateLimiters based on the annotations and properties you specify. However, you could manually create and use RateLimiters.

class MyResource {
    
    RateLimiter rateLimiter = RateLimiterFactory.of(MyResource.class, "smile");
    
    @Rate(id = "smile", permits = 2)
    String smile() {
        return ":)";
    }
}

This way you use the RateLimiter as you see fit.

Annotation Specifications

Please read the annotation specs. It is concise.

Enjoy! ๐Ÿ˜‰

rate-limiter-javaee's People

Contributors

poshjosh avatar

Watchers

 avatar  avatar

rate-limiter-javaee's Issues

Implement MatchType.REMOTE_ADDRESS for usage in @RateRequestIf

The annotation @RateRequestIf requires a MatchType enum. This enum is used to provision matchers and supports various match types. However support for MatchType.REMOTE_ADDRESS is yet to be implemented.

ContainerRequestContext does not provide access to the remote address. To access the remote address we need to use @javax.ws.rs.core.Context to inject a javax.servlet.http.HttpServletRequest and call its getRemoteAddr() method. However, the exact point where the remote address is needed is within a static context, which makes injection extra-ordinary.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.