Core concepts
Routing & controllers
Nokron handles routing through the use of controllers and actions, which are one of the primary advantages of using Nokron. All incoming HTTP requests are mapped to specific actions in controllres and their corresponding method.
What are Controllers?
Controllers are an essential part of the Model-View-Controller (MVC) architecture, where they act as the bridge between the model (data) and the view (presentation). In the context of web development, controllers are responsible for handling incoming requests, processing the data, and returning a response.
Nokron builds controllers around classes, similar to ASP.NET, where each method inside a controller class represents an action that is mapped to a specific route. These methods are called action methods or handler functions, and they define the logic to be executed when a request is received at a specific URL.
Defining a Controller
To define a controller in Nokron, you need to create a new class and decorate it with the @Controller
decorator. The decorator takes an argument that specifies the base route for all the actions defined inside the controller.
For example, the following code defines a CatController
class with a base route of /cats
:
import { Controller } from '@nokron/core';
@Controller('/cats')
export class CatController {
// Actions defined here...
}
All the actions methods inside the CatController
class will be accessible through URLs that begin with /cats
.
Defining an Action Method
To define an action method in Nokron, you need to decorate it with an HTTP method decorator, such as @HttpGet
, @HttpPost
, @HttpPut
, @HttpDelete
, etc. The decorator specifies the HTTP method for which the action method should handle requests and takes an argument that specifies the route for the action.
For example, the following code defines a getCats
method inside the CatController
class that handles HTTP GET requests to the /cats
route:
import { Controller, HttpGet, Ok } from '@nokron/core';
@Controller('/cats')
export class CatController {
@HttpGet('/')
public async getCats() {
return Ok([
{ name: 'Garfield', age: 40 },
{ name: 'Tom', age: 45 },
]);
}
}
In the above example, the getCats
method returns an Ok
response that contains an array of cat objects when the /cats
route is accessed using an HTTP GET request.
Sending the response
All action methods must return an instance of IActionResult
. The interface defines the contract that represents the result of the action method, which is used by Nokron to execute and generate the result that is returned with the HTTP response.
Now, we're not expecting you to ever create your own concrete implementation of IActionResult
and return that. Instead, we've provided a series of helper methods which can be used to return a desired result, such as Ok()
, Created()
, NotFound()
, and many more.
Some of the helper methods, such as Ok
and Created
, allows for an object value to be provided, so that the action method can return data as a response.
The example below shows how the called Ok
helper methods takes an array of cats, which will be returned as JSON in the response body.
import { Controller, HttpGet, Ok } from '@nokron/core';
@Controller('/cats')
export class CatController {
@HttpGet('/')
public async getCats() {
return Ok([
{ name: 'Garfield', age: 40 },
{ name: 'Tom', age: 45 },
]);
}
}
Advanced response handling
Some cases calls for more advanced control of the response, like setting cookies or custom response headers. This can be achieved by adding a parameter decorated with @Res
to the action function, like so:
@HttpPost('/refresh')
public async refreshSession(@Res() res: Response) {
// Do some business logic..
// Set refresh token in cookie
res.cookie('refreshToken', token, {
httpOnly: true,
secure: true,
sameSite: 'none',
expires: new Date(refreshToken.expiration),
});
return Ok();
}
In the example above, the response instance is attached to the res
parameter and can be altered before it is sent. In this case, a cookie is being set on the response with a token and some cookie settings. As soon as the Ok
method is called and returned, the modified response will used in the execution of the action to create the action result.
Routing
Nokron makes use of Express.js' routing system for handling incoming requests, as Nokron is built on top of Express.js.
Defining route paths
A route path is a string that specifies the URL pattern that the controller action should handle. In Nokron, you can define route paths using the same conventions as in Express.js.
As mentioned previsouly, all Action Methods will use the controller class root path as a prefix for their route path. For example, the following code defines a route path for the listCats
action method:
@Controller('/cats')
export class CatController {
@HttpGet('/list')
public async listCats() {
// Logic to handle GET /cats/list
}
}
The route path for the listCats
method is /cats/list
, which means that it handles GET requests to that url.
Route parameters
Route parameters are placeholders in the route path that capture values from the URL and pass them to the controller action as arguments. In Nokron, you can define route parameters using the same conventions as in Express.js.
For example, the following code defines a route parameter for the getCatById
action method:
@Controller('/cats')
export class CatController {
@HttpGet('/:id')
public async getCatById(@Param('id') id: string) {
// Logic to handle GET /cats/:id
}
}
In the above example, the :id
in the route path is a route parameter that captures the value from the URL and passes it to the getCatById
method as an argument.