Skip to content

REST API Overview

The Banyan Platform automatically generates RESTful HTTP endpoints for all service commands and queries without any additional code or configuration.

Every command and query contract automatically creates a REST endpoint with proper HTTP semantics:

  • Commands generate POST endpoints (state-changing operations)
  • Queries generate GET endpoints (read-only operations)
  • URLs follow RESTful resource patterns
  • Authentication handled automatically via JWT tokens
  • Validation enforced from contract definitions

No manual routing, controller classes, or HTTP-specific code needed. The API Gateway:

  1. Discovers all service contracts via service discovery
  2. Generates appropriate HTTP endpoints automatically
  3. Translates HTTP requests to message bus commands/queries
  4. Returns responses in standard JSON format
  5. Handles errors with proper HTTP status codes

Commands represent state-changing operations and always use POST:

@Command({
description: 'Create a new user account',
permissions: ['users:create']
})
export class CreateUserCommand {
email!: string;
firstName!: string;
lastName?: string;
}

Generates:

POST /api/users
Content-Type: application/json
Authorization: Bearer <token>
{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
}

Queries represent read operations and use GET with URL parameters:

@Query({
description: 'Retrieve user by ID',
permissions: ['users:read']
})
export class GetUserQuery {
userId!: string;
}

Generates:

GET /api/users/:userId
Authorization: Bearer <token>

Or with query parameters:

GET /api/users?userId=user-123
Authorization: Bearer <token>

All API endpoints are served from the API Gateway:

Development: http://localhost:3003
Production: https://api.your-domain.com

All endpoints are prefixed with /api/:

  • POST /api/users - Create user
  • GET /api/users/:userId - Get user
  • PUT /api/users/:userId - Update user

The platform maps commands and queries to appropriate HTTP methods:

OperationHTTP MethodIdempotentCacheable
CreatePOSTNoNo
ReadGETYesYes
UpdatePUTYesNo
DeleteDELETEYesNo
ListGETYesYes

All requests use JSON:

POST /api/users
Content-Type: application/json
Authorization: Bearer <token>
{
"email": "user@example.com",
"firstName": "John"
}

All responses return JSON:

{
"userId": "user-123",
"email": "user@example.com",
"firstName": "John",
"createdAt": "2025-11-15T12:00:00Z"
}

Errors follow a consistent structure:

{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": {
"email": "Invalid email format"
}
}

All requests require authentication via JWT tokens (except public endpoints):

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

See Authentication Reference for details.

For local development only:

X-Dev-User-Id: dev-user-123
X-Dev-Permissions: users:create,users:read

WARNING: Development mode bypasses all authentication. Never use in production.

Content-Type: application/json # For POST/PUT requests
Authorization: Bearer <token> # Production authentication
X-Correlation-Id: custom-trace-id # For distributed tracing
Accept: application/json # Response format preference

The API Gateway includes helpful headers in responses:

X-Correlation-Id: abc-123-def # Request correlation ID
X-Request-Id: req-456-ghi # Unique request ID
Content-Type: application/json

CORS is automatically configured for browser clients:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, X-Dev-User-Id, X-Dev-Permissions
Access-Control-Max-Age: 86400

When rate limiting is configured, responses include headers:

X-RateLimit-Limit: 1000 # Requests allowed per window
X-RateLimit-Remaining: 999 # Remaining requests
X-RateLimit-Reset: 1700056800 # Window reset timestamp