В последнее время из-за потребностей бизнеса облачный продукт CSB, в исследованиях и разработках которого я участвовал, должен открыть открытый API для внешнего мира, что несложно, потому что открытый механизм открытого API внутри Alibaba Cloud очень зрелый, и я не вообще не нужно проектировать его, но на этот раз спрос в основном на некоторые независимые сценарии развертывания, и вам нужно разработать набор спецификаций, что означает, что вам нужно сделать некоторые спецификации и ограничения на Open API, так что есть эта статья.
Open API, как и front-end страница, всегда были лицом продукта, а Open API не стандартизирован, что снизит профессионализм продукта. В облачном сценарии многие пользователи предпочтут создавать свои собственные порталы для стыковки Open API облачных продуктов, что побуждает нас создавать зрелый механизм Open API.
С точки зрения бизнеса есть несколько руководящих принципов, которые помогут нам улучшить механизм Open API:
- Интерфейс, используемый интерфейсной страницей, и интерфейс, предоставляемый Open API, представляют собой один и тот же набор интерфейсов.
- Любой внешний интерфейс страницы должен иметь соответствующий Open API.
С технической точки зрения существует множество стандартов OPEN API для нашей справки, и документация по Open API для некоторых продуктов с открытым исходным кодом также очень полная. С одной стороны, я возьму его суть, с другой стороны, я должен учитывать особенности формы выпуска собственного продукта. В этой статье мы сосредоточимся на ряде факторов, чтобы попытаться изучить подходящую спецификацию открытого API.
Рекомендации по проектированию открытого API
Что именно должна регулировать хорошо зарекомендовавшая себя спецификация Open API?
С точки зрения дизайна необходимо учитывать: спецификацию именования, спецификацию композиции, спецификацию пути, спецификацию параметра доступа, спецификацию типа данных, спецификацию унифицированного возвращаемого значения, спецификацию кода ошибки, спецификацию разбиения на страницы.
С точки зрения команды, достаточно ли у команды основной и промежуточной разработки, а также передних исследований и разработок опыта для понимания и реализации сформулированных спецификаций API. В то же время, с потоком людей, эта спецификация Open API может быть хорошо передана.
С точки зрения отрасли необходимо учитывать, является ли рынок, на котором продукт, предоставляющий Open API, зрелым, и может ли стиль API уже иметь соответствующие спецификации.
С точки зрения продукта каждый продукт соответствует своему стилю API, и эта точка зрения будет выделена ниже.
Короче говоря, с дизайном открытых API сложно договориться, и прежде чем я представлю спецификации Open API, которые в конечном итоге будут приняты моими продуктами, я сначала расскажу о некоторых знакомых концепциях, таких как restful.
Спокойная нормальная битва
Где есть люди, там будут реки и озера.
То же самое верно, когда есть код.
Если вы находитесь в цикле кодирования, вы слышали о спокойной спецификации:
-
Добавления, удаления и исправления должны быть объявлены как: POST, DELETE, PUT, PATCH, GET.
-
Глаголы не должны появляться, и они единообразно представлены методами http.
-
Воплощает абстракцию «ресурсов»
-
Используйте pathVariable, queryParam, header, statusCode, чтобы выразить большую часть бизнес-семантики.
Успокаивающая спецификация может показаться красивой, но если вы действительно пробовали приземляться, вы обязательно столкнетесь с некоторыми похожими проблемами:
- Взяв в качестве примера интерфейс входа пользователя, такой интерфейс трудно сопоставить с добавлением, удалением, модификацией и модификацией ресурсов.
- Взяв в качестве примера частоту ошибок запроса интерфейса за последние 7 часов запроса, полученную из сложных сценариев запросов, таких как graphQL, часто требуется структура json, GET не может достичь этого, можно передать только POST
Исходя из этого, у restful спецификации постепенно появляются возражения:
- Принуждение всего к «ресурсному» противоречит здравому смыслу разработки, и интерфейс может быть не в состоянии отображаться простыми добавлениями, удалениями и исправлениями.
- Семантика сложного запроса не может быть выражена в GET
У поклонников спокойного стиля нет недостатка в критике этих возражений, и в сообществе неизбежно появляются заявления о том, что «основные люди, которые отвергают спокойный стиль, — это низкоуровневые непредприимчивые архитекторы и фронтенд-программисты, которые не будут проектировать как человеческая проблема, а не нормативная проблема» и так далее. При этом restful сублимируется: задача извлечения сложных параметров должна быть классифицирована как post в семантике restful, потому что поведение — это не позиционирование ресурса (GET), а извлечение ресурса (POST)
Это, видимо, раздражало нервы противников спокойного стиля, пренебрежительно: О, тупые умиротворенные фундаменталисты.
Не знаете, вы сторонник или противник отдыха? Или нейтрально.
Спор об отдыхе на этом пока заканчивается, и этот спор чисто фиктивный, и чиновникам не о чем беспокоиться. Что бы вы ни думали об отдыхе, как я расскажу ниже, вы можете быть нейтральным, иначе эффект уменьшится вдвое.
ROA против RPC
Дизайн API — это не только спокойная спецификация, в более широкой перспективе основной стиль дизайна API можно разделить на
- Проект, ориентированный на ресурсы, известный как ROA (архитектура, ориентированная на ресурсы).
- Процессно-ориентированный дизайн, т.е. RPC (удаленный вызов процедур)
Restful является типичным примером стиля roA, а стиль RPC относительно менее известен, но на самом деле большая часть системного интерфейса выполнена в стиле RPC, но концепция стиля RPC менее известна.
Возьмите CRUD пользовательского модуля в качестве примера, сравните следующие два стиля:
ROA-стиль
Создать пользователя (POST)
Request:
POST /users{"name": "kirito", "age": 18}
Response:
HTTP 201 Created
{"id": 1, "name": "kirito", "age": 18}
Запрос пользователя (GET)
Request:
GET /users/1
Response:
HTTP 200 OK
{"id": 1, "name": "kirito", "age": 18}
Запрос списка пользователей (GET)
Request:
GET /usersResponse:HTTP 200 OK{[{"id": 1, "name": "kirito", "age": 18}], "next": "/users?offset=1"}
Создать/изменить пользователя (PUT)
Request:
PUT /users/1
{"name": "kirito", "age": 19}
Response:
HTTP 200 OK
{"id": 1, "name": "kirito", "age": 19}
Изменить пользователя (PATCH)
Request:
PATCH /users/1
{"age": 20}
Response:
HTTP 200 OK
{"id": 1, "name": "kirito", "age": 20}
Удалить пользователя
Request:
DELETE /users/1
Response:HTTP 204 No Content
Стиль ROA и спецификации restful иллюстрируют одно и то же, и для облегчения сравнения с интерфейсом в стиле RPC приведем некоторые примечательные моменты приведенного выше примера:
- Используя коды ответа HTTP (200, 201, 204), сопоставление семантики HTTP и бизнес-семантики завершено, и поток исключений также отображается 404, 401 и т. д. (из соображений экономии места в этой статье поток исключений не представлен).
- Раздел PATCH изменяет ресурс, а тело запроса является содержимым измененного раздела; PUT создает/изменяет ресурс, а тело запроса представляет собой все содержимое нового ресурса.
- id — это локатор ресурса, а age, name — атрибуты
Стиль RPC
Создать пользователя (POST)
Request:
POST /user/createUser{"name": "kirito", "age": 18}
Response:
HTTP 200 OK
{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 18}}
Запрос пользователя (POST)
Request:
POST /user/getUser{"id": 1}
Response:
HTTP 200 OK
{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 18}}
Запрос списка пользователей (POST)
Request:
POST /user/listUsersResponse:HTTP 200 OK{"code": 0, "message": "", "data": {"user": [{"id": 1, "name": "kirito", "age": 18}], "next": "/user/listUsers?offset=1"}}
Изменить пользователя (POST)
Request:
POST /user/modifyUser{"id": 1, "name": "kirito", "age": 19}
Response:
HTTP 200 OK
{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 19}}
Изменить имя пользователя (POST)
Request:
POST /user/modifyUserAge{"id": 1, "age": 20}
Response:
HTTP 200 OK
{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 20}}
Удалить пользователя
Request:
POST /user/deleteUser{"id": 1}
Response:
{"code": 0, "message": ""}
Стиль RPC не похож на стиль RESTFUL ROA, здесь есть какие-то общепринятые нормы, каждая бизнес-система в лендинге, есть отличия, поэтому здесь только личный опыт автора, надеюсь, читатели смогут найти точки соприкосновения, сохраняя при этом различия:
- user — это имя модуля, и его не нужно использовать во множественном числе, как в стиле ROA.
- Вместо сопоставления CRUD с http-методами HTTP-методы единообразно используют POST, а сценарии запросов также могут использовать GET.
- Возвращаемое значение содержит код, сообщение и данные для сопоставления статуса ответа и информации об ответе, как правило, вы можете определить код состояния кода самостоятельно, в этой статье используется 0 для определения успеха запроса, сообщение имеет смысл только тогда, когда бизнес ответ терпит неудачу, и данные представляют собой результат бизнес-ответа
Выбор RPC и ROA требует решений, основанных на бизнес-ситуации самого продукта. Существуют следующие рекомендации:
- API со сложной бизнес-логикой в стиле RPC следует использовать, когда нельзя использовать простые добавления, удаления, изменения и описания.
- Если ваш бизнес является частью отраслевого стандарта, который требует API в спокойном стиле или ROA для удовлетворения потребностей вашего бизнеса, вам следует использовать стиль ROA.
AWS в основном использует стиль RPC, Azure и Google в основном используют стиль ROA (спокойный), а Alibaba Cloud OpenAPI поддерживает как RPC, так и ROA, в основном RPC.
Хоть норма и невинная, но я видел много «ям» в стиле ROA на практике:
- Требовать ресурсов, чтобы идти в первую очередь, то есть сначала проектировать ресурсы, а затем проектировать интерфейсы, что требует более высоких требований к процессу разработки программного обеспечения.
- Неправильный случай проектирования ROA 1: когда сервер приложений, такой как tomcat, обрабатывает HTTP-запрос для метода DELETE, ему по умолчанию не разрешено передавать тело запроса, и его необходимо явно включить, что приводит к сбою удаления. (Этот случай - проблема дизайнера, сложная сцена удаления не должна отображаться на DELELE, а должна быть изменена на POST, DELETE не должна нести тело запроса)
- Вариант 2 неправильного проектирования ROA: параметры, передаваемые по остаточному пути, могут вызывать регулярные проблемы сопоставления, такие как ошибочное использование почтового ящика в качестве параметра пути или конфликтная проблема с многоуровневым сопоставлением путей (в этом случае проблема разработчика, сложный сценарий запроса, не должен сопоставляться с GET, но должен быть изменен на POST, путь должен отображаться только в локаторе ресурсов, а не в атрибуте)
- С кодом ответа 404 трудно различить, существует ли реальный путь или не существует ресурса.
- Это не подходит для таких сценариев, как стыковочные шлюзы, требующие настройки переадресации маршрутов.
Спецификация CSB Open API должна соответствовать следующим требованиям:
- Когда интерфейс проектирования внутренней разработки имеет четкую идею дизайна, а не из-за того, реализован ли интерфейс с помощью POST или GET, и не тратится слишком много времени на абстракцию ресурсов (это не означает, что ресурсы делают не надо проектировать)
- Когда клиентская часть разрабатывает интерфейс стыковки, она может относительно быстро взаимодействовать с серверной частью и способствует инкапсуляции внешнего интерфейса.
- Когда пользователи подключаются к Open API, общий стиль остается неизменным, а модули понятны.
Подводя итог, с точки зрения выбора стиля дизайна я планирую принять спецификации дизайна RPC. Подводя итог преимуществам стиля RPC:
- Дизайн API менее сложен и прост в посадке
- Большинство зрелых продуктов уровня IAAS от Alibaba Cloud используют спецификацию RPC.
- Подходит для сложных бизнес-сценариев
Подробный пример документации интерфейса RPC
Создать сервис
Параметры запроса
Требуется UpstreamType=fixed, пример: [{"host": "1.1.1.1", "port": "80", "weight": "1"}]
Требуется имя в реестре, upstreamType=discovery
серийный номер | Название китайское поле | Английское название поля | тип данных | необходимые | иллюстрировать |
---|---|---|---|---|---|
1 | имя | имя | string | be | Изменения имен |
2 | соглашение | протокол | string | be | Значение перечисления: http/grpc/webservice |
3 | Балансировка нагрузки | lb | string | be | Значение перечисления: случайный/циклический |
4 | Тип восходящего потока | upstreamType | string | be | Значение перечисления: фиксированное/обнаружение |
5 | Список узлов | узлы | массив | не | |
6 | Идентификатор источника | идентификатор происхождения | string | не | |
7 | Название сервиса | наименование услуги | string | не | |
8 | Описание услуг | описание | string | не | |
9 | Идентификатор шлюза | идентификатор шлюза | string | be |
Возвращает параметр
серийный номер | Название китайское поле | Английское название поля | тип данных | иллюстрировать |
---|---|---|---|---|
1 | Код ответа | код | Int | 0 Отмечено как успешное; 1 Идентификация не удалась |
2 | Информация об ответе | сообщение | string | |
3 | Результаты ответа | дата | string | Возвращает идентификатор службы |
Запросить пример
POST /service/createService
Request:{"name": "httpbin",
"protocol": "http",
"lb": "random",
"upstreamType": "fixed",
"nodes": [
{"host": "httpbin.org",
"port": "80",
"weight": "1"
}],"gatewayId": "gw-1qw2e3e4"
}Response:{"code": 0,
"message": "",
"serviceId": "s-1qw2e3e4"
}
Соглашения об именах API
-
API-интерфейсы должны использовать орфографический английский язык и соответствовать грамматическим спецификациям, включая единственное и множественное число, время и языковые соглашения.
-
У вас не может быть нескольких API с одинаковым значением, но без практических различий в функциональности, таких как /user/getUser и /user/describeUser.
-
Языковые привычки: использование пиньинь запрещено.
-
Исправлены соглашения об именах для следующих распространенных сценариев.
- Параметры типа datetime должны называться xxxxTime. Например: время создания
-
Спецификация общего имени операции
- создать: создать
- изменить: изменить
- удалить: Удалить
- get: получить подробную информацию об одном ресурсе
- list: Получает список ресурсов
- installRelation: установить ресурсные отношения
- destroyRelation: уничтожить отношения ресурсов
резюме
Возьмем в качестве примера спецификацию, отстаиваемую в этой статье: «Все интерфейсы используют POST», что не для размещения низкоуровневых непредприимчивых архитекторов и фронтенд-программистов (я видел на форуме сообщества), а для повышения эффективности разработки, сокращения коммуникации расходы, сократить затраты на эксплуатацию и техническое обслуживание и затраты на неправильное позиционирование, а также инвестировать затраты на слепое отбрасывание в другие области, такие как проектирование бизнес-архитектуры, системы тестирования, онлайн-мониторинг, аварийное восстановление и понижение версии.
Спецификация интерфейса — это не то, что я резюмировал, только RPC и ROA, есть некоторые замечания, которые классифицируют GraphQL как отдельный стиль проектирования API для сложных сценариев запросов, заинтересованные студенты могут обратиться к документации API es.
Таким образом, я планирую принять стиль дизайна API RPC.
Оставьте комментарий