Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

LuaadvancedbackendAI generated

Nginx OpenResty API Gateway with Rate Limiting and Auth

Build an API gateway with OpenResty, a version of Nginx that runs Lua code inside the web server. Every request passes through your Lua code before reaching the backend services: it checks the JWT token (signature, expiry and scopes) with lua-resty-jwt, enforces a request limit per client using memory shared between all Nginx workers, and then forwards the request to the right backend. Because the code runs inside Nginx, the gateway adds almost no delay, even under heavy load. You'll learn the Nginx request phases, Lua in OpenResty, JWT validation, rate limiting algorithms with shared dictionaries, proxying and upstreams, and load testing and tuning.

Estimate
~14h
Steps
7
Completed by
0
Proposed by
codeseed.app

OpenResty · lua-resty-jwt · Nginx

Project roadmap

  1. 01

    Set up OpenResty

    ~2h

    Run OpenResty in Docker (the openresty/openresty image) with your nginx.conf mounted. Add two small backend services (for example tiny Python or Node.js apps returning JSON) in the same Docker Compose file. Declare lua_shared_dict zones for rate limiting, and a location that runs a Lua block returning Hello. Done when: docker compose up starts everything, and the Lua location answers.

  2. 02

    Validate JWTs

    ~2.5h

    Install lua-resty-jwt with opm or LuaRocks. In the access_by_lua_block phase, read the Authorization: Bearer header, verify the signature (HS256 with a secret from an environment variable, or RS256 with a public key), and check the expiry, issuer and audience. Return 401 with a JSON error for missing or invalid tokens, and pass the user id and scopes to the backend as headers. Write a small script to generate test tokens. Done when: valid tokens pass, and expired or tampered ones get 401.

  3. 03

    Limit requests per client

    ~2.5h

    Implement rate limiting keyed by the token's client id (or the IP for public routes) using a shared dictionary, with a sliding window or token bucket, or use the lua-resty-limit-traffic library. Use atomic operations such as incr so that all workers share the counts correctly. Return 429 with Retry-After and X-RateLimit headers. Make limits configurable per route. Done when: going over the limit returns 429 no matter which worker handles the request.

  4. 04

    Route to backends

    ~1.5h

    Define upstream blocks for the backends and locations that proxy_pass by path (/users/ to one service, /orders/ to the other), with timeouts, and require specific scopes per route (for example orders:read). Remove the Authorization header before forwarding when backends don't need it. Return a JSON 502 or 504 when a backend fails. Done when: each path reaches the right backend, and missing scopes get 403.

  5. 05

    Add logging and metrics

    ~1.5h

    In the log_by_lua phase, write a JSON access log line with the client id, route, status, decision (allowed, unauthorized, rate limited) and latency, never the token. Count requests by route and decision in a shared dictionary, and expose them on an internal /metrics endpoint that only accepts local requests. Done when: the logs and metrics show every decision.

  6. 06

    Load test and tune

    ~2h

    Load test the gateway on your own machine with wrk or k6, with valid tokens, and compare the latency with calling the backend directly. Try different worker counts and shared dictionary sizes, and cache verified tokens for a short time to avoid repeating signature checks. Record the results in README.md. Done when: README.md shows the throughput and the latency added by the gateway before and after tuning.

  7. 07

    Test it

    ~2h

    Write tests with Test::Nginx (the OpenResty test framework) or a script that runs requests against the Docker setup: valid, expired and tampered tokens, missing scopes, rate limits, routing, and backend failures. Done when: every test case passes against the running gateway.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~14h · 7 steps

Tech stack

OpenRestylua-resty-jwtNginx