abstract struct Kemal::Controller

Overview

Abstract controller class that provides a structured way to define HTTP endpoints.

Controllers are structs, so the overhead is minimal and you can still use all Kemal features. Method parameters automatically map to GET/POST/URL parameters with type-safe conversion.

Example

struct UsersController < Kemal::Controller
  @[Get("/users")]
  def index
    "Listing all users"
  end

  @[Get("/users/:id")]
  def show(id : Int32)
    "Showing user with ID: #{id}"
  end

  @[Post("/users")]
  def create(name : String, age : Int32, description : String?)
    "Creating user with name: #{name}, age: #{age}, description: #{description}"
  end
end

Supported Parameter Types

Parameter Mapping

Route annotation parameters

Example

@[Get("/users/:id")]
def show(id : Int32)
  "User #{id}"
end

Example with Authentication

@[Get("/admin/dashboard", auth: true)]
def dashboard
  "Admin Dashboard"
end

private def authenticate! : Bool
  # Return false to halt with 401 status
  request.headers["Authorization"]? == "SecretToken"
end

Example with Parameter Stripping

@[Post("/users", strip: true)]
def create(name : String, description : String?)
  # name and description will have leading/trailing whitespace removed
end

@[Post("/login", strip: [:email])]
def login(email : String, password : String)
  # Only email will be stripped, password remains unchanged
end

Defined in:

kemal/controller.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(context : HTTP::Server::Context) #

Initializes a new controller instance.

This is called automatically by the framework when processing a request. You typically don't need to call this directly.

Parameters

  • #context : HTTP::Server::Context - The HTTP server context for the request

[View source]

Instance Method Detail

def context : HTTP::Server::Context #

The HTTP server context for the current request.

Provides access to the underlying HTTP::Server::Context which contains the request and response objects.


[View source]
def error(field, message, status : HTTP::Status | Nil = nil) #

Adds a field-specific error message.

Stores an error message for a specific field and sets the appropriate HTTP status code. If no custom status is provided, sets 400 (Bad Request) for GET/HEAD/OPTIONS requests or 422 (Unprocessable Entity) for POST/PUT/PATCH/DELETE requests.

Parameters

  • field : String - The name of the field that has an error
  • message : String - The error message for this field
  • status : HTTP::Status? - Optional custom HTTP status code (default: nil)

Example

def create(email : String, password : String)
  if !email.includes?("@")
    error("email", "Invalid email format")
    render("src/views/users/new.ecr")
    return
  end
  if password.size < 8
    error("password", "Password must be at least 8 characters", HTTP::Status::BAD_REQUEST)
    render("src/views/users/new.ecr")
    return
  end
end

[View source]
def error(message : String) #

Adds a general error message to the base error field.

This is useful for errors that don't belong to a specific field. Sets the response status to 400 (Bad Request) for GET/HEAD/OPTIONS requests or 422 (Unprocessable Entity) for POST/PUT/PATCH/DELETE requests.

Parameters

  • message : String - The error message to add

Example

def create(name : String)
  if name.empty?
    error("Name cannot be empty")
    render("src/views/users/new.ecr")
    return
  end
end

[View source]
def error_for?(field : String) : String | Nil #

Returns the error message for a specific field.

Returns nil if there is no error for the specified field.

Parameters

  • field : String - The name of the field to check for errors

Example

def create(email : String)
  error("email", "Invalid email") unless email.includes?("@")

  if msg = error_for?("email")
    render("src/views/users/new.ecr")
    return
  end
end

[View source]
def error_for_base : String | Nil #

Returns the error message for the "base" field.

The "base" field is used for general errors that don't belong to a specific field. Returns nil if there is no base error.

Example

def update
  error("Something went wrong")
  if msg = error_for_base
    render("src/views/error.ecr")
    return
  end
end

[View source]
def errors : Errors | Nil #

Hash of validation errors that occurred during request processing.

Maps field names to error messages. Use #error methods to add errors and #has_error?, #error_for?, #error_for_base to check for errors.

Returns nil if no errors have been recorded.


[View source]
def has_error? : Bool #

Checks if any errors have been recorded.

Returns true if there are one or more validation errors, false otherwise.

Example

def create(name : String, email : String)
  error("name", "Name is required") if name.empty?
  error("email", "Email is required") if email.empty?

  if has_error?
    render("src/views/users/new.ecr")
    return
  end

  # Process the valid data
end

[View source]
def redirect(*args, **options) #

Delegates to the redirect method from the context.

Redirects the request to another URL.

Example

redirect("/login")

[View source]
def redirect(*args, **options, &) #

Delegates to the redirect method from the context.

Redirects the request to another URL.

Example

redirect("/login")

[View source]
def request(*args, **options) #

Delegates to the request object from the context.

Provides direct access to the HTTP::Request for the current request.


[View source]
def request(*args, **options, &) #

Delegates to the request object from the context.

Provides direct access to the HTTP::Request for the current request.


[View source]
def response(*args, **options) #

Delegates to the response object from the context.

Provides direct access to the HTTP::Response for the current request.


[View source]
def response(*args, **options, &) #

Delegates to the response object from the context.

Provides direct access to the HTTP::Response for the current request.


[View source]
def session(*args, **options) #

Delegates to the session object from the context.

Provides access to the Kemal session for the current request.


[View source]
def session(*args, **options, &) #

Delegates to the session object from the context.

Provides access to the Kemal session for the current request.


[View source]