Controllers
After the routing has been determined (see routes), a controller action will get called to process the request and provide a response.
Here's what a simple controller looks like:
local InfoController = {}
function InfoController:whoami()
return 200, { name = 'gin' }
end
return InfoController
When called, this returns an HTTP 200
response with body:
{
"name": "gin"
}
Return values
The return values of a controller define its response. There are three way you can do so.
Just the HTTP code
return 200
Returning only the HTTP code will respond with the provided code, an empty JSON body and no additional headers.
The HTTP code and the body
return 200, { name = 'gin' }
Gin will respond with the provided code and the encoded JSON body, with no additional headers.
The HTTP code, the body and the headers
return 200, { name = 'gin' }, { ["Cache-Control"] = "max-age=3600", ["Retry-After"] = "120" }
Gin will respond with the provided code, the encoded JSON body, and the additional headers.
Raising errors
Once you have defined your errors, it's really easy to return error responses.
To raise an error, simply refer to the error number you've defined in your errors' initializer. For instance, if your Errors are defined as:
local Errors = {
[1000] = { status = 400, message = "Invalid request." }
}
return Errors
Then from a controller you can simply raise it with:
self:raise_error(1000)
This will return a HTTP status 400
with the body:
{
"code": 1000,
"message": "Invalid request."
}
If you need to provide additional information in the payload of the error body, you can do so by passing a table as a second parameter, like so:
self:raise_error(1000, { missing_fields = { "first_name", "last_name" } })
This will merge the provided table and return a HTTP status 400
with the body:
{
"code": 1000,
"message": "Invalid request.",
"missing_fields": [
"first_name",
"last_name"
]
}
The routes parameters
The parameters resulting from a route match are available in the table:
self.params
Please see routes for additional information on how to capture and use these.
The request
The original request is available in a controller's action and accessible on self:
self.request
Gin only accepts requests that provide JSON in the body, hence the body is available to you pre-parsed for your convenience.
The request has the following properties:
request.uri_params
: the parsed querystring params (a table)request.method
: the HTTP methodrequest.headers
: the HTTP headers (a table)request.body
: the parsed JSON body (a table)request.api_version
: the complete API version as specified by the client.
It also provide these additional advanced properties:
request.uri
: the full URIrequest.body_raw
: the raw bodyrequest.ngx
: the ngx object, refer to the HttpLuaModule documentation for more information.
Minor version support
While support for major version numbers is baked into Gin by calling the controllers that correspond to a major version number, minor versioning logic can be implemented at a controller level.
Let's say that a client requests the specific version 1.0.2-rc1
in the request headers. Gin will automatically support major versioning by calling the controller located in the corresponding directory ./app/controllers/1
, but then in your controller the full version requested by the client is available in the parameter self.request.api_version
.
A very simple logic looks like this:
local InfoController = {}
function InfoController:whoami()
if self.request.api_version == "1.0.2-rc1" then
return 200, { name = "gin newer" }
else
return 200, { name = "gin standard" }
end
end
return InfoController
The Accepted Params helper
The controller exposes the method accepted_params
that allows you to filter out any unwanted keys from the requested params in the body.
This allows you to filter out:
- Non-existent params in a database table
- Params that you do not want to expose to the caller.
For instance:
local params = self:accepted_params({ 'first_name', 'last_name' }, self.request.body)
The variable params
will only contains the keys first_name
, last_name
from the request body.