2010-03-04 10 views
8

Estoy creando una API que pretendo actualizar con el tiempo. ¿Es razonable incluir un número de versión como argumento en la API?¿Debe una API tener números de versión en ella?

Estoy escribiendo una API de clave/valor de tienda en Ruby, Java, Erlang y C#. Quiero construir algo que sea extensible, ya que sé que hay muchas cosas en las que aún no he pensado que pueden tener que incorporarse en el futuro. Sin embargo, quiero saber si hay una forma clara de hacerlo y si los números de versión también forman parte de esto.

+0

Eso depende. Por favor, danos más información sobre lo que debes hacer y por qué. –

+0

¿Quiere decir que las personas llaman a su API de la siguiente manera 'api-> FetchMagicData (3);' donde 3 es la versión de su API que quieren usar? –

+0

@Dominic. Podrías ampliar un poco lo que dijiste, no entendí del todo – Zubair

Respuesta

7

Usted puede hacerlo, es mejor (en mi humilde opinión) si usted acaba de hacer compatibles con versiones anteriores de su API sin embargo. En general, es más fácil, ya que no necesita ramificarse de su lado, según el número de versión, simplemente vuelve a implementar el método dado.

Supongo que es realmente bastante específico de la implementación (y también específico del entorno). Haría lo que pareciera más fácil/mejor.

Yo diría que siempre y cuando se mantenga la compatibilidad con versiones anteriores en de alguna manera, entonces todo está bien.

+0

Esto suena muy sensato, manteniendo la compatibilidad con versiones anteriores. Así que tal vez usar números de versión es un tipo de olor anti/patrón o código – Zubair

+0

¿Por qué tiene que ser una opción de "versión" o "no versión, mantener compatibilidad hacia atrás" - versionar LE PERMITE mantener compatibilidad hacia atrás al saber lo que espera un cliente en función de su número de versión. Si no usa el control de versiones, lo que escriba tendrá que quedarse para siempre, si lo cambia, romperá todos los clientes. Los desarrolladores no son perfectos, los enfoques y los requisitos cambian. El control de versiones le permite ser flexible a ese cambio. –

+0

Supongo que no sabía si era una opción de "versión" o "no versión", pero si es posible, creo que es mejor no versionar, ya que siempre quiero que la gente pueda usar la última versión de la API. – Zubair

2

Sí, tomemos por ejemplo Google Maps:

<script type="text/javascript"> 
    google.load("maps", "2"); 
</script> 
+0

¿Google hace esto porque no es compatible con versiones anteriores? – Zubair

3

En primer lugar, ¿qué tipo de API quieres decir? ¿Una biblioteca con la que se vinculan las aplicaciones o una API XML/RPC? Voy a suponer lo último en mi respuesta.

Definitivamente, es la única forma en que su API y/o el cliente pueden distinguir qué métodos/parámetros están disponibles para ellos. También le permite continuar atendiendo clientes antiguos con una nueva versión de la API.

Algo que he encontrado funciona bien en el pasado, es tener algún tipo de método de handshake, donde el cliente le dice al servidor qué versión está esperando. A continuación, el servidor responde con su versión actual y puede optar por no admitir ese cliente (lo que le permite eliminar una versión anterior y luego dejar de admitirla más adelante).

As para una biblioteca, definitivamente debe incluir un número de versión para que las aplicaciones puedan vincularse con diferentes versiones, y puede continuar usando una versión anterior, incluso si existe una versión más nueva hasta que la aplicación se haya actualizado para manejar la nueva versión.

+0

Una API con la que las aplicaciones se vinculan, creo. – Zubair

+0

Entonces definitivamente sí. Hay momentos en los que es deseable cambiar una interfaz porque las necesidades de la biblioteca han cambiado. Significando un salto importante en el número de versión le permite hacer esto, mientras mantiene aplicaciones previas (ya que enlazan con la versión anterior de la biblioteca). La forma de hacer UNIX (soname) es un buen ejemplo. –

+0

Pero necesito algo que funcione en todos los idiomas y sistemas operativos. Tal vez lo malentendí? – Zubair

5

Eso podría ser razonable si está construyendo una API orientada a objetos y le da el número de versión a una fábrica. También es común en las API centradas en datos dinámicos: usted solicita datos a la biblioteca y tiene que indicar a qué formato/versión desea que sean devueltos los datos.

Más comúnmente para bibliotecas "tradicionales" (. Como en los que enlace en su C/C++/NET) hecho es:

  • proporcionan una API para buscar el número de versión de la biblioteca . Esto permite que la aplicación decida si necesita una versión más nueva/más antigua de la biblioteca.

  • ser compatible con versiones anteriores siempre que sea posible.

  • Agregue funciones, no las cambie. Si tiene que agregar argumentos/entrada o cambiar el comportamiento, cree una función nueva y mantenga la anterior.

  • cuando finalmente tenga que romper la compatibilidad con versiones anteriores y deshacerse de todas las piezas antiguas mantenidas solo por el bien de ser compatibles con versiones anteriores, tenga un esquema de versiones en buen estado que indique claramente versiones incompatibles.

+0

pero si agrega funciones ¿no complica los nombres de las funciones? – Zubair

+2

Sí, pero ser compatible con versiones anteriores suele ser más importante. – nos

+1

Sí, ya veo. La compatibilidad con versiones anteriores es lo más importante para mí. – Zubair

3

En primer lugar, es difícil ser específico sin saber para qué idioma es su API.

Creo que sería aceptable permitir un número de versión para la creación de un objeto. Para que pueda crear un objeto de la versión 1 o la versión 2 MyApi, con diferentes versiones del Objeto con diferentes métodos. Todavía debería ser posible crear la versión 1 obejcts con la versión 2 API para que los usuarios de la biblioteca puedan actualizarse gradualmente.

No creo que deba tener números de versión en métodos o llamadas a funciones. Para mí, esto parece agregar un texto repetitivo a cada llamada a su API. En este caso, considere usar cualquiera de los parámetros opcionales para que pueda extender sin romper la compatibilidad hacia atrás y desaprobar métodos cuando sea necesario.

+0

Una API, cuatro idiomas: Ruby, Java, Erlang y C#. – Zubair

2

Sí, es muy sensato, especialmente si está utilizando un sistema basado en clasificación/desasignación e interfaces (COM/CORBA/SOAP). Incluso es útil en aplicaciones monolíticas.

Sin embargo, este enfoque es adecuado para proyectos de software muy complicados, y si no lo necesita, no lo use; puede encerrarse en una versión interminable: infierno.

edición: Es posible que desee ver en Apache Thrift (escasamente documentado) para el intercambio de datos, o Protocol Buffers (menos idiomas)

+0

Por "complicado" ¿te refieres a un gran sistema SOA compuesto de muchas aplicaciones diferentes, por ejemplo, donde diferentes sistemas están usando diferentes versiones de una API? – Zubair

+0

sí, eso sería un ejemplo de complicado. –

5

He usado varias API que apoyan algún tipo de control de versiones, sobre todo ODBC . Ninguna de estas versiones permitido a nivel llamada a la API - que todo lo que se requiere para contar la biblioteca de la versión que quería trabajar con sobre una base de una sola vez - algo así como:

MyAPI::UseVesion(2, 1); 

Personalmente, yo evitaría este camino de ser posible (haga que sus nuevas API sean compatibles con versiones anteriores) y que el control de versiones en el nivel de llamada individual sea intolerable e inviable. Imagínese un código como:

MyAPI::Handle h = MyAPI::GeHandle(2, 1); // get 2.1 version of handle 
MyAPI::UseHandle(3, 0, h);     // use it somehow with a 3.0 function 

No se puede detectar la falta de coincidencia en tiempo de compilación, y puede o no puede trabajar en tiempo de ejecución. Yechh!

+0

Creo que lo explicaste bien, Neil.Realmente puedo ver ahora cómo una API versionada será horrible para todos sus usuarios – Zubair

+0

Excelente descripción, Neil! Traté de decir lo mismo, pero tu ejemplo lo hace mucho más claro. –

3

Sí, permitir números de versión en API es razonable, pero limitaría pasarlos a un único método en un MetaAPI, mediante el cual el usuario de su API recupera una versión particular del mismo.

Para cada versión, utilice una interfaz diferente y nunca la cambie una vez que se haya liberado.

Esto hace que la compatibilidad con versiones anteriores sea mucho más fácil.

1

Una cosa que querrá hacer es proporcionar funciones que tomen números de versión y les den sentido.Las funciones como:

def has_extended_key_format(version): 
    return version > 3 

o:

#define HAS_EXTENDED_KEY_FORMAT(version) ((version) > 3) 

(. Sí, utilizar #define para C y C++, por lo que el preprocesador puede hacer cosas dependiendo de la versión en tiempo de compilación)

De esta manera, su código no está cargado con números mágicos en sus comprobaciones de versión, y las personas pueden leer su código y saber qué función realmente está buscando.

+0

Mis pensamientos exactamente. Esto parece una solución bastante limpia. –

Cuestiones relacionadas