glimit

Package Version Hex Docs test

A simple, framework-agnostic, in-memory rate limiter for Gleam. ๐Ÿ’ซ

โš ๏ธ This library is still in development, use at your own risk.

Features

Usage

A very minimalistic example of how to use glimit would be the following snippet:

import glimit

let limiter =
  glimit.new()
  |> glimit.per_second(2)
  |> glimit.identifier(fn(x) { x })
  |> glimit.on_limit_exceeded(fn(_) { "Stop!" })
  |> glimit.build

let func =
  fn(_) { "OK" }
  |> glimit.apply(limiter)

func("๐Ÿš€") // "OK"
func("๐Ÿ’ซ") // "OK"
func("๐Ÿ’ซ") // "OK"
func("๐Ÿ’ซ") // "Stop!"
func("๐Ÿš€") // "OK"
func("๐Ÿš€") // "Stop!"

A more practical example would be to use glimit to rate limit requests to a mist HTTP server:

import glimit


fn handle_request(req: Request(Connection)) -> Response(ResponseData) {
  let index =
    response.new(200)
    |> response.set_body(mist.Bytes(bytes_builder.new()))
  let not_found =
    response.new(404)
    |> response.set_body(mist.Bytes(bytes_builder.new()))

  case request.path_segments(req) {
    [] -> index
    _ -> not_found
  }
}

fn get_identifier(req: Request(Connection)) -> Result(String, String) {
  req.body
  |> get_client_info
  |> result.map(fn(client_info: ConnectionInfo) {
    client_info.ip_address |> string.inspect
  })
  |> result.unwrap("unknown IP address")
}

pub fn main() {
  let rate_limit_reached = fn(_req) -> {
    response.new(429)
    |> response.set_body(mist.Bytes(bytes_builder.new()))
  }

  let limiter =
    glimit.new()
    |> glimit.per_second(10)
    |> glimit.burst_limit(100)
    |> glimit.identifier(get_identifier)
    |> glimit.on_limit_exceeded(rate_limit_reached)
    |> glimit.build

  let assert Ok(_) =
    handle_request
    |> glimit.apply(limiter)
    |> mist.new
    |> mist.port(8080)
    |> mist.start_http

  process.sleep_forever()
}

Constraints

While the in-memory rate limiter is simple and easy to use, it does have an important constraint: it is scoped to the BEAM VM cluster it runs in. This means that if your application is running across multiple BEAM VM clusters, the rate limiter will not be shared between them.

There are plans to add support for a centralized data store using Redis in the future.

Documentation

Further documentation can be found at https://hexdocs.pm/glimit/glimit.html.

Contributing

Contributions like PRโ€™s, bug reports or suggestions are more than welcome! โ™ฅ๏ธ

โœจ Search Document