Keystone Gateway Documentation

Simple, interface-focused documentation.

Getting Started

Philosophy

Keystone Gateway is a general-purpose HTTP routing primitive with embedded Lua scripting.

Core principle: The gateway is dumb. Tenants are smart.

The gateway provides primitives (HTTP routing, Lua execution). You compose them into solutions.

Configuration

Lua API

Examples

Key Concepts

Stateless Design

  • No health checking (delegated to load balancers)
  • No backend state tracking
  • Horizontal scaling without coordination

Lua State Pooling

  • Pre-allocated Lua VMs for thread safety
  • Configurable pool size (default: 10)
  • Metrics at /debug/lua-pool

LuaRocks Support

  • Compatible with pure Lua modules
  • Avoid lua-resty-* modules (require nginx ngx.* API)
  • Check LuaRocks.org before implementing

Path-Based Routing

  • Multi-tenant with path prefixes
  • Chi router patterns (/users/{id})
  • Domain routing via external reverse proxy

Architecture

HTTP Request
    ↓
Chi Router (path-based)
    ↓
Middleware Chain (optional Lua functions)
    ↓
Handler (Lua function OR backend proxy)
    ↓
HTTP Response

Debug Endpoints

  • /health - Liveness check (returns 200 OK)
  • /debug/lua-pool - State pool metrics (hits, misses, wait time)

Performance Tips

  1. Disable logging for highest throughput:
    middleware:
      logging: false
    
  2. Increase state pool for high concurrency:
    lua_routing:
      state_pool_size: 60
    
  3. Use LuaRocks libraries (e.g., lua-cjson) instead of pure Lua implementations

  4. Enable compression for bandwidth savings:
    compression:
      enabled: true
      level: 1  # Fast compression
    

Common Patterns

Handler Structure

function handler_name(req)
    -- Access request: req.method, req.path, req.headers, req.params, req.body
    -- Process logic
    return {
        status = 200,
        body = "response",
        headers = {["Content-Type"] = "text/plain"}
    }
end

Middleware Structure

function middleware_name(req, next)
    -- Validate/check
    if not valid then
        return {status = 401, body = "Unauthorized"}
    end

    -- Continue chain
    next()
    return nil
end

Error Handling

local resp, err = http_get(url)

if err then
    log("Error: " .. err)
    return {status = 502, body = "Service unavailable"}
end

if resp.status ~= 200 then
    return {status = resp.status, body = resp.body}
end

Further Reading


Remember: Always check LuaRocks.org before implementing features. Use pure Lua modules, avoid lua-resty-* modules.