Основная цель написания этой статьи — обобщить и отсортировать мой многолетний опыт разработки RESTful API и, кстати, поделиться им с вами.
Чтобы лучше объяснить некоторые проблемы дизайна и точки внимания, эта статья будет объяснена на одном и том же примере от начала до конца. Конечно, этот пример представляет собой программную систему с архитектурой yy REST. Давайте просто назовем его GoodHR, и адрес этой системыwww.goodhr.com(Любое сходство чисто случайно).
Проще говоря, RESTful API на самом деле представляет собой протокол http, основанный на веб-среде в соответствии с концепцией проектирования архитектуры системы REST для описания интерфейса системы. Поэтому весь дизайн RESTful API в основном делится на две основные части, описывающие URI ресурса (ресурса) и метод работы с ресурсом (метод).
Статья будет разделена на три основные части: 1) Для практики проектирования Uri (UNIFORM Resource Identifier); 2) Для практики проектирования метода, здесь я просто поместил наиболее распространенные способы (POST, PUT, GET и УДАЛИТЬ) Описание; 3) Для некоторых специальных сцен, например, Restful API, который поддерживает сложные возможности Query/Search, поддерживает асинхронную обработку RESTful API и т.д., СЛУЧАЙНО.
URI-дизайн
В дизайне RESTful API основная цель состоит в том, чтобы сделать весь интерфейс более самоописываемым, чтобы повысить производительность с точки зрения простоты использования и удобства обслуживания интерфейса.
URI ресурса — это просто стандарт описания, используемый для поиска ресурса в веб-среде. URI ресурса RESTful API обычно состоит из двух частей: Path и Query Parameters, Позвольте мне представить и объяснить их соответственно.
Path
В основном он описывает путь доступа к ресурсу, а путь обычно состоит из существительных.
В дизайне RESTful API содержимое пути также включает параметр пути, то есть часть динамического параметра.Например, если у нас есть путь, указывающий на конкретный объект ресурса компании, у нас будет следующий дизайн пути
http://www.goodhr.com/api/v1/companies/{公司id}
Здесь {идентификатор компании} — это параметр пути, который можно заменить конкретным значением идентификатора, чтобы указать, какой объект ресурса компании. Параметр пути представлен в концепции дизайна URI всего API RESTful.Обязательный параметрТо есть значение Path Parameter должно отдавать, иначе вы не сможете использовать RESTful API, либо API будет иметь доступ к другой ситуации.
На самом деле, несмотря на разные сценарии, в дизайне Path есть разные практики, я перечислю наиболее часто используемые ниже:
1. Набор объектов ресурсов
Если оно используется для описания ресурса (совокупности ресурсов), оно должно быть выражено во множественном числе, как в следующем примере:
http://www.goodhr.com/api/v1/companies/66/employees
2. Отдельные объекты ресурсов
Если он используется для описания ресурса, то ресурс должен иметь уникальный идентификатор для идентификации ресурса, как в следующем примере:
http://www.goodhr.com/api/v1/companies/66/employees/{员工id}
3. Ресурсная принадлежность
Отношения подчиненного ресурса, например, сотрудники будут подчинены компании, тогда дизайн этого uri должен быть выражен следующим образом:
http://www.goodhr.com/api/v1/companies/66/employees/1001
Другая функция этого способа выражения состоит в том, чтобы представить сильную зависимость от жизненного цикла ее ресурсов, Короче говоря, если компания удалена, то сотрудники ниже нее не должны быть доступны или изменены.
4. Отношение индекса ресурса
Ресурсы с индексируемыми отношениями. Например, сотрудник может присоединиться к нескольким отделам в компании. Тогда отношения между отделами и сотрудниками не являются отношениями строгой подчиненности.
http://www.goodhr.com/api/v1/companies/66/departments/{部门id}/employees
Приведенное выше выражение на самом деле не сильно отличается от uri ресурса отношения принадлежности, но оно описывает группу сотрудников в определенном отделе путем добавления пути на уровне отделов.
Query Parameter
Параметр запроса относится к параметру "ключ-значение", который появляется после вопросительного знака (?) в URI. В дизайне RSETful API он фактически обеспечиваетнеобязательный параметрРоль - не будет доступа к другим ресурсам, и это не приведет к тому, что этот API не будет выполняться. Например, нам нужно получить все объекты ресурсов сотрудников компании, тогда наш API можно оформить следующим образом:
http://www.goodhr.com/api/v1/companies/66/employees?pageStart=1&pageSize=100
Тогда pageStart и pageSize, показанные выше, на самом деле являются параметрами запроса, которые используются в качестве параметров для перелистывания страниц. Если при реализации этого RESTful API должна быть реализована логика по умолчанию для случаев, когда pageStart или pageSize отсутствуют. Здесь мы обычно говорим, что когда pageStart не указан, мы по умолчанию начинаем с 1. Если pageSize не указан, мы используем размер страницы по умолчанию, например: 20.
дизайн метода
Наиболее часто используемые методы операций с ресурсами в RESTful API — это POST, PUT, GET и DELETE. Ниже я подробно объясню, как разработать каждый метод.
В официальной спецификации протокола http методы GET, PUT и DELETE являются идемпотентными, а POST — нет.
1. Метод POST
Метод POST представляет собой создание нового ресурса для ресурса, описанного uri. Метод POST может содержать тело запроса, а тело RESTful API обычно использует тип JSON. Тип возвращаемого значения метода POST обычно имеет формат JSON, а код состояния HTTP должен быть 201 (создано).
Обычно существует два сценария определения POST RESTful API:
1. Идентификатор ресурса не определен
Если идентификатор ресурса, который вы хотите создать, распространяется сервером, то в целом URI должен соответствоватьнабор ресурсовстиль дизайна. Например, создайте нового сотрудника со следующим URI
http://www.goodhr.com/api/v1/companies/66/employees
тело запроса
{
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumber": "1234567890123456789"
}
вернуть результат
{
"companyId": 66,
"id": 1001,
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumberMask": "123************789",
"creationTime": "2019-01-01 09:00:01",
"updatedTime": "2019-01-01 09:00:01"
}
Здесь значение поля «id» распределяется сервером при создании записи сотрудника.
2. Идентификатор ресурса может быть определен
Бывает ситуация, когда вы заранее определяете ID создаваемого ресурса, и его не нужно раздавать серверу при его создании. Тогда в этом случае URI должен быть такимотдельный ресурсстиль дизайна.
Например, создайте новый отдел со следующим URI
http://www.goodhr.com/api/v1/companies/66/departments/dept-acct
тело запроса
{
"name": "财会",
"introduction": "公司的财务部门"
}
вернуть результат
{
"companyId": 66,
"code": "dept-acct",
"name": "财会",
"introduction": "公司的财务部门"
"creationTime": "2019-01-01 09:00:01"
}
метод PUT
Проще говоря, метод PUT обычно используется для обновления информационного элемента, связанного с ресурсом.Согласно спецификации http, PUT должен быть идемпотентной операцией.Поэтому в дизайне интерфейса PUT информация о ресурсе должна быть полностью обновлено, а не частичное обновление. Здесь мы используем сотрудников в качестве примера:
URI должен соответствоватьотдельный ресурсстиль дизайна, а возвращаемый код состояния http должен быть 200 в случае успеха
1. Свойства объекта ресурса относительно просты
Вообще говоря, информация об атрибутах, содержащаяся в некоторых объектах ресурсов, относительно проста, и в этом случае можно использовать стандартный PUT RESTful API для разработки, например, обновления информации о сотрудниках:
http://www.goodhr.com/api/v1/companies/66/employees/1001
Структура тела запроса здесь заключается в обновлении полного объема информации о сотруднике (ниже) вместо частичного обновления тела запроса.
{
"firstname": "Kevin",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2018-03-01",
"socialSecurityNumber": "1234567890123456789"
}
вернуть результат
{
"companyId": 66,
"id": 1001,
"firstname": "Kevin",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2018-03-01",
"socialSecurityNumberMask": "123************789",
"creationTime": "2019-01-01 09:00:01",
"updatedTime": "2019-01-05 14:56:12"
}
2. Ресурсные объекты имеют много свойств
Иногда у нас будет сценарий, когда ресурс содержит много атрибутов, и эти атрибуты классифицируются по некоторым типам. Например, в объекте ресурса компании будет основная информация, налоговая информация и информация о совете, бизнес-статус и т. д. ., то в этом случае, если мы используем RESTful API для выполнения полных обновлений, на самом деле, будь то из-за простоты использования этого API или управления разрешениями на доступ к ресурсам в будущем, есть определенные проблемы. В этом случае я бы разработал API таким образом, предоставив отдельные URI для разных типов атрибутов, как показано ниже:
Основная информация о компании
http://www.goodhr.com/api/v1/companies/66/profile
Компания налоговая информация
http://www.goodhr.com/api/v1/companies/66/tax-info
Совет директоров компании
http://www.goodhr.com/api/v1/companies/66/executive-info
Бизнес-статус компании
http://www.goodhr.com/api/v1/companies/66/status
УДАЛИТЬ метод
Этот метод, как следует из названия, предназначен для удаления ресурсов, и сам этот метод является идемпотентным, поэтому правило реализации этого интерфейса заключается в том, чтобы удалить существующий ресурс в первый раз или удалить ресурс, который больше не существует. , он должен быть возвращен.Тот же результат - код состояния = 204 для http.
1. Удалить отдельные ресурсы
URI должен соответствоватьотдельный ресурсСтиль оформления не требует отдавать тело сообщения запроса.Например удаляем сотрудника.
http://www.goodhr.com/api/v1/companies/66/employees/1001
Есть два способа вернуть сообщение: 1. Вернуть пустое содержимое, но код состояния http — 204. 2. Может быть возвращен результат, и его содержимое может содержать идентификатор ключа удаленного сотрудника, например, идентификатор компании и 1001 в указанном выше URI.
{
"companyId": 66,
"employeeId": 1001
}
2. Удалить пакет ресурсов
На самом деле такая ситуация встречается не часто, но возможны сценарии применения.Например, для удаления всех записей о сотрудниках, уволившихся из компании более 3 лет, этот URI может использовать следующие стили оформления:
http://www.goodhr.com/api/v1/companies/66/employees/_resigned-exceed-years/3
«_resigned-exceed-years» — это условие обновления для набора ресурсов сотрудников, а следующие 3 — это значение этого условия обновления.
Здесь я предлагаю указать возвращаемое значение, основная функция которого состоит в том, чтобы сообщить о результате этого удаления следующим образом:
{
"companyId": 66,
"numberOfDeletedEmployees": 132
}
GET
Сценарий использования этого метода прост для понимания, то есть для получения ресурсов, однако в процессе реальной практики я обнаружил, что сценарий, с которым сталкивается метод GET, является самым сложным. Например, сложные многокритериальные поиски.
1. Получите один ресурсный объект
Получить указанный объект ресурса, например, получить сотрудника с заданным идентификатором сотрудника
http://www.goodhr.com/api/v1/companies/66/employees/1001
возвращаемое значение
{
"companyId": 66,
"id": 1001,
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumberMask": "123************789",
"creationTime": "2019-01-01 09:00:01",
"updatedTime": "2019-01-01 09:00:01"
}
2. Получите набор объектов ресурса
Например, получить всех сотрудников в компании
http://www.goodhr.com/api/v1/companies/66/employees?pageStart=1&pageSize=100&orderBy=creationTime&order=DESC
Для проектирования возвращаемых данных набора ресурсов необходимо добавить слой полей для лучшего представления набора данных и отображения набора данных, полученных по каким условиям.Дизайн может учитывать следующие методы:
{
"queryConditions": {},
"pagination": {
"pageStart": 1,
"pageSize": 100,
"sorting": {
"orderBy": "creationTime",
"order": "DESC"
}
},
"data": {
"size": 100,
"records": [
{
"companyId": 66,
"id": 1001,
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumberMask": "123************789",
"creationTime": "2019-01-01 09:00:01",
"updatedTime": "2019-01-01 09:00:01"
}
...
]
}
}
При выполнении операции по приобретению по отношению к набору объектов ресурсов, содержащие максимально возможное, при получении информации параметров, используемой в возвращенном объекте, таких как вышеупомянутое, включающее в себя запросы, используемые для представления приема ресурсов, когда состояние поиска нет , он пуст, вкладка «Пагибинация» для объяснения данных внутри информационных ресурсов и включает в себя не только поля данных набора записей, возвращаемых ресурса, дополнительно включающими, как размер фактических записей, чтобы увеличить простоту использования интерфейс.
3. Получите объект набора ресурсов, выполнив поиск
Предоставление возможности поиска ресурсов на самом деле является общей возможностью во многих системах.Например, имя сотрудника может быть получено путем поиска по имени или комбинации различных условий, таких как имя плюс возраст и т.д. В дизайне этого RESTful API, если используется метод GET, самая большая проблема заключается в том, что сам GET не может предоставить тело запроса, поэтому он обычно поддерживается в форме параметра запроса.
Например, мы хотим найти сотрудников, чье имя Стив и которым меньше 60 лет, и вернуть их в порядке, обратном времени ввода:
http://www.goodhr.com/api/v1/companies/66/employees?firstname=Steve&age=%3C60
pageStart=1&pageSize=100&orderBy=hiredDate&order=DESC
{
"queryConditions": {
"firstname":"steve",
"age": "<60"
},
"pagination": {
"pageStart": 1,
"pageSize": 100,
"sorting": {
"orderBy": "creationTime",
"order": "DESC"
}
},
"data": {
"size": 13,
"records": [
{
"companyId": 66,
"id": 1001,
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumberMask": "123************789",
"creationTime": "2019-01-01 09:00:01",
"updatedTime": "2019-01-01 09:00:01"
}
...
]
}
}
Многие на самом деле боятся использовать GET для сложного поиска, потому что будут проблемы с ограничением длины URL.Однако по стандарту http в пределах 2048 символов проблем нет.Поэтому общая система предоставляет возможности поиска для ресурсов должно хватить. Конечно, мы не можем отрицать, что на самом деле некоторые сложные сценарии поиска всё же существуют, и если это так, то вы можете увидеть введение некоторых практик проектирования для специальных сценариев в следующих трёх частях.
специальная сцена
Основываясь на теории 2/8, вы можете понять, что практика проектирования в двух вышеупомянутых частях URI и метода охватывает 80% сценариев, и в этой части я уделяю больше внимания этим 20% сложных сценариев. , То, что я обобщил, — это только ситуации, с которыми я столкнулся при разработке RESTful API для систем в разных отраслях за последние 10 лет, а не все ситуации, поэтому, если вы обнаружите, что описанные мной сценарии не охватывают ваш, вы можете выбрать частный напишите мне, мы можем обсудить, как разработать вместе :).
1. Супер сложный поиск
В редких случаях довольно часто предоставляется такой чрезмерно сложный поисковый RESTful API. При этом, если оформление вести по стандартному методу GET+параметры запроса, то фактически будет возможность превышения стандартной длины url, поэтому в особых случаях мы можем только с ними бороться Вообще говоря, вместо этого мы будем использовать метод POST, а затем поместим критерии поиска в тело запроса и предоставим их в виде json.
Например, нам нужно найти запись об отпуске сотрудника:
http://www.goodhr.com/api/v1/companies/66/timeoff-records?pageStart=1&pageSize=100&orderBy=creationTime&order=DESC
Используйте метод POST для отправки информации о критериях поиска:
{
"type": [
"vocation",
"sick"
],
"appliedDateRange": {
"startDate": "2019-01-01",
"endDate": null
},
"departments":[
"dept-acct",
"dept-tech",
"dept-marketing"
]
}
возвращаемый объект
{
"queryConditions": {
"type": [
"vocation",
"sick"
],
"appliedDateRange": {
"startDate": "2019-06-01",
"endDate": null
},
"departments":[
"dept-acct",
"dept-tech",
"dept-marketing"
]
},
"pagination": {
"pageStart": 1,
"pageSize": 100,
"sorting": {
"orderBy": "creationTime",
"order": "DESC"
}
},
"data": {
"size": 13,
"records": [
{
"companyId": 66,
"id": 10293,
"applicantId": 1002,
"applicationDateTime": "2019-01-01 09:00:01",
"approverId": 98,
"type": "vocation",
"timeoffBegin": "2019-06-01 AM",
"timeoffEnd": "2019-06-01 PM",
"creationTime": "2019-01-01 09:00:01",
"updatedTime": "2019-01-01 09:00:01"
}
...
]
}
}
2. Асинхронная обработка
Если необходимо обеспечить, например, резервное копирование данных, формирование результатов отчетов, сложные вычислительные задачи или требуется ручная обработка, обычно используется асинхронная обработка.При разработке RESTful API используются так называемые асинхронный и асинхронный API в системе не очень. То же самое, что это не асинхронное решение на основе потоков, а больше то, что запрос обрабатывается через RESTful API, а результат обработки запроса нужно получать через другой API. Есть два способа спроектировать эту асинхронную обработку, о которых я расскажу отдельно ниже.
а. Разделение исполнения и приобретения
Проще говоря, этот стиль дизайна заключается в том, что вам нужно активировать API A, чтобы создать задачу запроса процесса, а затем получить результаты через API B. Например, нам нужно сформировать, пожалуйста, добавить статистические отчеты по всем сотрудникам:
Первый RESTful API, который мы используем для создания и генерации отчетов, здесь мы используем метод POST, потому что при каждом вызове этого интерфейса будет создаваться новая задача генерации отчета
http://www.goodhr.com/api/v1/companies/66/statistics/timeoff
тело запроса
{
"contentType": "excel",
"dateRange": {
"startDate": "2018-01-01",
"endDate": "2018-12-31",
}
}
возвращаемый объект
{
"jobId": "timeoff-100202",
"creationTime": "2019-01-01 09:00:01",
"contentType": "excel",
"dateRange": {
"startDate": "2018-01-01",
"endDate": "2018-12-31",
}
}
Здесь jobId используется для получения результата этой задачи асинхронной обработки из второго API.
Второй RESTful API используется для получения этого статистического отчета, здесь мы используем метод GET.
http://www.goodhr.com/api/v1/companies/66/statistics/timeoff/{jobId}
возвращаемый объект
{
"jobId": "timeoff-100202",
"creationTime": "2019-01-01 09:00:01",
"status": "finished",
"retrivalLocation": "https://static.goodhr.com/reports/timeoff-100202.xls"
}
Конечно, также возможно, что отчет все еще создается.В этом случае статус возвращенного объекта может быть «Обработка», а retrievalLocaiton — null.
б. Активный толчок завершен
Сравнение между этой схемой проектирования и схемой а состоит в том, что схема а — это способ тянуть, чтобы получить результат, а эта схема — способ подтолкнуть. Если RESTful API, который создает приведенный выше отчет о времени ожидания, разработан таким образом, общая конструкция будет иметь некоторую сложность.Конечно, преимущество заключается в том, что метод принудительной разработки снизит системную нагрузку на систему.
В этой схеме проектирования нам нужно только предоставить RESTful API первого POST в a, чтобы выполнить ту же задачу по созданию отчета, и тело запроса не изменится, а поле «callbackUrl» необходимо добавить к возвращаемому объекта следующим образом:
{
"jobId": "timeoff-100202",
"creationTime": "2019-01-01 09:00:01",
"callbackUrl": "https://another-system.somewhere.com/receive-reports/timeoff",
"contentType": "excel",
"dateRange": {
"startDate": "2018-01-01",
"endDate": "2018-12-31",
}
}
CallbackUrl здесь на самом деле является дизайном веб-перехватчика.Для веб-перехватчика, если это внутренняя система, рекомендуется просто добавить проверку белого списка узлов, а если это SaaS Open API для предоставления возможностей расширения третьим сторонам, то это Дополнительные функции управления веб-перехватчиком встроены для обеспечения достаточной безопасности, например, междоменных атак или перехвата запросов.
3. Супермультипольный ресурсный объект
Иногда некоторые объекты ресурсов содержат очень много свойств, десятки, а то и сотни сотен, и в этот раз мы получаем этот ресурс через RESTFUL API, если просто получить объект ресурса, который определяется по ID, то это еще приемлемо Однако, если это набор объектов ресурсов, будут генерироваться ненужные потери, будь то системные или сетевые издержки.
Для разработки связанного RESTful API этого ресурса рассмотрите возможность предоставления параметра запроса в структуре его URI, чтобы сообщить серверу, какие атрибуты ресурса необходимо вернуть, например, для доступа к ресурсам компании.
http://www.goodhr.com/api/v1/companies/66?fields={属性类型}
Значение полей здесь может быть предоставлено в соответствии с классификацией атрибутов объекта компании.Например, добавление налоговой информации означает, что необходимо вернуть налоговую информацию, а добавление исполнительной информации означает, что необходимо вернуть управленческую информацию. Конечно, если поля не указаны, у нас должна быть логика возврата содержимого по умолчанию, например, возвращать основную информацию о компании в качестве возвращаемого атрибута по умолчанию.
Надежность полей в этой схеме дизайна предпочтительно является атрибутом, а не атрибутом, так что будет относительно хороший баланс между читабельностью кода и сложностью и гибкостью реализации кода на стороне сервера. нужно, чтобы вызывающая сторона этого интерфейса давала каждому конкретному имени свойство, тогда это будет катастрофа.
4. Схема идемпотентной операции
Дизайн этого RESTful API на самом деле очень прост.Как правило, параметр запроса предоставляется в URI для представления идентификатора транзакции, что позволяет вам постоянно безопасно повторять транзакцию.
Предположим, что мы создаем систему для логики записей работников, включая взаимодействие и обновление данных и других систем, то нам нужно преобразовать предыдущий пример, он создал метод Post Contricteee Records, разрешается поддерживать такие операции, как мощность.
http://www.goodhr.com/api/v1/companies/66/employees
тело запроса
{
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumber": "1234567890123456789"
}
Здесь мы добавляем поле transactionId к возвращаемому результату, которое используется для представления транзакции этого запроса на создание.
вернуть результат
{
"transactionId": "e721ac103ckc910ck20c",
...
}
Если в процессе создания возникает исключение (код состояния, отличный от 204), что приводит к сбою создания записи о сотруднике, вы можете добавить этот идентификатор транзакции во вторую попытку, чтобы убедиться, что сервер может реализовать идемпотентную операцию следующим образом:
http://www.goodhr.com/api/v1/companies/66/employees?transactionId=e721ac103ckc910ck20c
последний из последних
Вот несколько основных практических принципов проектирования, которые, как мне кажется, полезны не только для RESTful API, но и для разработки системных API.
Скажи, не спрашивай принцип
Этот принцип в основном подчеркивает, что каждый интерфейс должен иметь возможность выполнять всю бизнес-логику, а не объединять несколько интерфейсов для завершения бизнес-логики вызывающей стороной.
Например, при создании записи о сотруднике вам необходимо вызвать системный интерфейс правительства, чтобы проверить его SIN (номер социального страхования), тогда лучший способ реализовать это — иметь интерфейс записи о сотруднике для завершения всех проверок SIN за один раз. время проверки и создания записи, как указано ниже,
good
POST: http://www.goodhr.com/api/v1/companies/66/employees
тело запроса
{
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumber": "1234567890123456789"
}
Наоборот, иногда кто-то будет разделять эти две логики на два независимых интерфейса для предоставления, что станет следующим эффектом
bad
Подтвердить номер социального страхования
GET: http://www.goodhr.com/api/v1/sin-record/1234567890123456789
Создание записей о сотрудниках
POST: http://www.goodhr.com/api/v1/companies/66/employees
тело запроса
{
"firstname": "Steve",
"lastname": "Bill",
"birthDate": "1982-01-01",
"gender": "male",
"hiredDate": "2019-01-01",
"socialSecurityNumber": "1234567890123456789"
"sinVerfiied": true
}
Версия
Должно быть управление версиями, которое не только легко поддерживать, но и облегчает обновление и рефакторинг вашей системы.
В RESTful API практический способ версии — добавить информацию о версии в Path в uri.
http://www.goodhr.com/api/v{版本号}
Часть номера версии может быть числом или любым другим значением, которое вы хотите.Например, некоторые будут использовать дату, такую как 20190101.
Эта статья была отправлена на мой публичный аккаунт WeChat "Jingjiti". Если вы считаете, что моя статья полезна, обратите внимание :)