Respostas de erro multilíngues da API pública
TLDR: As mensagens de erro e de sucesso da API pública são traduzíveis e devolvidas no idioma do chamador (
pt-BR,en,es), compt-BRcomo padrão. O Admin/ActiveAdmin fica fora — não é multilíngue.
Visão geral
Toda mensagem user-facing da API pública vive em arquivo de locale sob o namespace api.*. A resolução do idioma da resposta acontece uma vez por request, em ApplicationController, via around_action :switch_locale — que envolve a ação em I18n.with_locale para o locale thread-local nunca vazar entre requests.
Somente locales presentes em I18n.available_locales (pt-BR, en, es, definidos em config/application.rb) são aceitos; qualquer outro valor cai no fallback. Com config.i18n.fallbacks = true, uma chave ausente em en/es cai no pt-BR em vez de quebrar.
Fluxo
mermaid
flowchart TD
R["Request"] --> P{"param ?locale= <br/>está em available_locales?"}
P -->|sim| USE["usa esse locale"]
P -->|não| H{"header Accept-Language<br/>tem match?"}
H -->|sim| USE
H -->|não| D["I18n.default_locale (pt-BR)"]
D --> USE
USE --> A["I18n.with_locale { action }"]
Precedência, em ordem:
- Param
?locale=— override explícito, mantido por compatibilidade. - Header
Accept-Language— melhor match respeitando os pesosq; tag regional cai no idioma base (en-US→en,pt-PT→pt-BR). I18n.default_locale(pt-BR) como fallback.
Contratos
Convenção de chaves
| Namespace | Uso | Domínios em uso |
|---|---|---|
api.errors.<domínio>.<chave> |
mensagens de erro | common, auth, membership, apolo, citrg, onboarding, webhook, webhook_email |
api.messages.<chave> |
mensagens de sucesso | ex.: profile_updated |
Tradução obrigatória nos três arquivos: config/locales/pt-BR.yml, config/locales/en.yml e config/locales/es.yml.
Mensagens de validação
As mensagens do ActiveRecord (blank, taken, …) e do Devise são localizadas por outra via: pt-BR pelo pt-BR.yml/devise.pt-BR.yml, en pelos defaults nativos do Rails, e es pelos gems rails-i18n/devise-i18n (já presentes). Nome de atributo sem tradução é humanizado automaticamente.
Regra ao adicionar uma mensagem nova
- Usar
I18n.t("api.errors....")/I18n.t("api.messages....")— nunca string literal. - Ter entrada em
pt-BR,enees. - Manter o shape de resposta do endpoint (
{ error: ... },{ message: ... }ou{ errors: [...] }) — a mudança é só na origem do texto.
Referências
app/controllers/application_controller.rb—switch_locale,resolved_locale,locale_from_header,best_available_localeconfig/application.rb—I18n.available_locales,default_locale,fallbacksconfig/locales/pt-BR.yml,config/locales/en.yml,config/locales/es.yml- Spec: respostas de erro multilíngues