RESTful API e i18n: ¿cómo diseñar la respuesta?

15

Estamos diseñando una API RESTful destinada principalmente a satisfacer las necesidades de un solo cliente. Debido a sus circunstancias muy particulares, este cliente tiene que hacer la menor cantidad de solicitudes posible.

La API maneja i18n a través de un encabezado Accept-Language en las solicitudes. Esto funciona para todas las cosas que el cliente debe hacer, excepto una característica, en la que el cliente necesita almacenar las respuestas de una solicitud a un único punto final en todas las configuraciones regionales disponibles.

¿Podemos diseñar de alguna manera la API de manera que permita al cliente obtener toda esta información con una sola solicitud y sin romper un diseño de API RESTful consistente y bien estructurado?

Opciones que hemos considerado hasta ahora:

  • Permitiendo la inclusión de múltiples configuraciones regionales en el encabezado Accept-Language y agregando versiones localizadas para todas las configuraciones regionales solicitadas en la respuesta, cada una identificada por su código de idioma ISO 639-1 como la clave.
  • Crear algo como un parámetro "? All_languages ​​= true" para ese punto final y devolver versiones localizadas para todas las configuraciones regionales disponibles en la respuesta si ese parámetro está presente.
  • (Si nada de lo anterior funciona para nosotros) realizar múltiples solicitudes para obtener todas las versiones localizadas del cliente.

¿Cuál es la mejor alternativa?

AMM
fuente

Respuestas:

22

Describió dos formas efectivas de solicitar varios idiomas. Cualquiera de los dos debería funcionar bien. Elegiría el parámetro de solicitud de idioma explícito para mi propio código.

TL; DR Historia de fondo

Hay un encabezado Accept-Language . Nota Acceptno Accepted. Es una parte estándar de la negociación de contenido HTTP. La respuesta generalmente establece un encabezado Content-Language de nuevo.

Accept-Languagees la oferta inicial, que ofrece un conjunto de opciones; Content-Languagees la resolución, indicando qué idioma se eligió. La mayoría de las Content-Languagerespuestas devuelven un solo idioma, pero hay una opción para proporcionar una lista de idiomas de respuesta separados por comas. Por lo general, eso sería contenido mixto, pero no hay razón para que no pueda señalar múltiples alternativas disjuntas. Si quería el cliente para solicitar todos los idiomas disponibles, ya hay una opción de solicitud de comodín, *.

Entonces, ya existe un mecanismo de encabezado HTTP que puede usar. Sin embargo, tenga en cuenta que estaría aprovechando un proceso de negociación que con mayor frecuencia presenta una variedad de opciones posibles y recupera una sola opción. Cambiarías el sentido a "aquí hay una lista de opciones, ¡dame todas!" Si estás de acuerdo con eso, tienes una solución.

Sin embargo, existe un debate considerable sobre la idoneidad de la señalización de los parámetros de la API REST en los encabezados HTTP. Es un poco como entrar en un restaurante y dejar salir tu pedido detallado al anfitrión o al maître d 'en lugar de esperar a que aparezca el camarero o la camarera. Puede funcionar, y puede funcionar bien, por ejemplo, si la orden dirigida al anfitrión se relaciona con bebidas o aperitivos, cosas que el anfitrión puede ver rápidamente o comunicarse rápidamente con su servidor. Pero también puede verse como una violación del protocolo, dirigida en el nivel / capa incorrecto o al jugador equivocado.

Una segunda alternativa sería un parámetro de solicitud explícito. Usted sugiere ?all_languages=true. Eso parece demasiado específico. Algo como lang=en,fr,es(permitir múltiples idiomas listados) lang=*o lang=all(especificar cada idioma disponible) parece más general. Esto podría expresarse en la URL o en el cuerpo de la solicitud.

De cualquier manera, su respuesta multilingüe puede codificarse fácilmente en la carga útil JSON devuelta:

[ { "lang": "en", "content": "As Gregor Samsa awoke one morning..." },
  { "lang": "de", "content": "Als Gregor Samsa eines Morgens..." },
  ...
]

Al final, cualquiera de estos enfoques debería funcionar bien para usted. Cualquiera de los dos podría verse como un "diseño RESTful API consistente y bien estructurado". La determinación de cuál es mejor se basa principalmente en su actitud hacia la idoneidad de llevar a cuestas (y alterar ligeramente el sentido típico de) los encabezados de negociación de contenido HTTP.

Mi preferencia es no mezclar encabezados y otros parámetros como partes iguales de una solicitud de API. El explícito lango languageparámetro me parece más limpio. Pero dado que el verbo HTTP (por ejemplo GET, PUT, POST, PATCH, ...) es parte de la cabecera, y también crítica para / entremezclado con la interpretación de la solicitud, que admiten la distinción frente a contenidos sobre es un poco artificial y difusa. Como con la mayoría de las decisiones de diseño, los expertos genuinos responden de manera diferente, y YMMV.

Jonathan Eunice
fuente
Su respuesta ha sido muy educativa e informativa. Gracias. Gracias también por notar lo aceptado-no-aceptado. Es correcto en nuestro código, pero luego no pude usar el término apropiado al escribir la publicación. Lo modificaré para más referencias.
AMM