Skip to main content

Controllers

A controller is a class that handles HTTP requests and responses. It is responsible for processing incoming requests, executing business logic, and returning appropriate responses. Controllers are typically associated with specific routes or endpoints in your application.

Your first controller​

Creating a controller is simple. You can create a new class and decorate it with the @Controller decorator. This decorator takes a string parameter that defines the base route for the controller.

user-controller.ts
import { Controller } from '@axisparkjs/http';

@Controller('/users')
export class UserController {
...
}

This controller will handle requests to the /users route. You can define methods within the controller to handle specific HTTP methods (GET, POST, PUT, DELETE, etc.) and routes.

If versioning is enabled, controller decorator allows to define 1 or more versions for the controller. For example, @Controller({ path: 'users', version: '1' }). See more info in the Versioning section.

Routing​

Once you have defined your controller, you can define routes for the methods within the controller. You can use decorators (@Get, @Post, @Put, @Patch, @Delete, @Options and @Head) to define routes for specific HTTP methods. Here's an example of a controller with routes for different HTTP methods.

todo-controller.ts
import { Body, Controller, Delete, Get, NotFoundError, Path, Post, Put } from '@axisparkjs/http';
import { TodoService } from './service';
import { NotEmpty, ParseInt, Pipe } from '@axisparkjs/engine';

@Controller('todos')
export class TodoController {
constructor(private readonly todoService: TodoService) {}

@Get()
getTodos() {...}

@Get(':index')
getTodoByIndex(@Path('index') index: number) {...}

@Post()
addTodo(@Body() todo: { task: string }) {...}

@Put(':index')
updateTodo(@Path('index') index: string, @Body() updatedTodo: { task: string }) {...}

@Delete(':index')
removeTodo(@Path('index') index: string) {...}
}

This controller will generate the following routes:

  • GET /todos - Get all todos
  • GET /todos/:index - Get a specific todo by index
  • POST /todos - Add a new todo
  • PUT /todos/:index - Update a specific todo by index
  • DELETE /todos/:index - Remove a specific todo by index

As well as the @Controller decorator, the route decorators also accept an object with a version property to define the version of the route. For example, @Get({ path: ':index', version: '1' }). See more info in the Versioning section.

Host-based routing​

You can restrict a controller to a hostname with the host option. The controller's routes are considered only when the request's Host header matches. Host matching ignores letter case and ports. Omitting host or setting it to '*' matches every host.

admin-controller.ts
@Controller({ host: 'admin.example.com', path: 'users' })
export class AdminUsersController {
@Get()
index() {
return { surface: 'admin' };
}
}

You can register the same path for another host:

api-controller.ts
@Controller({ host: 'api.example.com', path: 'users' })
export class ApiUsersController {
@Get()
index() {
return { surface: 'api' };
}
}

Host patterns also accept * or a named label such as :tenant:

@Controller({ host: '*.example.com', path: 'users' })
export class SubdomainUsersController {}

@Controller({ host: ':tenant.example.net', path: 'users' })
export class TenantUsersController {}

Each wildcard or named label matches one subdomain label. If more than one host pattern matches, the most specific pattern is selected. Routes without a host option remain unrestricted and can serve as a fallback.