Backend Development 17 min read

How to Build a High‑Performance API Gateway with OpenResty and Lua

This article explains the role of API gateways, compares access‑layer and application‑layer designs, and provides a step‑by‑step guide to constructing a dynamic, high‑throughput gateway using OpenResty’s Nginx‑Lua architecture, plugin system, and runtime configuration features.

macrozheng
macrozheng
macrozheng
How to Build a High‑Performance API Gateway with OpenResty and Lua

Preface

After sharing several gateway‑related posts, we noticed strong interest, so this article introduces how to use OpenResty to build a gateway system, summarizing key OpenResty concepts and providing a comprehensive overview of its high‑performance web platform.

Gateway Role

A gateway is the entry point for all requests, handling security, rate limiting, circuit breaking, monitoring, logging, risk control, and authentication. Two types exist:

Access‑layer gateway: routing, WAF, rate limiting, logging, caching, and forwarding requests to application‑layer gateways.

Application‑layer gateway: after routing, it performs authentication, timeout handling, retries, and circuit breaking for microservices written in various languages.

The access layer bears the entire traffic load, making its design critical for overall system capacity.

Access‑Layer Gateway Architecture and Implementation

The core function is routing requests to the appropriate backend cluster based on routing rules . Required capabilities include:

Routing: forward requests to upstream clusters according to host, URL, etc.

Plugin‑based routing strategy: authentication, rate limiting, security checks, etc., are implemented as independent, dynamically configurable plugins that can be added or removed without restarting.

Dynamic backend cluster changes: support adding or removing servers on the fly.

Monitoring and statistics: request volume, error rates, and logging for alerting and analysis.

Understanding OpenResty is essential to achieve these features.

Technical Selection

While Nginx offers high performance with an epoll model, it lacks runtime APIs for dynamic configuration, requiring configuration reloads. OpenResty extends Nginx with Lua, providing a programmable, dynamically configurable platform. Its key advantages are extensive documentation, test cases, and built‑in non‑blocking coroutine support.

OpenResty® is a high‑performance web platform based on Nginx and Lua, integrating many Lua libraries and third‑party modules to handle massive concurrency and provide dynamic web services.

OpenResty = Nginx + Lua, allowing runtime control of routing, upstreams, SSL, requests, and responses without restarting.

OpenResty Principle Analysis

Working Principle

OpenResty inherits Nginx’s architecture: a master process manages worker processes, which handle client requests using an asynchronous, non‑blocking event‑driven model (epoll). Each worker runs a single‑threaded Lua VM, and Lua coroutines cooperate with Nginx’s event loop to achieve massive concurrency.

When a Lua script performs I/O (e.g., MySQL or Redis queries), it yields, registers a callback with Nginx, and the worker can process other requests. Once the I/O completes, Nginx resumes the coroutine, ensuring non‑blocking behavior.

<code>local res, err = query_mysql(sql)
local value, err = query_redis(key)</code>

The

sync

vs

async

and

blocking

vs

non‑blocking

concepts are explained in the article.

OpenResty Request Lifecycle

Nginx processes each request through 11 phases; OpenResty provides corresponding

*_by_lua

directives such as

set_by_lua

,

rewrite_by_lua

,

access_by_lua

,

content_by_lua

,

header_filter_by_lua

,

body_filter_by_lua

, and

log_by_lua

. This modularity enables separating concerns—for example, decrypting requests in the access phase and encrypting responses in the body‑filter phase without touching core business logic.

<code># Plain protocol version
location /request {
    content_by_lua '...';   # handle request
}

# Encrypted protocol version
location /request {
    access_by_lua '...';    # decrypt request
    content_by_lua '...';   # process request
    body_filter_by_lua '...'; # encrypt response
}</code>

Worker‑Shared Data: shared_dict

OpenResty provides shared_dict , an efficient in‑memory key‑value store with atomic Lua APIs, allowing data sharing across independent worker processes.

Routing Strategy Pluginization

Routing policies are defined as

{url, action, cluster}

entries stored in a database. At startup, workers fetch these rules, compile them into Lua functions, and cache them in

shared_dict

. When rules change, the control plane notifies OpenResty to reload them.

Dynamic Backend Cluster Configuration

Static

upstream

blocks require manual edits and reloads. OpenResty’s

dyups

module offers an API to add, delete, or modify upstreams at runtime, eliminating reload overhead.

<code># Dynamic upstream API
server {
    listen 127.0.0.1:81;
    location / { dyups_interface; }
}

# Add upstream
curl -d "server 10.53.10.191;" 127.0.0.1:81/upstream/user_backend

# Delete upstream
curl -i -X DELETE 127.0.0.1:81/upstream/user_backend</code>

Final Architecture Diagram

The design achieves a configurable, dynamic gateway capable of handling massive traffic with low latency.

Conclusion

Choosing OpenResty for a gateway offers high performance, proven adoption by major companies, and a rich ecosystem for dynamic routing, pluginization, and runtime configuration. While the article covers core concepts, OpenResty provides many more features for deeper exploration.

backend developmentAPI gatewaynginxLuaOpenResty
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.