Controller
Controller responsible for directing and coordinating the flow of data and operations within an application. The controller are defined in controllers directory. You can define the payload request and response in a controller.
Here is the default Raiden's controller.
package controllers
import (
"github.com/sev-2/raiden"
)
type HelloWorldRequest struct {
}
type HelloWorldResponse struct {
Message string `json:"message"`
}
type HelloWorldController struct {
raiden.ControllerBase
Payload *HelloWorldRequest
Result HelloWorldResponse
}
func (c *HelloWorldController) Get(ctx raiden.Context) error {
c.Result.Message = "Welcome to raiden"
return ctx.SendJson(c.Result)
}Routing
All routings are automatically generated by controllers based on their location within the controllers directory. The folder structure directly dictates the URL path.
Static Routes
For example, a controller located at controllers/status.go will automatically be accessible at the /status endpoint.
Dynamic Routes
Folders prefixed with an underscore (_) denote dynamic route segments. The name after the underscore becomes the parameter name, which can be accessed within the controller using ctx.GetParam("parameterName").
For example, a controller located at controllers/rest/v1/users/_id/custom.go will be accessible at /rest/v1/users/{id}. Inside the controller, you can retrieve the id like this:
id := ctx.GetParam("id").(string)HTTP Verb
You can use Get, Post, Put, Patch, Delete, Options, or Head on function name to use specific HTTP verb request.
For example, if you want to use Post and Delete request.
func (c *HelloWorldController) Post(ctx raiden.Context) error {
c.Result.Message = "Data has been inserted."
return ctx.SendJson(c.Result)
}
func (c *HelloWorldController) Delete(ctx raiden.Context) error {
c.Result.Message = "Data has been deleted."
return ctx.SendJson(c.Result)
}Type
There are several options for the controller type: custom, rest, rpc. These types influence the controller's behavior and generated functionalities, while the route itself is determined by the folder structure.
For example, a custom type controller:
type HelloWorldController struct {
raiden.ControllerBase
Payload *HelloWorldRequest
Result HelloWorldResponse
}INFO
The rpc type only available for Post verb.
Lifecycle Hooks
Each controller handler supports Before and After hooks. These hooks run before and after the main handler method, allowing you to add logic like authorization checks, logging, or response transformations.
Available hooks:
| Hook | Description |
|---|---|
BeforeAll / AfterAll | Runs before/after any HTTP method handler |
BeforeGet / AfterGet | Runs before/after Get handler |
BeforePost / AfterPost | Runs before/after Post handler |
BeforePut / AfterPut | Runs before/after Put handler |
BeforePatch / AfterPatch | Runs before/after Patch handler |
BeforeDelete / AfterDelete | Runs before/after Delete handler |
BeforeOptions / AfterOptions | Runs before/after Options handler |
BeforeHead / AfterHead | Runs before/after Head handler |
Example
type HelloWorldController struct {
raiden.ControllerBase
Payload *HelloWorldRequest
Result HelloWorldResponse
}
func (c *HelloWorldController) BeforeGet(ctx raiden.Context) error {
// Authorization check before Get handler
userRole := ctx.Get("role")
if userRole != "admin" {
return ctx.SendErrorWithCode(403, fmt.Errorf("forbidden"))
}
return nil
}
func (c *HelloWorldController) Get(ctx raiden.Context) error {
c.Result.Message = "Welcome to raiden"
return ctx.SendJson(c.Result)
}
func (c *HelloWorldController) AfterGet(ctx raiden.Context) error {
// Log after Get handler
fmt.Println("Get handler completed")
return nil
}RestController
RestController provides automatic CRUD operations for a model by proxying requests to the Supabase REST API. You don't need to write individual Get, Post, Put, Patch, or Delete handlers.
type ProductsController struct {
raiden.RestController
Model models.Products
Payload *ProductsRequest
Result ProductsResponse
}With RestController, the following endpoints are automatically available:
| Method | Description |
|---|---|
GET | Retrieve data (list or single) |
POST | Insert new data |
PUT | Replace existing data |
PATCH | Update existing data |
DELETE | Delete data |
You can still override any handler or add Before/After hooks to customize behavior:
func (c *ProductsController) BeforePost(ctx raiden.Context) error {
// Validate payload before insert
return nil
}