Управление версиями API веб-сервисов

Я предлагаю небольшой API веб-сервисов для своих клиентов, которые я планирую развивать с течением времени. Поэтому мне нужно какое-то управление версиями, но я не могу найти никакой информации о том, как вы делаете что-то подобное.

Есть ли наилучшая практика?

Как я могу продолжать добавлять новые функции, не нарушая совместимость с пользователями веб-сервисов?

Ответы

Ответ 1

Версии - сложная тема, поэтому сначала вам нужно определить свои цели более наглядным образом. Было бы здорово сказать, что у вас есть интерфейс, гарантирующий, что вы никогда не нарушите совместимость, но в зависимости от того, что такое новая функциональность, это может быть даже невозможно. Таким образом, существуют разные ситуации и разные компромиссы.

Если вы намерены только предоставлять новые функции новым пользователям, а все ваши потребители являются прямыми потребителями (без посредников, фреймворков и т.д.), тогда выбор на основе дискретных конечных точек - лучший выбор. Каждый раз, когда вы добавляете функцию, которая рискует перерывом, создайте новую конечную точку, дайте ей новый номер версии, а затем пусть потребители узнают, чтобы проверить ее и переключить их конфигурации. Эта стратегия довольно испробована и верна, но у нее есть недостатки в том, чтобы возлагать нагрузку на потребителей на постоянную актуальность. Кроме того, если есть зависимости между службами, это может стать основной задачей для отслеживания. Воспроизведение вверх, если код нарушает его (напрямую) вашу ошибку.

Другой основной стратегией является расширяемый интерфейс. Здесь я знаю три разных сорта. Во-первых, это тип интерфейса, который так хорошо описывает домен службы, что каждая возможная функция, которую вы могли бы добавить, каким-то образом возможна с учетом существующего интерфейса. Если это звучит сложно, это так. Вы можете назвать это идеальным интерфейсом. Все полностью описано, но весь домен также полностью описан. "Совершенно" действительно только на бумаге.

Второй сорт - это тип, который выглядит как обычный интерфейс, но добавляет общие точки расширения. В WSDL это означает, что xs: любые, пары имя-значение или что-то подобное. Вы можете назвать это основным расширяемым интерфейсом. Это не слишком сложно сделать, но это не без осложнений. Точки расширения могут затруднить работу интерфейса в определенных инструментах (xs: any) или явно потерять часть вашей способности проверять входы и выходы (пары имя-значение). Также довольно легко злоупотреблять этими точками расширения таким образом, чтобы упростить использование версии 3 или 4.

Третий сорт - это тип, который преобразует ваш интерфейс в байтовый поток. Вы можете назвать эти интерфейсы богов. Они не лишены своих оправданий, но если вы используете их, вы можете спросить, почему вы используете веб-службы вообще. Возможно, вам стоит подумать о необработанном TCP/IP или базовом HTTP GET/POST. Но, может быть, вам надоела сложность WSDL и XSD, и вы просто хотите начать с нуля, но вы привязаны к веб-сервисам по какой-то причине инфраструктуры. Поймите, однако, что, как только вы начнете с этого пути, вам понадобится совершенно новый способ описать вашим потребителям, как/не использовать вашу службу, и если вы используете XSD для этого. Ну, вы в основном назад, где вы начали.

Лучше всего знать все эти варианты и подойти к дизайну сервиса, сначала попробовав "идеальный интерфейс", а затем откажитесь от добавления и добавьте общие точки расширяемости. Попытка разработать идеальный интерфейс заставит вас научиться вещам, которые улучшат вашу услугу, а не только ваш интерфейс, но для этого потребуется время, и если вы не ограничите это время, это будет навсегда.

Немного меньше интерфейса реального бога, есть интерфейс оболочки. Если у вас есть слои, вы хотите, чтобы ваш интерфейс тоже был в слоях. Когда вы меняете слой B, вы хотите только изменить слой B, а не все экземпляры в слое C.

Ответ 2

Наиболее распространенной стратегией, которую я видел, является версия WSDL, добавив идентификацию версии (обычно yyyy/MM[/dd]) в пространство имен объектов в wsdl, а именно:

targetNamespace="http://schemas.mycompany.com/2010/01/widgets"

Это можно сделать либо на уровне type (types/schema), либо на всем уровне WSDL - <definitions> в версии 1.1 или <description> в 2.0.

Отчасти устаревший, но эта ссылка от IBM Developer Works дает обоснование для этого подхода, и особенно когда версии нужно увеличивать:

Совместимые/не изменяющиеся изменения в обратном порядке:

  • Добавление новых операций
  • Добавление новых типов

Нарушение изменений:

  • Операции удаления или переименования
  • Изменение параметров для метода
  • Изменение сложного типа

Ответ 3

Обычно я добавляю строку версии к URL-адресу веб-службы, предоставляя мне "конечные точки с версией". Код, реализующий эти конечные точки, может быть разделен, если различия тривиальны и могут обрабатываться одним и тем же кодом, или код может быть клонирован или где-то посередине.

Различные конечные точки с версией также могут использовать версии XML Schemas, если это вам нужно.

Ответ 4

Одна из возможностей заключается в том, чтобы все операции веб-сервиса имели только один параметр типа, который наследуется от некоторого абстрактного типа, который содержит номер версии. Этот подход реализуется платформа веб-сервисов eBay. Что-то вроде следующего:

<xsd:complexType name="AbstractRequestType">
  <xsd:attribute name="version" type="string" />
  ....

<xsd:complexType name="AddCustomerRequestType">
  <xsd:complexContent>
   <xsd:extension base="AbstractRequestType">
   ....

then use AddCustomerRequestType as a type of only parameter 
in addCustomer web service operation.

Кроме того, если вы работаете над http, вам может потребоваться добавить версию в качестве параметра http GET в URL-адрес конечной точки веб-службы, чтобы вы могли легко найти запрошенную версию http://server/service?version=1

Ответ 5

Добавьте "номер версии API" в качестве параметра во всем своем API, а затем примените стратегический шаблон в коде веб-службы, где номер версии определяет, какую стратегию использовать.