Развитие API за счет использования системы управления версиями

Пользовательские соединители для Azure Logic Apps, Microsoft Power Automate или Microsoft Power Apps должны предоставлять файл спецификации OpenAPI. В этой спецификации OpenAPI определяются отдельные точки входа, т. е. операции. Каждая операция имеет уникальный operationId, а также уникальное сочетание urlPath и HttpVerb.

{
    "/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems"
        },
        "post": {
            "summary": "Insert row",
            "description": "This operation inserts an item.",
            "operationId": "PostItem"
        }
    }
}

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

Но многие изменения могут действительно нарушать контракт, описанный в спецификации OpenAPI. Удаление параметров, больше не поддерживающих определенные входные данные, или изменение значения и поведения входных, выходных данных или самой операции подпадает под категорию "критическое изменение".

Чтобы безопасно развивать API, важно следовать шаблону, который можно применять между клиентами. API отвечает за обратную совместимость, передачу намерений и обозначение атрибутов управления версиями. Клиент отвечает за отображение или скрытие тех операций, которые устарели, срок действия которых истек или у которых могут быть новые версии. Таким образом, операции могут увеличиваться и развиваться с течением времени, не вызывая значительную уязвимость для приложений, которые их используют.

Аннотация API

OpenAPI изначально не поддерживает управление версиями операций. Для нашей цели большая часть работы выполняется с использованием объекта x-ms-api-annotation, который применяется как глобально, так и в области операции. Глобальный объект содержит свойства, которые применяются к API в целом:

{
    "x-ms-api-annotation": {
        "status": "Preview"
    }
}
Свойство Значения По умолчанию Описание
статус "Preview" "Production" "Preview" Состояние API в целом — начиная с Preview (Предварительная версия) и до изменения на Production (Производство) по мере использования и в зависимости от стабильности.

В области операции этот объект содержит более подробные свойства. Есть также дополнительные свойства за пределами объекта. Они применяются и участвуют в процессе эволюционного управления версиями:

{
    "deprecated": true,
    "x-ms-api-annotation": {
        "status": "Production",
        "family": "MyOperation",
        "revision": 2
    }
}
Свойство Values По умолчанию. Описание
устарело null false true false Указывает, устарела ли операция.
x-ms-visibility null "" "Important" "Advanced" "Internal" "" Предполагаемая видимость и значимость этой операции, где null или "" подразумевает состояние Normal.
статус "Preview" "Production" "Production" Состояние операции,—которое может отличаться от состояния самого API, но если не указано, будет наследоваться от состояния API верхнего уровня.
семейство {общее имя операции} operationName Имя, которое применяется к каждой версии этой операции
версия цифры (1,2,3...) 1 Версия указанного семейства операций
срок действия истекает Дата ISO8601 (нет) Дополнительная подсказка клиенту о планируемом времени окончания поддержки

Свойству нерекомендуемый можно задать значение true, если клиентам нежелательно использовать эту операцию. Это свойство есть в спецификации фиксированных полей OpenAPI.

Свойство видимость — это индикатор предполагаемой относительной значимости операции. Видимость "Important" указывает, что операция должна находиться ближе к началу списка, т. е. отображаться как значимая. Видимость normal (со значением null или пустой строкой "") — значение по умолчанию, которое означает, что скорее всего, операция будет отображаться в списке после операций Important. Видимость "Advanced" указывает, что операция может находиться внизу списка или даже быть изначально скрыта за элементом управления expando. Значение Advanced может быть у операций, которые труднее использовать, которые менее популярны или у которых небольшая область применения. Видимость "Internal" указывает, что операция не должна предоставляться пользователям и предназначена только для внутреннего использования. Операции Internal важны и служат для программных целей, но не предназначены для пользователей. Для операций можно также отмечать значение Internal, чтобы скрывать их в любом пользовательском интерфейсе при объявлении устаревшими, но не удалять из API, что в противном случае стало бы критическим изменением.

Свойство status обозначает стабильность работы API или операции. Значение "Preview" указывает, что операция или API являются новыми и, возможно, непроверенными. Preview — показатель того, что на рабочие среды следует обратить внимание и учесть зависимости. Когда операция или API станут более устоявшимися и будет проверено их соответствие стандартам надежности, показателей успешного выполнения и масштабируемости, можно будет преднамеренно указать состояние "Production".

Требования к метрикам, указанные ниже, обычно применяются к операциям, которые ищут состояние "Production":

  • 80% успешных попыток в течение трех недель
    • процент кодов HTTP-ответов в диапазоне 2xx;
  • 99,9% надежности в течение трех недель:
    • процент кодов HTTP-ответов в диапазоне, отличном от 5xx (502, 504 и 520 исключаются из этого расчета).

Свойство family указывает на связь между операциями, которые в общем представляют собой разные версии одной операции с потенциально критическими изменениями. У нескольких операций будет общее имя семейства, если их следует рассматривать как версии друг друга и они упорядочены по уникальным номерам версий.

Свойство revision указывает на эволюционный порядок операции в семействе операций. У каждой операции в семействе будет версия — целочисленный указатель последовательности. Пустая строка свойства версии будет считаться версией 1. При появлении новых версий операции клиенты должны более точно указывать их значимость и преимущества, но по-прежнему должны предусматривать выбор потенциально старых версий, которые еще не устарели.

Истекает — это необязательное свойство. Оно указывает возможное время окончания жизненного цикла, когда поддержка операции больше не гарантируется. Это свойство следует задавать только для устаревших операций, и оно не показывается ни в одном интерфейсе.

Время жизни операции

У операций прогнозируемое время жизни, что показано в примере ниже.

Начальная точка

Изначально не всегда указываются версии операций. К таким операциям применяются значения по умолчанию, поэтому они рассматриваются как версия 1 в имени семейства, что соответствует идентификатору operationId.

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems"
        }
    }
}

Это эквивалентно более явному определению:

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems",
            "deprecated": false,
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 1
            }
        }
    }
}

Инициация операций

Большинство шагов по развитию API заключается в добавлении операции, например новых методов и новых версий существующих методов. Чтобы безопасно инициировать новую версию, необходимо изменить спецификацию OpenAPI следующим образом:

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows (V1 - downplayed)",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems",
            "deprecated": false,
            "x-ms-visibility": "advanced",
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 1
            }
        }
    }
    "/v2/{list}/items": {
        "get": {
            "summary": "Get rows (V2 - new hotness)",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems_V2",
            "deprecated": false,
            "x-ms-api-annotation": {
                "status": "Preview",
                "family": "GetItems",
                "revision": 2
            }
        }
    }
}

Важно!

Обратите внимание, что у операции GetItems версии 2 есть уникальный идентификатор operationId, и она изначально указана с состоянием Preview. Обратите также внимание, что у операции GetItems версии 1 теперь видимость Advanced, поэтому она будет отображаться соответствующим образом.

Устаревшая операция

Иногда существующие точки входа версии 1 остаются бессрочно, если представляют ценность и нет особой причины для их устранения. Но многие точки входа версии 2 намеренно заменяют точки версии 1. Чтобы сделать это было безопасно, весь трафик исходной операции должен быть условно равен нулю. Когда это подтвердится в данных телеметрии, можно внести следующие изменения:

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows (deprecated)",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems",
            "deprecated": true,
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 1
            }
        }
    }
    "/v2/{list}/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems_V2",
            "deprecated": false,
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 2
            }
        }
    }
}

Важно!

Обратите внимание, что операция GetItems версии 1 теперь отмечена как deprecated. Это последний переход для устаревших операций. Теперь операции GetItems версии 2 полностью заменила GetItems версии 1.

Зачем это нужно?

Есть множество причин использовать управление версиями операций. Прежде всего, это гарантирует, что такие клиенты, как Azure Logic Apps и Power Automate, будут и далее работать правильно, когда пользователи интегрируют операции соединителя в потоки данных. Для операций следует указывать версии, используя метод выше, когда:

  • добавляете новую версию операции;
  • существующая операция добавляет или удаляет параметры;
  • существующая операция существенно изменяет входные или выходные данные.

Меры предосторожности

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

  • Добавляется новая операция.

    Это не нарушает контракты с существующими клиентами.

  • В существующую операцию добавляется новый необязательный параметр.

    Это не нарушает существующие вызовы, но следует соблюдать осторожность.

  • Существующая операция незначительно изменяет поведение.

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

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

Предоставление отзывов

Для нас очень важны отзывы о проблемах с нашей платформой соединителей и новые идеи о функциях. Чтобы оставить отзыв, выберите пункт Сообщить о проблемах или получить помощь с соединителями и выберите тип отзыва.