Parameter/Model Binding

KambojaJS automatically binds request parameter/query string to appropriate controller’s action parameter.

KambojaJS parameter binding system separated into two kinds based on the controller base class. When a controller inherited from Controller default parameter binding system will be applied, and when a controller inherited from ApiController a combination of api convention parameter binder and default parameter binder will be applied.

Api Convention Parameter Binder

Api convention parameter binder has the highest priority for all ApiController derived class. Basically it will search for the specialized parameters below.

Action URL
get(id, <optional>) /items/:id?<optional>
delete(id, <optional>) /items/:id?<optional>
add(body, <optional>) /items?<optional>
replace(id, body, <optional>) /items/:id?<optional>
modify(id, body, <optional>) /items/:id?<optional>

Api convention parameter binder works based on table above, position of the action parameter is mandatory.

  • For get and delete action the binder will look for the first parameter and assigned with the appropriate request parameter with the same name.
  • For add action it will look for the request body and applied to the first parameter.
  • For replace and modify action it will look for the first parameter seems like the get action and assigned the request body to the second parameter.
  • For the rest optional parameter the binder system will pass it through the default parameter binder.

Above process define the rule described on the ApiController reference.

Default Parameter Binder

Default parameter binder system works based on parameter name, it will search for action parameter name and bound it with appropriate request parameters.

For example if the request is like below

GET /items/index?id=20&message=hello

The appropriate controller is like below

import { Controller } from "kamboja"
 
export class ItemsController extends Controller {
    index(id:number, message:string) { }
}

id parameter of the controller’s action automatically bound with id query string of the url, so does the message parameter.

So after the request sent to the server, id parameter will have value 20 and message parameter have value hello.

Decorator Binding

It is possible to bind part of request property to action parameter by using @bind decorator.

import { Controller, route, bind } from "kamboja"
 
export class ItemsController extends Controller {
    @route.post()
    index(@bind.body() body:any) { }
}

Above code will bind request body to the body parameter. Here are list of complete members of @bind decorator

Method Description
@bind.body() Bind parameter to request body
@bind.cookie() Bind parameter to all cookies
@bind.cookie(“cookie-key”) Bind parameter only to cookie-key cookie

Value Converter

Important thing to note that parameter binding system doesn’t have information about action’s parameter type, by default the value is guessed automatically.

For example above if the request url is like below

GET /items/index?id=true&message=hello

The id parameter of the action will receive true type of boolean.

Note this behavior caused by JavaScript doesn’t have type system, even we defined them in the TypeScript code it will be erased after compiled.

To prevent unwanted conversion from other data type, you can specify a value converter. Value converter is part of validation system, if specified value doesn’t match with provided type an error will be returned.

import { Controller, val } from "kamboja"
 
export class ItemsController extends Controller {
    index(@val.type("number") id:number, message:string) { }
}

@val.type("number") on above code decorate the id parameter, that makes id parameter have a type of number validation, when a string is provided the value converter system will throw error.

KambojaJS have 3 value converter systems, all parameters will be checked for value converter based on its priority:

Decorator converter

This is the most priority converter. above code example is using decorator converter. Other possible type is string, number and boolean.

When used inside a model, there is an extra type supported

  • Array type string[], number[] and boolean[]
  • Qualified class name ModelName, model/path
  • Qualified class array ModelName[], model/path

Convention Converter

Convention converter have second priority in the system. It converts value based on prefix on parameter name.

  • Numeric parameter should start with i or n
  • String parameter should start with s
  • Boolean parameter should start with b
import { Controller } from "kamboja"
 
export class ItemsController extends Controller {
    index(iAge, sName, bIsGraduated) { }
}

Above code showing that iAge parameter have numeric value converter, sName have string value converter and bIsGraduate has boolean value converter.

Note this value converter doesn’t applied to model, because JavaScript doesn’t have static information about property.

Default converter

This is the default value converter will be applied if none of above converter match the condition.

This converter will convert value base on the value provided in the query string. for example:

GET /items/index?id=true&message=hello&age=0.34

From above url, id will get boolean value, message get string value, and age will get number value, it will ignore the TypeScript type annotation.