Ratelimiter4s : A functional rate limiting library

ayush mittal
Jul 27 · 3 min read

Rate limiting is a common feature that come across these days. With the upsurge of cloud based api’s , rate limiting has become a de-facto standard of protecting the resources and controlling requests.

What is rate limiting ?

Rate limiting is used to control the amount of incoming and outgoing traffic to or from a network. For example, let’s say you are using a particular service’s API that is configured to allow 100 requests/minute. If the number of requests you make exceeds that limit, then an error will be triggered. The reasoning behind implementing rate limits is to allow for a better flow of data and to increase security by mitigating attacks such as DDoS.

There are some pretty good libraries out there that provide some kind of support to add rate limiting capabilities to your API’s. Resilience4j is one such library which in inspired from Netflix Hystrix and supports Java8.

I was inspired from Resilience4j to write a rate limiting api in Scala. However the motive was not to built the rate limiting capabilities from scratch. That would be reinventing the wheel. The motivation was to support Scala based effect while providing rate limiting capabilities.

ratelimter4s is lightweight library i came up with. It is designed for Scala and provides wrappers to enhance any Function with rate limiting capabilities. The wrappers are available in 3 flavours

  • FRateLimiter : Rate limited method returns a Either type
  • CatsRateLimiter : Rate limited method returns a EitherT type
  • ZIORateLimiter : Rate limited method returns a Task type

Lets check out FRateLimiter in action :

Consider a public service which takes a character name and returns an Artist.

Rules dictate that calling rate for getArtist to be not higher than 3 requests/second.We can define a RateLimiter config defined like this

The details of the limiter config are described in detail here

We can use this config and add rate-limiting capability to our service. We would need to import the FRateLimiter class that provides the method limit.

Lets checkout a rate limited service in action

And that is it! We have achieved the objective of limiting the requests to 3/second.

Pure and Impure

A pure scala function is side-effect free, plus the result does not depend on anything other than its inputs. Example :

def greeter(guest: String) : String = s"Hello $guest"

FunctionNLimiter provides a pure apply for every rate-limited function. The return type of pure is Either[RequestNotPermitted,A].

Decorating greeter with a rate limiter

We can call pure on the rate limited method.

Any exceptions thrown by the original greeter method are unhandled. So any instances of Left can only have a RequestNotPermitted type inside.

However many useful methods that we would like to rate limit interact with outside world, mutate state and would not qualify as pure functions. Such a rate limited method could throw exceptions which are caused by the actual business logic.

Consider the following example as a tweak to the original greeter.

Decorating the impure greeter with a rate limiter would remain the same.

We should call an apply on the rate limited method instead of pure. This means that we are also expecting greeterto fail for reasons other than rate limitations.

The Left is of Throwable type in this case which is self-explanatory.

ratelimiter4s also has support for creating cats-io and zio effect types which are enhancements on the top of the basic scala Either effect type. Detailed documentation about its usage can be read on the github site.

I would be more than happy to receive feedback on the library and what other features can be supported.

Happy coding!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade