Pregunta Mejores prácticas para el control de versiones API [cerrado]


¿Hay algún tipo de prácticas conocidas o prácticas recomendadas para el control de versiones de la API REST del servicio web?

Me he dado cuenta que AWS realiza versiones por la URL del punto final. ¿Es esta la única manera o hay otras formas de lograr el mismo objetivo? Si hay múltiples formas, ¿cuáles son los méritos de cada camino?


878
2017-12-23 15:32


origen


Respuestas:


Esta es una pregunta buena y difícil. El tema de El diseño de URI es al mismo tiempo la parte más destacada de una API REST y, por lo tanto, un potencial compromiso a largo plazo hacia los usuarios de esa API.

Dado que la evolución de una aplicación y, en menor medida, su API es una realidad y que incluso es similar a la evolución de un producto aparentemente complejo como un lenguaje de programación, el Diseño de URI debería tener menos restricciones naturales y debe ser preservado con el tiempo. Cuanto más larga sea la vida útil de la aplicación y la API, mayor será el compromiso con los usuarios de la aplicación y la API.

Por otro lado, otro hecho de la vida es que es difícil prever todos los recursos y sus aspectos que se consumirían a través de la API. Afortunadamente, no es necesario diseñar toda la API que se utilizará hasta Apocalipsis. Es suficiente para definir correctamente todos los puntos finales de los recursos y el esquema de direccionamiento de cada instancia de recursos y recursos.

Con el tiempo, puede necesitar agregar nuevos recursos y nuevos atributos a cada recurso en particular, pero el método que los usuarios de la API sigan para acceder a recursos particulares no debería cambiar una vez que un esquema de direccionamiento de recursos se vuelva público y, por lo tanto, definitivo.

Este método se aplica a la semántica de verbos HTTP (por ejemplo, PUT siempre debe actualizar / reemplazar) y códigos de estado HTTP que son compatibles con versiones anteriores de API (deben seguir funcionando para que los clientes API que han trabajado sin intervención humana puedan continuar trabajando como eso).

Además, dado que la incrustación de la versión API en el URI perturbaría el concepto de hipermedia como el motor del estado de la aplicación (expuesto en la disertación de doctorado de Roy T. Fieldings) al tener una dirección de recursos / URI que cambiaría con el tiempo, concluiría que Las versiones de API no deben mantenerse en los URI de recursos durante mucho tiempo significa que Los URI de recursos de los que pueden depender los usuarios de API deben ser enlaces permanentes.

Por supuesto, es posible incrustar la versión de API en el URI base pero solo para usos razonables y restringidos, como la depuración de un cliente API eso funciona con la nueva versión de API. Tales API versionadas deberían tener un límite de tiempo y estar disponibles solo para grupos limitados de usuarios API (como durante betas cerradas). De lo contrario, te comprometes donde no deberías.

Un par de consideraciones sobre el mantenimiento de las versiones de API que tienen fecha de caducidad. Todas las plataformas de programación / lenguajes utilizados comúnmente para implementar servicios web (Java, .NET, PHP, Perl, Rails, etc.) permiten una fácil unión de los puntos finales del servicio web a un URI base. De esta manera es fácil reunir y mantener una colección de archivos / clases / métodos separar en diferentes versiones de API.

Desde el punto de vista de los usuarios de la API, también es más fácil trabajar con una versión específica de la API y unirse a ella cuando es así de obvio, pero solo por tiempo limitado, es decir, durante el desarrollo.

Desde el punto de vista del desarrollador de API, es más fácil mantener diferentes versiones de API en paralelo mediante el uso de sistemas de control de fuente que trabajan predominantemente en archivos como la unidad más pequeña de versiones (código fuente).

Sin embargo, con las versiones de API claramente visibles en URI hay una advertencia: también se podría objetar este enfoque desde El historial de API se vuelve visible / aparent en el diseño de URI  y por lo tanto, es propenso a cambios a lo largo del tiempo lo cual va en contra de las pautas de REST. ¡Estoy de acuerdo!

La forma de evitar esta objeción razonable es implementar la última versión de API bajo URI base de API sin versión. En este caso, los desarrolladores de cliente API pueden elegir entre:

  • desarrollar contra el último (comprometerse a mantener la aplicación protegiéndola de eventuales cambios API que podrían romper su mal diseñado API cliente)

  • enlazar a una versión específica de la API (que se vuelve aparente) pero solo por un tiempo limitado

Por ejemplo, si API v3.0 es la versión más reciente de la API, los dos siguientes deberían ser alias (es decir, comportarse de manera idéntica a todas las solicitudes de la API):

http: // shonzilla / api / clientes / 1234
http: // shonzilla / api/v3.0/ clientes / 1234
http: // shonzilla / api/ v3/ clientes / 1234

Además, los clientes API que todavía intentan apuntar a la antiguo La API debe ser informada para usar la última versión anterior de la API, si la versión de la API que están utilizando ya no es compatible o ya no es compatible. Para acceder a cualquiera de los URI obsoletos como estos:

http: // shonzilla / api/v2.2/ clientes / 1234
http: // shonzilla / api/v2.0/ clientes / 1234
http: // shonzilla / api/ v2/ clientes / 1234
http: // shonzilla / api/v1.1/ clientes / 1234
http: // shonzilla / api/ v1/ clientes / 1234

debe devolver cualquiera de los 30x códigos de estado HTTP que indican la redirección que se usan junto con Location El encabezado HTTP que redirige a la versión apropiada del URI de recursos que sigue siendo este:

http: // shonzilla / api / clientes / 1234

Existen al menos dos códigos de estado HTTP de redireccionamiento que son apropiados para los escenarios de versiones API:

  • 301 Movido Permanentemente lo que indica que el recurso con un URI solicitado se mueve de forma permanente a otro URI (que debe ser un enlace permanente de instancia de recurso que no contiene información de versión de API). Este código de estado se puede usar para indicar una versión de API obsoleta / no compatible, informando al cliente de API que el URI de recursos versionados ha sido reemplazado por un enlace permanente de recursos.

  • 302 encontrados lo que indica que el recurso solicitado se encuentra temporalmente en otra ubicación, mientras que el URI solicitado aún puede ser compatible. Este código de estado puede ser útil cuando los URI sin versión están temporalmente no disponibles y una solicitud debe repetirse usando la dirección de redirección (por ejemplo, apuntando al URI con la versión APi incrustada) y queremos decirle a los clientes que sigan usándolo (es decir, permalinks).

  • otros escenarios se pueden encontrar en Capítulo de redirección 3xx de la especificación HTTP 1.1


684
2017-12-29 20:24



La URL NO debe contener las versiones. La versión no tiene nada que ver con la "idea" del recurso que está solicitando. Debería intentar pensar que la URL es una ruta hacia el concepto que le gustaría, no cómo desea que se devuelva el elemento. La versión dicta la representación del objeto, no el concepto del objeto. Como han dicho otros carteles, debe especificar el formato (incluida la versión) en el encabezado de la solicitud.

Si observa la solicitud HTTP completa para las URL que tienen versiones, se ve así:

(BAD WAY TO DO IT):

http://company.com/api/v3.0/customer/123
====>
GET v3.0/customer/123 HTTP/1.1
Accept: application/xml

<====
HTTP/1.1 200 OK
Content-Type: application/xml
<customer version="3.0">
  <name>Neil Armstrong</name>
</customer>

El encabezado contiene la línea que contiene la representación que está solicitando ("Aceptar: aplicación / xml"). Ahí es donde debería ir la versión. Todo el mundo parece pasar por alto el hecho de que puede querer lo mismo en diferentes formatos y que el cliente debe poder pedir lo que quiere. En el ejemplo anterior, el cliente está pidiendo ALGUNA Representación XML del recurso: no es realmente la representación real de lo que quiere. El servidor podría, en teoría, devolver algo completamente ajeno a la solicitud, siempre que fuera XML y tendría que ser analizado para darse cuenta de que está mal.

Una mejor manera es:

(GOOD WAY TO DO IT)

http://company.com/api/customer/123
===>
GET /customer/123 HTTP/1.1
Accept: application/vnd.company.myapp.customer-v3+xml

<===
HTTP/1.1 200 OK
Content-Type: application/vnd.company.myapp-v3+xml
<customer>
  <name>Neil Armstrong</name>
</customer>

Además, digamos que los clientes piensan que el XML es demasiado detallado y ahora quieren JSON. En los otros ejemplos, debería tener una nueva URL para el mismo cliente, por lo que terminaría con:

(BAD)
http://company.com/api/JSONv3.0/customers/123
  or
http://company.com/api/v3.0/customers/123?format="JSON"

(o algo similar). Cuando, de hecho, cada solicitud HTTP contiene el formato que está buscando:

(GOOD WAY TO DO IT)
===>
GET /customer/123 HTTP/1.1
Accept: application/vnd.company.myapp.customer-v3+json

<===
HTTP/1.1 200 OK
Content-Type: application/vnd.company.myapp-v3+json

{"customer":
  {"name":"Neil Armstrong"}
}

Al usar este método, tiene mucha más libertad en el diseño y en realidad se adhiere a la idea original de REST. Puede cambiar las versiones sin interrumpir a los clientes o cambiar de forma incremental los clientes a medida que cambian las API. Si elige dejar de admitir una representación, puede responder a las solicitudes con código de estado HTTP o códigos personalizados. El cliente también puede verificar que la respuesta esté en el formato correcto y validar el XML.

Hay muchas otras ventajas y analizo algunas de ellas aquí en mi blog:    http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

Un último ejemplo para mostrar cómo poner la versión en la URL es malo. Supongamos que quiere información dentro del objeto y ha versionado sus diversos objetos (los clientes son v3.0, los pedidos son v2.0 y el objeto shipto es v4.2). Aquí está la URL desagradable que debe proporcionar en el cliente:

(Another reason why version in the URL sucks)
http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

273
2017-07-19 16:08



Nos pareció práctico y útil poner la versión en la URL. Hace que sea fácil decir lo que estás usando de un vistazo. Hacemos alias / foo a / foo / (últimas versiones) para facilitar el uso, URL más cortas / más limpias, etc., como lo sugiere la respuesta aceptada.

Mantener la compatibilidad hacia atrás para siempre suele ser prohibitivo y / o muy difícil. Preferimos dar aviso anticipado de desaprobación, redirecciones como las sugeridas aquí, documentos y otros mecanismos.


99
2018-01-04 20:57



Acepto que versionar la representación de recursos sigue mejor el enfoque REST ... pero, un gran problema con los tipos MIME personalizados (o los tipos MIME que añaden un parámetro de versión) es la falta de soporte para escribir en Aceptar y encabezados de tipo de contenido en HTML y JavaScript.

Por ejemplo, no es posible que IMO PUBLIQUE con los siguientes encabezados en formularios HTML5, para crear un recurso:

Accept: application/vnd.company.myapp-v3+json
Content-Type: application/vnd.company.myapp-v3+json 

Esto es porque el HTML5 enctype atributo es una enumeración, por lo tanto, cualquier cosa que no sea la habitual application/x-www-formurlencoded, multipart/form-data y text/plain son inválidos

... ni estoy seguro de que sea compatible con todos los navegadores en HTML4 (que tiene un atributo de encytpe más laxo, pero sería un problema de implementación del navegador en cuanto a si se reenvió el tipo MIME)

Debido a esto, ahora siento que la forma más adecuada para la versión es a través del URI, pero acepto que no es la forma "correcta".


46
2017-10-13 10:51



Pon tu versión en el URI. Una versión de una API no siempre admite los tipos de otra, por lo que el argumento de que los recursos simplemente migran de una versión a otra es simplemente incorrecto. No es lo mismo que cambiar el formato de XML a JSON. Es posible que los tipos no existan o que hayan cambiado semánticamente.

Las versiones son parte de la dirección del recurso. Está enrutando de una API a otra. No es RESTful ocultar el direccionamiento en el encabezado.


21
2018-06-05 15:09



Hay algunos lugares donde puedes hacer versiones en una API REST:

  1. Como se señaló, en el URI. Esto puede ser tratable e incluso estéticamente agradable si se usan bien los redireccionamientos y similares.

  2. En el encabezado Acepta: para que la versión esté en el tipo de archivo. Como 'mp3' vs 'mp4'. Esto también funcionará, aunque IMO funciona un poco menos bien que ...

  3. En el recurso en sí. Muchos formatos de archivo tienen sus números de versión incrustados en ellos, generalmente en el encabezado; esto permite que el software más reciente 'simplemente funcione' mediante la comprensión de todas las versiones existentes del tipo de archivo, mientras que el software anterior puede puntualizar si se especifica una versión no compatible (más reciente). En el contexto de una API REST, significa que sus URI nunca tienen que cambiar, solo su respuesta a la versión particular de los datos que le entregaron.

Puedo ver razones para usar los tres enfoques:

  1. si te gusta hacer nuevas API de "barrido limpio", o para cambios de versiones principales en los que desees tal enfoque.
  2. si quiere que el cliente lo sepa antes de hacer un PUT / POST, ya sea que funcione o no.
  3. si está bien si el cliente tiene que hacer su PUT / POST para averiguar si va a funcionar.

13
2017-10-24 16:39



La versión de su API REST es análoga a la versión de cualquier otra API. Se pueden realizar cambios menores en su lugar, los cambios importantes pueden requerir una API completamente nueva. Lo más fácil para usted es comenzar desde cero cada vez, que es cuando poner la versión en la URL tiene más sentido. Si desea hacer la vida más fácil para el cliente, intente mantener la compatibilidad con versiones anteriores, lo que puede hacer con deprecation (redirección permanente), recursos en varias versiones, etc. Esto es más complicado y requiere más esfuerzo. Pero también es lo que REST fomenta en "Los URI geniales no cambian".

Al final es como cualquier otro diseño de API. Pesar el esfuerzo contra la conveniencia del cliente. Considere la posibilidad de adoptar versiones semánticas para su API, lo que deja en claro para sus clientes qué tan compatible es su nueva versión.


8
2018-03-06 07:16