Skip to main content
The HTTP module (RestApiModule) allows you to expose iii functions as HTTP/REST endpoints, making them accessible via standard HTTP requests.

Configuration

Configure the HTTP module in config.yaml:
config.yaml
modules:
  - class: modules::api::RestApiModule
    config:
      port: 3111
      host: 127.0.0.1
      default_timeout: 30000  # milliseconds
      concurrency_request_limit: 1024
      cors:
        allowed_origins:
          - '*'  # Allow all origins
        allowed_methods:
          - GET
          - POST
          - PUT
          - DELETE
          - OPTIONS

Configuration Options

port
number
default:"3111"
HTTP server port
host
string
default:"127.0.0.1"
Bind address for the HTTP server
default_timeout
number
default:"30000"
Request timeout in milliseconds
concurrency_request_limit
number
default:"1024"
Maximum concurrent HTTP requests
cors
object
CORS configuration for cross-origin requests
  • allowed_origins: Array of allowed origins (use '*' for all)
  • allowed_methods: Array of allowed HTTP methods

Creating HTTP Endpoints

Define HTTP triggers in your function configuration:
index.ts
export default iii({
  triggers: {
    'get-user': {
      type: 'http',
      config: {
        path: '/users/:id',
        method: 'GET',
      },
    },
    'create-user': {
      type: 'http',
      config: {
        path: '/users',
        method: 'POST',
      },
    },
  },
});

export async function getUser(input: any) {
  const userId = input.path_params.id;
  return { id: userId, name: 'John Doe' };
}

export async function createUser(input: any) {
  const { name, email } = input.body;
  return { id: 123, name, email };
}

Request Input Format

HTTP triggers receive input in this format:
{
  method: string;          // HTTP method: GET, POST, etc.
  path: string;            // Request path
  path_params: object;     // URL path parameters
  query_params: object;    // Query string parameters
  headers: object;         // Request headers
  body: any;               // Parsed request body (JSON)
}

Example: Path Parameters

// Trigger: GET /users/:id
export async function getUser(input: any) {
  const userId = input.path_params.id;  // Access :id parameter
  return await db.users.get(userId);
}

Example: Query Parameters

// Trigger: GET /search?q=rust&limit=10
export async function search(input: any) {
  const { q, limit } = input.query_params;
  return await searchDatabase(q, parseInt(limit || '10'));
}

Example: Request Body

// Trigger: POST /users
export async function createUser(input: any) {
  const { name, email } = input.body;
  return await db.users.create({ name, email });
}

HTTP Methods

Supported HTTP methods:
  • GET - Retrieve resources
  • POST - Create resources
  • PUT - Update/replace resources
  • DELETE - Delete resources
  • PATCH - Partial updates
  • OPTIONS - CORS preflight

Response Handling

Success Response

Return data directly from your function:
export async function getUser(input: any) {
  return {
    id: 123,
    name: 'John Doe',
    email: '[email protected]',
  };
}
HTTP response:
{
  "id": 123,
  "name": "John Doe",
  "email": "[email protected]"
}

Error Response

Throw errors to return error responses:
export async function getUser(input: any) {
  const user = await db.users.get(input.path_params.id);
  if (!user) {
    throw new Error('User not found');
  }
  return user;
}

Path Patterns

The HTTP module supports dynamic path parameters:
triggers:
  my-endpoint:
    type: http
    config:
      path: /api/users/:userId/posts/:postId
      method: GET
Access parameters:
const { userId, postId } = input.path_params;

CORS Configuration

Allow All Origins (Development)

cors:
  allowed_origins:
    - '*'
  allowed_methods:
    - GET
    - POST

Specific Origins (Production)

cors:
  allowed_origins:
    - https://app.example.com
    - https://admin.example.com
  allowed_methods:
    - GET
    - POST
    - PUT
    - DELETE

Middleware & Timeout

The HTTP module applies these layers automatically:
  1. CORS - Cross-origin resource sharing
  2. Timeout - Request timeout (configurable)
  3. Concurrency Limit - Max concurrent requests

Example: Complete API

index.ts
export default iii({
  triggers: {
    'list-todos': {
      type: 'http',
      config: { path: '/todos', method: 'GET' },
    },
    'create-todo': {
      type: 'http',
      config: { path: '/todos', method: 'POST' },
    },
    'get-todo': {
      type: 'http',
      config: { path: '/todos/:id', method: 'GET' },
    },
    'delete-todo': {
      type: 'http',
      config: { path: '/todos/:id', method: 'DELETE' },
    },
  },
});

export async function listTodos() {
  return await state.list({ scope: 'todos' });
}

export async function createTodo(input: any) {
  const { title, completed } = input.body;
  const id = Date.now().toString();
  await state.set({
    scope: 'todos',
    key: id,
    value: { title, completed: completed || false },
  });
  return { id, title, completed };
}

export async function getTodo(input: any) {
  const todo = await state.get({
    scope: 'todos',
    key: input.path_params.id,
  });
  if (!todo) throw new Error('Todo not found');
  return todo;
}

export async function deleteTodo(input: any) {
  await state.delete({
    scope: 'todos',
    key: input.path_params.id,
  });
  return { success: true };
}

Testing Endpoints

# List todos
curl http://localhost:3111/todos

# Create todo
curl -X POST http://localhost:3111/todos \
  -H "Content-Type: application/json" \
  -d '{"title":"Buy milk","completed":false}'

# Get specific todo
curl http://localhost:3111/todos/123

# Delete todo
curl -X DELETE http://localhost:3111/todos/123

Source Code Reference

  • Module: src/modules/rest_api/api_core.rs:69
  • Router: src/modules/rest_api/hot_router.rs
  • Trigger registration: src/modules/rest_api/api_core.rs:100

Build docs developers (and LLMs) love