Designing HTTP APIs in Rails That Your Frontend Team Will Actually Like
Most API complaints are about inconsistency, not missing features. Consistency is the actual deliverable of API design.
Publié le 6 février 2022 · 4 min de lecture
Most API complaints from frontend teams aren't about missing features, they're about inconsistency: one endpoint returns dates as ISO strings, another as Unix timestamps, and errors come back in three different shapes depending on which controller raised them. Consistency is the actual deliverable of API design.
Pick an error shape once, apply it everywhere
A single, predictable error format lets a frontend write one error handler instead of one per endpoint.
rescue_from ActiveRecord::RecordInvalid do |e|
render json: {
error: { code: "validation_failed", message: e.message, fields: e.record.errors.as_json }
}, status: :unprocessable_entity
end
Serialize explicitly, don't leak the model
Rendering an ActiveRecord object directly exposes every column, including ones added next quarter for an unrelated reason. A dedicated serializer keeps the response shape a deliberate contract instead of an accident of the schema.
Version from day one, even a monolith's internal API
Adding a version prefix to routes costs nothing when there's a single consumer. Retrofitting it after three external integrations already depend on the unversioned path costs a migration plan and a deprecation window. We add the prefix even on APIs we're certain will only ever have one client, because that certainty is usually wrong within a year.
Pagination and filtering are part of the contract, not an afterthought
An endpoint returning all records "for now" becomes a production incident the day that table crosses a few hundred thousand rows. Cursor-based pagination, documented from the first version, avoids both the performance cliff and the breaking change of adding pagination later to a client that assumed a flat array.
None of this is about following a spec for its own sake. It's about making the API something a frontend team can build against without reading the Rails source to guess what happens next.
Articles liés
Events vs Commands: Untangling Event-Driven Architecture in a Rails System
Two very different contracts hide behind the same "event-driven" label. Getting the naming right decides how the rest of the architecture behaves.
Designing a Rails Service Architecture Around SEPA and Payment Flows
Payments change the design questions a Rails codebase has to answer. Notes on isolating money movement, ledgers, and modeling SEPA as the asynchronous process it is.