Skip to content

Resource-scoped limits

Use one strategy and backend while assigning different capacities to named application operations.

Prerequisites

  • Go 1.24 or newer
  • no external service

Run

go run ./examples/resource_scoped
examples/resource_scoped/main.go
// Package main demonstrates using resource-scoped rate limiting with per-resource policies.
package main

import (
    "context"
    "fmt"
    "time"

    "github.com/AliRizaAynaci/gorl/v2"
    "github.com/AliRizaAynaci/gorl/v2/core"
)

func main() {
    limiter, err := gorl.NewResourceLimiter(core.ResourceConfig{
        Strategy: core.SlidingWindow,
        DefaultPolicy: core.ResourcePolicy{
            Limit:  100,
            Window: time.Minute,
        },
        Resources: map[string]core.ResourcePolicy{
            "login": {
                Limit:  5,
                Window: time.Minute,
            },
            "search": {
                Limit:  20,
                Window: time.Second,
            },
        },
    })
    if err != nil {
        panic(err)
    }
    defer limiter.Close()

    ctx := context.Background()

    for i := 1; i <= 6; i++ {
        res, err := limiter.AllowResource(ctx, "login", "user-123")
        fmt.Printf("login req %d: allowed=%v remaining=%d err=%v\n", i, res.Allowed, res.Remaining, err)
    }

    for i := 1; i <= 3; i++ {
        res, err := limiter.AllowResource(ctx, "search", "user-123")
        fmt.Printf("search req %d: allowed=%v remaining=%d err=%v\n", i, res.Allowed, res.Remaining, err)
    }

    res, err := limiter.AllowResource(ctx, "unlisted", "user-123")
    fmt.Printf("default resource: allowed=%v remaining=%d err=%v\n", res.Allowed, res.Remaining, err)
}

Expected behavior

The login resource allows five requests per minute and denies the sixth for user-123. The search resource has its own, larger policy and separate state. Any resource not listed in Resources uses DefaultPolicy.

Production cautions

Resource names are application contracts. Prefer stable identifiers such as route patterns or operation names, not raw URLs containing IDs. Review the fallback policy: a typo in a resource name selects the default rather than returning an unknown-resource error.