Product API
Alongside the server-rendered store, the platform exposes a versioned JSON API for products — for mobile clients, integrations, and headless use.
Design
- REST + JSON under a versioned namespace, so the contract can evolve without breaking existing clients.
- Cursor-paginated list endpoints (see Scaling) — stable, fast pagination that does not drift when the catalog changes mid-scroll.
- Filtering and search that reuse the same query objects as the web store, so API and web results stay consistent.
- Authorization through the same Pundit policies as the rest of the app — the API is not a side door around the permission model.
Documented with OpenAPI
The API is specified with rswag, which generates an OpenAPI (Swagger) document straight from the request specs. That means:
- The docs are generated from tests — if the spec passes, the documentation is accurate by construction.
- A browsable Swagger UI is served at
/api-docsfor trying endpoints interactively.
bundle exec rspec spec/requests/api # tests + regenerates the OpenAPI spec
This closes the usual gap where hand-written API docs rot out of sync with the implementation.
Why it ships with the monolith
The API is a thin presentation layer over the same models, query objects, and policies the web store uses. Splitting it into its own service would have meant duplicating that logic or adding a network hop to reach it. Keeping it in the monolith means one source of truth for product data and one place to change it.
Key files
| Concern | Files |
|---|---|
| Controllers | app/controllers/api/, app/services/api/ |
| Pagination | CursorPaginator |
| Docs | rswag, request specs under spec/requests/, Swagger UI at /api-docs |