Description
Currently, Rage::OpenAPI's @request and @response tags support inline schemas, shared references, and automatic generation from ActiveRecord models or Alba/Blueprinter serializers. However, there is no way to reference application-level Ruby constants — such as enums, status lists, or category arrays — in the OpenAPI schema.
This means users who define constants in their Ruby code must duplicate those values manually in the OpenAPI specification:
# In the application
module OrderStatus
PENDING = "pending"
CONFIRMED = "confirmed"
SHIPPED = "shipped"
CANCELLED = "cancelled"
ALL = [PENDING, CONFIRMED, SHIPPED, CANCELLED].freeze
end
# In the controller — values are duplicated
class Api::V1::OrdersController < ApplicationController
# @response { id: Integer, status: String }
def show
end
end
The status field in the OpenAPI output has no enum constraint — consumers don't know which values are valid. And if the developer adds the values manually to a shared components file, they must remember to update it every time the Ruby constant changes.
The goal is to extend the @request and @response syntax so users can reference Ruby constants directly, and Rage::OpenAPI will resolve them to OpenAPI enum values:
class Api::V1::OrdersController < ApplicationController
# @response { id: Integer, status: OrderStatus::ALL }
def show
end
end
This would generate:
status:
type: string
enum:
- pending
- confirmed
- shipped
- cancelled
Design considerations
- Which constant types to support. Arrays and hashes of simple values (strings, integers) are the most common case. Consider whether to also support
Set, ranges, or other enumerables in the initial implementation.
- Constant resolution. Constants must be resolved at spec generation time, not at boot. Since
Rage::OpenAPI analyzes controller source code using YARD-style tags, the implementation needs a strategy for resolving constant references from tag strings to actual Ruby values. Consider how namespacing and relative constant lookup should work.
- Inline vs. named schemas. When a constant is referenced in multiple places, should it produce a named schema in
components/schemas (DRY, but requires a naming convention) or inline the enum each time (simpler, but duplicates values in the spec)?
- Syntax design. The syntax should feel natural within the existing
@request/@response tag format. Consider how to differentiate a constant reference from a type name — OrderStatus::ALL is clearly a constant, but something like Status could be ambiguous (is it a type or a constant?).
Tips
- Review the OpenAPI docs to understand the existing
@request and @response tag syntax, shared references, and automatic schema generation.
- Look at how
Rage::OpenAPI currently resolves inline schemas and type references (e.g. Integer, String, Alba serializers) to understand where constant resolution would fit in.
- Check the architecture doc to see how Rage's core components interact and to understand the design principles.
- Read the contributing guide for coding conventions and design principles used across the codebase.
- Before starting the implementation, please share your proposed design approach. The syntax and resolution strategy need careful consideration, so discussing the approach early will drastically increase the chances of acceptance and help avoid rework.
- Feel free to ask any questions or request help in the comments below!
Description
Currently,
Rage::OpenAPI's@requestand@responsetags support inline schemas, shared references, and automatic generation from ActiveRecord models or Alba/Blueprinter serializers. However, there is no way to reference application-level Ruby constants — such as enums, status lists, or category arrays — in the OpenAPI schema.This means users who define constants in their Ruby code must duplicate those values manually in the OpenAPI specification:
The
statusfield in the OpenAPI output has no enum constraint — consumers don't know which values are valid. And if the developer adds the values manually to a shared components file, they must remember to update it every time the Ruby constant changes.The goal is to extend the
@requestand@responsesyntax so users can reference Ruby constants directly, andRage::OpenAPIwill resolve them to OpenAPI enum values:This would generate:
Design considerations
Set, ranges, or other enumerables in the initial implementation.Rage::OpenAPIanalyzes controller source code using YARD-style tags, the implementation needs a strategy for resolving constant references from tag strings to actual Ruby values. Consider how namespacing and relative constant lookup should work.components/schemas(DRY, but requires a naming convention) or inline the enum each time (simpler, but duplicates values in the spec)?@request/@responsetag format. Consider how to differentiate a constant reference from a type name —OrderStatus::ALLis clearly a constant, but something likeStatuscould be ambiguous (is it a type or a constant?).Tips
@requestand@responsetag syntax, shared references, and automatic schema generation.Rage::OpenAPIcurrently resolves inline schemas and type references (e.g.Integer,String, Alba serializers) to understand where constant resolution would fit in.