Rage Framework Documentation

website·Indexed 32 days ago

https://rage-rb.dev

Technical documentation for the Rage framework, including API references for classes and modules, telemetry, and an Inertia.js adapter. Includes guides on handling database connection errors in concurrent processing and system startup.

Tokens
12.1K
Snippets
82
Records
99
Agent score
62%

What's inside Rage

  1. Rage Framework Core Components Overview

    The Rage Framework provides several core components for application structure: Controller for handling HTTP requests and responses, Router for defining and managing application routes, and Configuration for managing application settings and environment variables.
  2. Implement application monitoring with Rage Telemetry

    Introduced in version 1.20.0, Rage includes a built-in telemetry system based on spans. These spans act as instrumentation points that wrap framework operations such as controller actions, cable actions, and deferred tasks. Developers can create custom handlers to observe these spans to track operation durations, record failures, and send metrics to external monitoring platforms. The system is designed to be passive, ensuring that errors in observability code do not crash the application.
  3. Observe application performance with Rage Telemetry Spans

    Rage uses a telemetry system based on spans to instrument framework operations (e.g., controller actions, cable actions, deferred tasks). Spans follow the naming pattern component.entity.action (e.g., controller.action.process). Developers can create handlers to observe these spans and integrate with external monitoring tools.
  4. Integrate Rage into an existing Rails application

    To use Rage for HTTP request handling while keeping Rails for ActiveRecord and migrations, follow these steps:

    1. Add gem "rage-rb" to Gemfile.
    2. Require require "rage/rails" in config/application.rb after the application class definition.
    3. Use Rage.routes.draw in config/routes.rb.
    4. Inherit ApplicationController from RageController::API.
    5. Update config.ru to run Rage.application.
    6. Use bundle exec rage s to start the server.
    # config/application.rb
    require "rage/rails"
    
    # config/routes.rb
    Rage.routes.draw do
      resources :bookings, only: %i(index create)
    end
    
    # app/controllers/application_controller.rb
    class ApplicationController < RageController::API
    end
    
    # config.ru
    require_relative "config/environment"
    run Rage.application
  5. Mark API endpoints as deprecated

    Use the @deprecated tag to mark specific actions or entire controllers as deprecated. When applied at the class level, it affects all actions within that controller and any child controllers.
    class Api::V1::UsersController < ApplicationController
      # Mark entire controller as deprecated
      # @deprecated
    
      def index
      end
    
      # Mark specific action as deprecated
      # @deprecated
      def create
      end
    end
  6. Schedule delayed or recurring tasks in `Rage::Deferred`

    Tasks can be scheduled for future execution using delay (seconds) or delay_until (Time object). Recurring tasks are configured in the global Rage configuration block using every.
    # Delayed execution
    SayHello.enqueue(name: "World", delay: 10)
    SayHello.enqueue(name: "World", delay_until: Time.now + 10)
    
    # Recurring schedule
    Rage.configure do
      config.deferred.schedule do
        every 5.minutes, task: ClearCache
      end
    end
  7. Set up RSpec for Rage request specs

    Rage integrates with RSpec to provide Rails-style testing helpers for API endpoints. To set up request specs, install rspec and database_cleaner-active_record, initialize RSpec, and configure the database cleaner.

    Critical Note: The transaction cleaning strategy is not supported because Rage executes requests in separate Fibers, which causes Active Record to use different connections for the test and the controller. Use the truncation strategy instead.

    # Gemfile
    group :test do
      gem "rspec"
      gem "database_cleaner-active_record"
    end
    
    # spec/spec_helper.rb
    RSpec.configure do |config|
      config.before(:suite) do
        DatabaseCleaner.strategy = :truncation
      end
    
      config.around(:each) do |example|
        DatabaseCleaner.cleaning(&example)
      end
    end
  8. Handle exceptions in Rage event subscribers

    Use the rescue_from method within a subscriber to centralize exception handling. For deferred subscribers, it is critical to re-raise the exception after handling it; otherwise, Rage will mark the subscriber as successful and will not trigger a retry.
    class CreateShipment
      include Rage::Events::Subscriber
      subscribe_to OrderCreated, deferred: true
    
      rescue_from Net::HTTPError do |exception|
        Rage.logger.with_context(exception:) do
          Rage.logger.error "Shipment API is unavailable"
        end
    
        raise exception
      end
    end
  9. Use shared OpenAPI component references

    For reusable schemas, create a YAML or JSON file (e.g., config/openapi_components.yml) with a root components key. Reference these components in controllers using JSON Pointer syntax (e.g., #/components/schemas/Name).
    # config/openapi_components.yml
    components:
      schemas:
        User:
          type: object
          properties:
            id: { type: integer }
            name: { type: string }
    class Api::V1::UsersController < ApplicationController
      # @response 200 #/components/schemas/User
      # @response 404 #/components/schemas/Error
      def show
      end
    end
  10. Create and structure Rage controllers

    Rage uses the MVC pattern where controllers handle incoming requests and coordinate responses. Each controller typically represents a resource. Public methods defined within a controller class are called 'actions' and handle specific operations on that resource.
    class UsersController < ApplicationController
      def create
        # create a user
      end
    end
  11. Implement controller callbacks with `before_action`

    The before_action callback runs code before a controller action executes. If render or head is called within a before_action, Rage halts request processing and skips the main controller action. This is commonly used for authentication and authorization.
    class UserStatusesController < ApplicationController
      before_action do
        @user = User.find_by(params[:id])
        head :bad_request unless @user
      end
    
      def create
        @user.activate!
      end
    end
  12. Create and broadcast to Unbounded SSE Streams

    Unbounded streams are long-lived connections that receive broadcasts from anywhere in the application (controllers, models, or background tasks). Use Rage::SSE.stream to attach a client to a named stream and Rage::SSE.broadcast to send data to all connected clients. Streams can be identified by strings or arrays (composite keys).
    # Controller: Establish connection
    render sse: Rage::SSE.stream([:notifications, params[:user_id]])
    
    # Anywhere: Broadcast message
    Rage::SSE.broadcast([:notifications, user.id], "New notification!")
    
    # Anywhere: Close all connections on a stream
    Rage::SSE.close_stream([:notifications, user.id])