Controller
Controller is a group of similar functionalities placed in a single class, for example UserController contains functionalities to manage User. Plumier controller is a plain ES6 class contains several methods that will handle http request. Further it provided convention to automatically generate route based on its name, methods name and parameters name.
Controller Naming#
Plumier doesn't strictly limit the controller name, except it must end with Controller word. This is useful when you have non controller class inside controller/ directory. Controller naming best practice is using plural word, such as AnimalsController, UsersController
Registration#
By default controller registered automatically by traversed through all files ends with controller recursively (./**/*controller.+(ts|js)). For example user-controller.ts or user_controller.ts.
Its also possible to register controller in specific place using ControllerFacility using relative/absolute or glob path.
But keep in mind that when using ControllerFacility the default registration behavior is overridden.
Parameter Binding#
Parameter binding is a Plumier feature to automatically bound request part (context/query/body) into action parameters. Plumier provided 3 kind of parameter binding: Decorator Binding, Name Binding, Model Binding.
- Decorator binding: Bind specific koa context into action parameter by using
@binddecorator. - Name binding: Bind query or request body part into action parameter based on parameter name.
- Model binding: Bind request body into parameter which is of type custom class and doesn't match above criteria (decorator binding, name binding)
Decorator Binding#
Bind action parameter using @bind decorator like example below
Some binding decorator accepts string parameter to access its child
Above code is the same as accessing ctx.request.body.
Allowed path example:
- Using dot to access child property
request.ipetc - Using array notation
request.body[0]
There are several built in binding decorator provided
| Decorator | Description |
|---|---|
@bind.ctx() | Bind request context into parameter |
@bind.request() | Bind request into parameter |
@bind.body() | Bind request body into parameter |
@bind.query() | Bind request query into parameter |
@bind.header() | Bind request header into parameter |
@bind.user() | Bind JWT claim (current user) into parameter |
@bind.file() | Bind file into parameter. See here on detail how to use file binding |
Name Binding#
Name binding is when action parameter automatically assigned with query parameter or part of body request based on its name. For example:
type and page parameter above automatically assigned with canine and 1.
username and password will automatically assigned with part of request body admin and super secret pwd.
More complex example:
Example above showing that type parameter assigned with the query string canine and the request body spread into 3 parameters name, birthDate and owner.
Model Binding#
Model binding is the default behavior of parameter binding. Plumier by default will assigned request body to any parameter that has custom class type and doesn't match any binding criteria (Name Binding/Decorator binding).
Request
Above code, the animal parameter in save action will automatically bound with request body.
File Binding#
Unlike File binding, File binding works like name binding and retrieve file(s) that already parsed into the parameter. Parameter type should be of type FormFile.
size: Size of the file (bytes)path: Temporary path of the uploaded filename: File name provided by clienttype: Mime type of the filemtime: The file timestamp
By default this feature is not enable, you need to enable this feature like below:
Than on the controller simply do something like below
Above code will handle multipart form below
For multiple file upload, method's parameter can be specified using array like below
Binding Behavior#
In order to properly bound the request, plumier use priority based on parameter binding kind above.
- Decorator binding is be the first priority
- Name binding is the second priority
- Model binding is the last
Its mean when an action parameter decorated with @bind decorator it will not further check for name binding nor model binding. If an action parameter doesn't decorated with @bind but its name match with a query parameter, it will not further check for model binding and so on.
Type Converter#
Plumier automatically convert values provided by parameter binding match with parameter data type. If provided value doesn't match provided data type type http 422 error will be thrown.
Number Converter#
id parameter will automatically convert to number inside get action
Boolean Converter#
id parameter will automatically convert to boolean inside get action
Date Converter#
id parameter will automatically convert to Date inside get action
Object Converter#
Object converter only works for POST and PUT method
model parameter will automatically convert to Animal inside save action
Object converter also supported deep nested object conversion
model parameter will automatically convert to Animal inside save action
Array Converter#
Array converter a little bit different due to TypeScript design type emit limitation, use @plumier/reflect @type() decorator to specify array element data type.
Controller Return Value#
Controller can return any JavaScript value including promised value and rendered into JSON response. Promised value automatically awaited during JSON serialization.
Return Value Data Type#
To get the proper result (for swagger and response authorization) its required to specify data type of the action return value by using @type decorator.
Action Result#
For more advance result that require setting http status or response header can be done using ActionResult.
ActionResult is a special class that used to create an Http Response. ActionResult has ability to modify Http Response which make it possible to make a custom response such as return an html, file, file download etc.
Action Result Signature#
ActionResult signature has some similarities with the http response like below:
fromContextcreateActionResultfrom Koa contextsetHeaderset header that will be used by Http ResponsesetStatusset Http Status that will be use by Http Responseexecuteinternally called by Plumier to generate Koa context and render the response
setHeader and setStatus designed to be chainable, so it will be able to create ActionResult object like below
Action Result Implementation#
Currently now Plumier has three types of ActionResult implementation:
ActionResultby default will returned JSON responseRedirectActionResultused to redirect request to specific url, internally it calls KoaContext.redirectFileActionResultreturned a file response based on provided file path. This class only enable when@plumier/serve-staticinstalled.
A shorthand namespace available to access all of above implementation called response
Custom Action Result#
It is possible to extends the ability of ActionResult to modify the Http response to return custom http response. The main logic is on the execute method.
For example the implementation of FileActionResult is quite simple as below
Throwing Errors#
Any uncaught error will automatically handled by Plumier and translated into http response with status 500. You can throw HttpStatusError to provide custom error message with some http status that will be rendered into proper JSON response with appropriate status.
