Arcwayv0.3.0

API Features

CORS, rate limiting, and health checks

CORS

Auto-Behavior

ModeDefault
DevelopmentPermissive (all origins allowed)
ProductionDisabled (no CORS headers)

Manual Configuration

CORS is configured under the server section:

// arcway.config.js
export default {
  server: {
    cors: {
      origin: ['https://app.example.com'],
      methods: ['GET', 'POST', 'PUT', 'DELETE'],
      allowedHeaders: ['Content-Type', 'Authorization'],
      credentials: true,
      maxAge: 86400,
    },
    // Or: cors: true (permissive), cors: false (disabled)
  },
};

OPTIONS preflight requests are handled automatically.

Per-Route CORS

Use corsMiddleware from arcway/middlewares for per-prefix CORS settings:

// api/external/_middleware.js
import { corsMiddleware } from 'arcway/middlewares';

export default {
  handler: corsMiddleware({
    origin: ['https://partner.example.com'],
    credentials: true,
  }),
};

Rate Limiting

Available as middleware. Import createRateLimitMiddleware and a store from arcway:

// api/_middleware.js
import { createRateLimitMiddleware, MemoryRateLimitStore } from 'arcway';

const store = new MemoryRateLimitStore();

export default {
  handler: createRateLimitMiddleware(
    {
      max: 100,          // Max requests per window
      windowMs: 60_000,  // Window size (1 minute)
      keyFn: (req) => req.headers['x-forwarded-for'] || req.ip || 'unknown',
    },
    store,
  ),
};

The keyFn receives ctx.req (the same request object available in handlers), so you can use any request property — req.ip, req.headers, req.session, etc. — to compute a rate-limit key.

MemoryRateLimitStore is for single-process deployments. For distributed/multi-replica deployments, use RedisRateLimitStore:

// api/_middleware.js
import { createRateLimitMiddleware, RedisRateLimitStore } from 'arcway';
import Redis from 'ioredis';

const redis = new Redis(process.env.REDIS_URL);
const store = new RedisRateLimitStore(redis);

export default {
  handler: createRateLimitMiddleware(
    {
      max: 100,
      windowMs: 60_000,
    },
    store,
  ),
};

Returns 429 Too Many Requests with Retry-After and X-RateLimit-* headers when limit is exceeded.


Health Checks

GET /_system/health is automatically available.

Response (healthy):

{
  "status": "ok",
  "components": {
    "database": { "status": "ok", "responseMs": 3 },
    "redis_queue": { "status": "ok", "responseMs": 1 }
  }
}

Response (degraded): Returns 503 with component-level status.

On this page