Mode API de Rails en 2026 : API RESTful, sérialisation et bonnes pratiques
Maîtriser le mode API de Rails avec les bonnes pratiques de conception RESTful, la sérialisation JSON avec Alba et jsonapi-serializer, les stratégies d'authentification et la gestion des erreurs dans Rails 8.

Le mode API de Rails supprime les middlewares spécifiques au navigateur pour livrer un backend léger et rapide, conçu spécifiquement pour les API JSON. Avec Rails 8.1 et l'écosystème grandissant de bibliothèques de sérialisation, construire des API RESTful de qualité production n'a jamais été aussi fluide.
Le mode API de Rails retire les sessions, les cookies, les vues et le middleware de l'asset pipeline. Le résultat : une stack plus légère optimisée pour les réponses JSON, idéale pour les backends mobiles, les microservices et les SPA découplées.
Créer une application Rails 8 en mode API uniquement
Créer une application Rails dédiée aux API tient en un seul flag. L'option --api configure ApplicationController pour qu'il hérite de ActionController::API au lieu de ActionController::Base, retirant plus de 15 couches de middleware sans aucune utilité dans un contexte purement API.
# Terminal command
rails new order_service --api --database=postgresqlCette commande génère un projet sans templates de vue, sans compilation d'assets ni cookies de session. Le fichier application.rb résultant inclut config.api_only = true, ce qui maintient la stack de middleware au strict minimum.
Pour les applications Rails full-stack existantes qui nécessitent un namespace API, l'approche diffère : créer un contrôleur API de base qui hérite de ActionController::API et monter les routes API sous un namespace versionné.
# app/controllers/api/v1/base_controller.rb
module Api
module V1
class BaseController < ActionController::API
before_action :authenticate_request
private
def authenticate_request
# Token validation logic
end
end
end
endCe pattern préserve l'application full-stack intacte tout en ajoutant une couche API dédiée.
Conception des routes RESTful et stratégies de versioning
Une conception de routes RESTful propre influence directement la facilité d'utilisation et la maintenabilité d'une API. Le DSL de routing de Rails rend l'expression des hiérarchies de ressources simple, mais quelques conventions séparent les API solides des API fragiles.
# config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :users, only: [:index, :show, :create, :update] do
resources :orders, only: [:index, :show, :create]
end
resources :products, only: [:index, :show] do
collection do
get :search
end
end
resource :session, only: [:create, :destroy]
end
end
endConventions clés :
- Versioning par namespace (
/api/v1/) plutôt que par en-tête, pour la simplicité et la mise en cache - Imbrication superficielle limitée à un seul niveau :
/users/:user_id/ordersfonctionne, mais/users/:user_id/orders/:order_id/itemsdevrait devenir/orders/:order_id/items - Ressources singulières pour les endpoints représentant la session ou le profil de l'utilisateur courant
Lors du retrait d'une version d'API, retourner un HTTP 410 Gone avec un corps JSON pointant vers la nouvelle version plutôt que de casser silencieusement les clients.
Sérialisation JSON : Alba vs. jsonapi-serializer
La sérialisation détermine comment les objets ActiveRecord deviennent du JSON. Le choix du sérialiseur affecte les temps de réponse, la structure de la charge utile et la flexibilité du contrat d'API. Deux bibliothèques dominent l'écosystème Rails en 2026 : Alba pour la vitesse et la simplicité, et jsonapi-serializer pour la conformité à la spécification JSON:API.
Alba : performance sans dépendance
Alba sérialise les objets Ruby jusqu'à 10 fois plus vite que les alternatives héritées comme ActiveModel::Serializer. Elle n'a aucune dépendance, ce qui la rend idéale pour les services API légers.
# app/resources/user_resource.rb
class UserResource
include Alba::Resource
root_key :user, :users
attributes :id, :email, :name, :created_at
attribute :full_name do |user|
"#{user.first_name} #{user.last_name}"
end
many :orders, resource: OrderResource
# Conditional attributes based on context
attribute :admin_notes, if: proc { |user, params|
params[:current_user]&.admin?
}
end# app/controllers/api/v1/users_controller.rb
class Api::V1::UsersController < Api::V1::BaseController
def show
user = User.includes(:orders).find(params[:id])
render json: UserResource.new(user, params: { current_user: current_user })
end
def index
users = User.where(active: true).page(params[:page])
render json: UserResource.new(users)
end
endjsonapi-serializer : conformité stricte à la spécification
Lorsque les consommateurs de l'API attendent des réponses au format JSON:API avec les clés data, type, attributes et relationships, jsonapi-serializer (le fork maintenu du fast_jsonapi de Netflix) gère le formatage automatiquement.
# app/serializers/user_serializer.rb
class UserSerializer
include JSONAPI::Serializer
set_type :user
set_id :id
attributes :email, :name, :created_at
has_many :orders, serializer: OrderSerializer
# Cache at the serializer level for high-traffic endpoints
cache_options store: Rails.cache, namespace: "jsonapi", expires_in: 1.hour
endLe choix dépend du projet : Alba pour les API internes, les microservices et les backends mobiles où la flexibilité de la charge utile compte. jsonapi-serializer pour les API publiques où des contrats standardisés réduisent les frictions d'intégration.
Prêt à réussir tes entretiens Ruby on Rails ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Patterns d'authentification pour les API Rails
Rails 8 a introduit un générateur d'authentification intégré qui échafaude une authentification basée sur les sessions. L'adapter au mode API uniquement nécessite de remplacer les sessions par cookies par une authentification basée sur des tokens. Deux patterns dominent : le JWT pour les architectures sans état et les tokens bearer opaques pour une révocation plus simple.
JWT avec tokens à courte durée de vie
# app/services/jwt_service.rb
class JwtService
SECRET = Rails.application.credentials.jwt_secret_key
ALGORITHM = "HS256"
def self.encode(payload, exp: 15.minutes.from_now)
payload[:exp] = exp.to_i
JWT.encode(payload, SECRET, ALGORITHM)
end
def self.decode(token)
body = JWT.decode(token, SECRET, true, algorithm: ALGORITHM).first
HashWithIndifferentAccess.new(body)
rescue JWT::ExpiredSignature, JWT::DecodeError => e
nil
end
end# app/controllers/concerns/jwt_authenticatable.rb
module JwtAuthenticatable
extend ActiveSupport::Concern
included do
before_action :authenticate_request
end
private
def authenticate_request
token = request.headers["Authorization"]&.split(" ")&.last
decoded = JwtService.decode(token)
if decoded
@current_user = User.find_by(id: decoded[:user_id])
end
render json: { error: "Unauthorized" }, status: :unauthorized unless @current_user
end
def current_user
@current_user
end
endDes tokens d'accès à courte durée de vie (15 minutes) associés à une rotation des refresh tokens offrent un équilibre sécurisé. Le token d'accès reste sans état, tandis que les refresh tokens stockés en base de données permettent la révocation lors d'un changement de mot de passe ou d'une déconnexion.
Tokens bearer opaques
Pour des API plus simples où une recherche en base de données par requête est acceptable, has_secure_token offre une approche directe :
# app/models/user.rb
class User < ApplicationRecord
has_secure_password
has_secure_token :api_token
def regenerate_api_token!
regenerate_api_token
end
endLes tokens opaques simplifient la révocation (supprimer ou régénérer le token) mais exigent une requête en base de données à chaque appel authentifié.
Gestion structurée des erreurs à travers l'API
Des réponses d'erreur cohérentes séparent les API professionnelles des prototypes. Un gestionnaire d'erreurs centralisé empêche Rails de retourner des pages d'erreur HTML et garantit que chaque échec retourne du JSON structuré.
# app/controllers/concerns/error_handler.rb
module ErrorHandler
extend ActiveSupport::Concern
included do
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActiveRecord::RecordInvalid, with: :unprocessable_entity
rescue_from ActionController::ParameterMissing, with: :bad_request
end
private
def not_found(exception)
render json: {
error: "not_found",
message: "Resource not found",
details: exception.message
}, status: :not_found
end
def unprocessable_entity(exception)
render json: {
error: "validation_failed",
message: "Validation failed",
details: exception.record.errors.full_messages
}, status: :unprocessable_entity
end
def bad_request(exception)
render json: {
error: "bad_request",
message: "Missing required parameter",
details: exception.message
}, status: :bad_request
end
endInclure ce concern dans le contrôleur API de base. Chaque endpoint retourne alors des erreurs JSON prévisibles avec des codes de statut HTTP appropriés, des types d'erreur lisibles par machine et des messages lisibles par l'humain.
Les contrôleurs API utilisant une authentification basée sur des tokens doivent ignorer la vérification CSRF. Ajouter skip_before_action :verify_authenticity_token ou hériter de ActionController::API, qui n'inclut pas le middleware CSRF par défaut.
Pagination et optimisation des réponses
Les requêtes sans limite sont le chemin le plus rapide vers la dégradation des performances. Chaque endpoint de liste devrait paginer les résultats et communiquer clairement les métadonnées de pagination.
# app/controllers/api/v1/products_controller.rb
class Api::V1::ProductsController < Api::V1::BaseController
def index
products = Product
.where(active: true)
.order(created_at: :desc)
.page(params[:page])
.per(params[:per_page] || 25)
render json: {
data: ProductResource.new(products).serializable_hash,
meta: {
current_page: products.current_page,
total_pages: products.total_pages,
total_count: products.total_count
}
}
end
endAu-delà de la pagination, trois optimisations font une différence mesurable sur les temps de réponse de l'API :
- L'eager loading avec
includesoupreloadélimine les requêtes N+1 qui multiplient les allers-retours vers la base de données - Sélectionner uniquement les colonnes nécessaires avec
.select(:id, :name, :price)quand les sérialiseurs n'utilisent qu'un sous-ensemble des attributs du modèle - Les en-têtes de cache HTTP via
stale?etfresh_whenpermettent aux clients et aux CDN de mettre en cache les réponses sans logique personnalisée
Tester les endpoints d'API Rails avec RSpec
Les tests d'API devraient vérifier les codes de statut, la structure des réponses et les barrières d'authentification. Les request specs dans RSpec traversent la stack de middleware complète, ce qui en fait la représentation la plus proche du comportement réel d'une API.
# spec/requests/api/v1/users_spec.rb
RSpec.describe "Api::V1::Users", type: :request do
let(:user) { create(:user) }
let(:token) { JwtService.encode(user_id: user.id) }
let(:headers) { { "Authorization" => "Bearer #{token}" } }
describe "GET /api/v1/users/:id" do
it "returns the user with correct structure" do
get "/api/v1/users/#{user.id}", headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json["user"]).to include(
"id" => user.id,
"email" => user.email,
"name" => user.name
)
end
it "returns 401 without authentication" do
get "/api/v1/users/#{user.id}"
expect(response).to have_http_status(:unauthorized)
end
it "returns 404 for non-existent user" do
get "/api/v1/users/0", headers: headers
expect(response).to have_http_status(:not_found)
json = JSON.parse(response.body)
expect(json["error"]).to eq("not_found")
end
end
endCes tests couvrent les trois scénarios que chaque endpoint d'API devrait gérer : la structure d'une réponse réussie, l'application de l'authentification et le format des réponses d'erreur.
Fonctionnalités d'API de Rails 8.1 qui valent l'adoption
Rails 8.1 (publié en octobre 2025) ajoute des capacités directement pertinentes pour le développement d'API :
- Les Continuable Jobs permettent aux tâches d'arrière-plan de longue durée (imports de données, traitement par lots) de reprendre depuis le dernier point de contrôle après des déploiements ou des redémarrages, éliminant le travail gaspillé dans les pipelines de jobs d'arrière-plan
- Le Structured Event Logging via
Rails.event.notify(...)émet des événements consommables par les plateformes APM (Datadog, New Relic) sans code d'instrumentation personnalisé - Les Deprecated Associations peuvent être marquées avec les modes
:warn,:raiseou:notify, aidant les équipes à retirer progressivement les relations héritées dans de grandes bases de code d'API
Ces fonctionnalités réduisent le boilerplate dans les projets d'API et améliorent l'observabilité dès le départ. Le guide de migration Rails 8 couvre le parcours de mise à niveau complet.
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
Conclusion
- Utiliser le mode
--apipour les services API dédiés afin d'éliminer le middleware superflu et réduire la latence de réponse - Choisir un sérialiseur adapté au contrat : Alba pour la vitesse et la flexibilité, jsonapi-serializer pour une conformité stricte à JSON:API
- Implémenter une authentification par token avec des JWT à courte durée de vie et une rotation des refresh tokens, ou des tokens bearer opaques pour des besoins de révocation plus simples
- Centraliser la gestion des erreurs dans un concern partagé pour que chaque endpoint retourne du JSON structuré avec des types d'erreur cohérents
- Paginer chaque endpoint de liste et appliquer l'eager loading pour éliminer les requêtes N+1 avant qu'elles n'atteignent la production
- Tester avec des request specs sur les trois scénarios fondamentaux : structure de succès, application de l'authentification et format des erreurs
- Adopter les fonctionnalités de Rails 8.1 comme les continuable jobs et les événements structurés pour améliorer la fiabilité et l'observabilité des services API
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
Tags
Partager
Articles similaires

Solid Queue et Solid Cache dans Rails 8 : Guide complet pour les entretiens techniques 2026
Analyse approfondie de Solid Queue et Solid Cache, les solutions par défaut basées sur la base de données dans Rails 8. Architecture, configuration, contrôle de concurrence et connaissances clés pour les entretiens techniques en 2026.

Ruby on Rails 8 : Nouvelles Fonctionnalités et Guide de Migration 2026
Ruby on Rails 8 introduit le Solid Trifecta, un générateur d'authentification natif, Kamal 2 et Propshaft. Ce tutoriel couvre chaque fonctionnalité majeure et détaille la mise à jour depuis Rails 7 étape par étape.

Action Cable et WebSockets dans Rails : Guide Complet pour les Entretiens Techniques
Action Cable integre les WebSockets directement dans Rails. Ce guide approfondi couvre l'architecture des connexions, les channels, Solid Cable, Turbo Streams, le scaling avec Redis et les patterns de test pour les entretiens techniques.