Controllers
Use the Zodra::Controller mixin for validated params and typed responses
Controllers
The Zodra::Controller mixin connects your Rails controllers to contracts, providing validated params and structured responses.
Setup
module Api
module V1
class ProductsController < ApplicationController
include Zodra::Controller
end
end
endZodra infers the contract name from the controller class: ProductsController → :products.
zodra_contract
Use zodra_contract to override the inferred name when the controller and contract names don't match:
zodra_contract :inventory # uses the :inventory contract instead of :productszodra_params
Returns the validated and coerced request params, parsed according to the action's params definition:
def create
params = zodra_params
# params is a hash with validated, typed values
# Unknown keys raise an error (when strict_params is true)
product = Product.create!(params)
zodra_respond(product, status: :created)
endFor actions without a params definition, zodra_params returns an empty hash.
zodra_respond
Renders a single object wrapped in { data: ... }:
def show
product = Product.find(zodra_params[:id])
zodra_respond(product)
# Response: { data: { id: "...", name: "...", ... } }
endWith a custom status:
zodra_respond(product, status: :created)For no-content responses:
def destroy
Product.find(zodra_params[:id]).destroy!
head :no_content
endzodra_respond_collection
Renders an array wrapped in { data: [...] }:
def index
products = Product.all
zodra_respond_collection(products)
# Response: { data: [...] }
endWith optional meta:
zodra_respond_collection(products, meta: { total: products.count })zodra_rescue
Maps exceptions to error codes defined in the contract:
class OrdersController < ApplicationController
include Zodra::Controller
zodra_rescue :confirm, InvalidTransitionError, as: :invalid_transition
zodra_rescue :cancel, InvalidTransitionError, as: :invalid_transition
def confirm
order = Order.find(zodra_params[:id])
order.confirm!
zodra_respond(order.reload)
end
endWhen InvalidTransitionError is raised, Zodra renders:
{
"error": {
"code": "invalid_transition",
"message": "..."
}
}The HTTP status comes from the error definition in the contract.
See Error Handling for the full error flow.
zodra_errors
Returns field-level validation errors. Accepts ActiveModel::Errors, hashes, or anything responding to .messages:
def create
product = Product.new(zodra_params)
if product.save
zodra_respond(product, status: :created)
else
zodra_errors(product.errors)
end
endKeys are automatically transformed to match your key_format configuration, including nested keys in arrays.
For complex error mapping (multiple models, key remapping), use Zodra::ErrorMapper. See Error Handling.
Full controller example
module Api
module V1
class CustomersController < ApplicationController
include Zodra::Controller
def index
zodra_respond_collection(Customer.all)
end
def show
zodra_respond(Customer.find(zodra_params[:id]))
end
def create
customer = Customer.new(zodra_params)
if customer.save
zodra_respond(customer, status: :created)
else
zodra_errors(customer.errors)
end
end
def update
customer = Customer.find(zodra_params[:id])
customer.assign_attributes(zodra_params.except(:id))
if customer.save
zodra_respond(customer)
else
zodra_errors(customer.errors)
end
end
def destroy
Customer.find(zodra_params[:id]).destroy!
head :no_content
end
end
end
end