Rails Integration

Servus core works in any Ruby application. Rails-specific features (async, controller helpers, generators) are optional additions that integrate with Rails conventions.

Controller Integration

Use the run_service helper to call services from controllers with automatic error handling:

class UsersController < ApplicationController
  include Servus::Helpers::ControllerHelpers

  def create
    run_service(Users::Create::Service, user_params)
  end

  # Failures automatically render JSON:
  # { "error": { "code": "validation_error", "message": "..." } }
  # with appropriate HTTP status code
  #
  # Success will go to view and service result will be available on @result
end

Without the helper, handle responses manually:

def create
  result = Users::Create::Service.call(user_params)
  if result.success?
    render json: { user: result.data[:user] }, status: :created
  else
    render json: { error: result.error.api_error }, status: error_status(result.error)
  end
end

Generator

Generate services with specs and schema files:

rails generate servus:service process_payment

# Creates:
# app/services/process_payment/service.rb
# spec/services/process_payment/service_spec.rb
# app/schemas/services/process_payment/arguments.json
# app/schemas/services/process_payment/result.json

Schema files are optional - delete them if you don't need validation.

Autoloading

Servus follows Rails autoloading conventions. Services in app/services/ are automatically loaded by Rails:

# app/services/users/create/service.rb
module Users
  module Create
    class Service < Servus::Base
      # ...
    end
  end
end

# Rails autoloads this as Users::Create::Service

Configuration

Configure Servus in an initializer if needed:

# config/initializers/servus.rb
Servus.configure do |config|
  config.schema_root = Rails.root.join('config/schemas')
end

Most applications don't need any configuration.

Background Jobs

Async execution requires ActiveJob setup. Configure your adapter:

# config/application.rb
config.active_job.queue_adapter = :sidekiq

Then use .call_async:

Users::SendWelcomeEmail::Service.call_async(user_id: user.id)