Controllers
In OzeanJs, a Controller’s main responsibility is to receive incoming HTTP requests from the client, process them, and send back an HTTP response. A Controller acts as the “front line” that connects the outside world to your application’s business logic.
The structure of a Controller is designed to be clear and modular, using Decorators to define routing and handle data.
Creating a Controller
Section titled “Creating a Controller”We create a Controller by creating a TypeScript class and attaching the @Controller()
decorator.
@Controller('/prefix')
: This decorator defines a “base path” or URL prefix for all routes defined within this class. For example, if you define@Controller('/users')
, all routes in this controller will start with/users
.
Defining Route Handlers
Section titled “Defining Route Handlers”Inside a Controller, we create various methods that act as “Route Handlers”. They are bound to specific HTTP Methods and sub-paths using Decorators:
@Get('/path')
: For handlingGET
requests.@Post('/path')
: For handlingPOST
requests.@Put('/path')
: For handlingPUT
requests.@Delete('/path')
: For handlingDELETE
requests.@Patch('/path')
: For handlingPATCH
requests.
Accessing Request Data (Parameter Decorators)
Section titled “Accessing Request Data (Parameter Decorators)”OzeanJs provides Parameter Decorators that help you easily extract data from various parts of the request into your handler methods:
@Param('key')
: Extracts a value from the URL parameter (e.g., from the route/users/:id
).@Query('key')
: Extracts a value from the URL’s query string (e.g., from/users?role=admin
).@Body()
: Extracts the entire request body (typically used withPOST
,PUT
,PATCH
).
Usage Example: UsersController
Section titled “Usage Example: UsersController”Here is a complete example of a UsersController
that demonstrates all these concepts working together.
import { Injectable } from 'ozean';
// Assume we have a UsersService that handles user-related logic@Injectable()export class UsersService { private users = [{ id: 1, name: 'John Doe' }];
findAll() { return this.users; }
findOne(id: number) { return this.users.find((user) => user.id === id); }
create(userData: { name: string }) { const newUser = { id: this.users.length + 1, ...userData }; this.users.push(newUser); return newUser; }}
// src/users/users.controller.tsimport { Controller, Get, Post, Param, Body } from 'ozean';import { UsersService } from './users.service';
@Controller('/users') // All routes in here will be prefixed with /usersexport class UsersController { constructor(private readonly usersService: UsersService) {}
// Handles GET requests to /users @Get() getAllUsers() { return this.usersService.findAll(); }
// Handles GET requests to /users/:id (e.g., /users/1) @Get('/:id') getUserById(@Param('id') id: string) { const user = this.usersService.findOne(parseInt(id, 10)); if (!user) { // You can return a Response object directly to set a custom status code return new Response('User not found', { status: 404 }); } return user; // Will be automatically converted to a JSON response }
// Handles POST requests to /users @Post() createUser(@Body() userData: { name: string }) { return this.usersService.create(userData); }}
Registering the Controller in a Module
Section titled “Registering the Controller in a Module”Finally, don’t forget to register the UsersController
you created in the controllers
array of the relevant module (e.g., UsersModule
) so that OzeanJs recognizes it and creates the routes automatically.
import { Module } from 'ozean';import { UsersController } from './users.controller';import { UsersService } from './users.service';
@Module({ controllers: [UsersController], providers: [UsersService],})export class UsersModule {}
With this structure, the logic for handling HTTP requests is clearly separated within the Controller, making your code cleaner and easier to maintain.