Rails projects typically start out as simple HTML pages and forms operating on a database, but evolve into more complex applications over time. In order to add a client-side framework or mobile application, creating a REST API might be necessary.
It’s really straightforward to create a new Rails API. However, it might be easier to add an API to an existing project. There is no one, “right” way to do this, but here are some things to keep in mind that can make future development a bit easier.
Keep API Routes in an API Namespace
By keeping API routes under a specific namespace, it’s easier for other developers to find which URLs are API-specific. It also gives clients a consistent and descriptive URL pattern.
This results in the following routes:
Another tip is to version the API with
v1 right off the bat, which allows it to grow into a
v2 if needed.
Create New API Controllers Under an API Module
With the routes in a separate namespace, all API-specific logic can go into new controllers:
They go into a similar module structure to how the routes are drawn:
Creating new controllers, rather than adding API logic to the existing web controllers, keeps them (and their tests) smaller and more cohesive. API controllers generally have to handle:
These are rarely needed in the existing web controllers, which handle more browser-centric concerns (ex. HTML templates).
Use an API-Specific Base Controller
The new controllers can probably get away with inheriting from
ApplicationController. However, it’s beneficial and easy to create a separate base controller:
This keeps shared, API-specific logic in its own place, like token authentication or JSON error-message formatting.
Share Business Logic via Service Objects
Logic between API and web controllers eventually overlap. This is where design patterns can really help keep code as DRY as possible.
Service objects can be used to share logic between controllers:
For example, querying data is typically the same in the
index actions of both API and web controllers:
By extracting this logic into a “query” object:
Both controllers can share the same logic:
This tip isn’t specific controllers. In fact, service objects can be beneficial throughout an entire Rails codebase.
Before adding a new REST API to an existing Rails project, keep these tips in mind. They aren’t hard and fast rules, but they might make development easier in the future.
Questions? Comments? Critiques? Leave me a comment below!