rails-api-design
Rails API Design
Build a JSON API that ages well. AI agents generate Rails APIs by reflex:
respond_to :json,to_json, no versioning, no rate limiting, no consistent error shape. This skill encodes the choices senior Rails API authors make when the API has to live for years.
Why this matters
A REST API is a contract. Once clients depend on it, every change is a coordination cost. Get the foundations right at the start — versioning strategy, serialization layer, pagination, error format — or pay for it later in deprecation pain.
The opinion
URL versioning (
/api/v1). jsonapi-serializer for JSON:API; alba for plain JSON. pagy for pagination (faster than kaminari). JWT for stateless third-party / mobile clients; session cookies for first-party SPAs on the same domain. rack-attack for rate limiting + brute-force. Structured errors per RFC 9457 (problem-details) or JSON:API errors. rswag for OpenAPI generation from request specs.
Counter-positions:
- GraphQL over REST: legitimate for highly-relational read APIs with many client variants. We default to REST because the tooling is broader and the operational burden is lower. If you have GraphQL needs, use
graphql-ruby. - Accept-header versioning (
Accept: application/vnd.myapp+json; version=2): cleaner in theory; in practice harder to debug, caches awkwardly, and devs hate it. URL versioning wins on operational ergonomics. - active_model_serializers (AMS): widely used historically. We default to
jsonapi-serializer(formerly Fast JSONAPI) oralbabecause both are 10–50× faster.