Версии API RESTful с XML и JSON Content-Type
В соответствии с эта отличная презентация по разработке интерфейсов RESTful, предпочтительный способ реализации управления версиями - использовать заголовок Accept-header, используя что-то вроде:
GET /products HTTP/1.1
Host: example.com
Accept: application/vnd.com.myservice.v2+xml
Это отлично работает для XML Content-Types, но можно использовать ту же схему для версии JSON-эквивалентного?
I.e, можно ли запросить:
GET /products HTTP/1.1
Host: example.com
Accept: application/vnd.com.myservice.v2+json
Ответ будет выглядеть примерно так:
HTTP/1.1 200 OK
Content-Type: application/vnd.com.myservice.v2+xml; charset=UTF-8
Allow: GET, POST
<?xml version="1.0" encoding="utf-8"?>
<products xmlns="urn:com.example.products"
xmlns:xl="http://www.w3.org/1999/xlink">
<product id="1234" xl:type="simple"
xl:href="#" onclick="location.href='http://example.com/products/1234'; return false;">
<name>Red Stapler</name>
<price currency="EUR">3.14</price>
<availability>false</availability>
</product>
</products>
и эквивалент JSON (вид):
HTTP/1.1 200 OK
Content-Type: application/vnd.com.myservice.v2+json; charset=UTF-8
Allow: GET, POST
[
{
id: "1234",
links: [
{
rel: "self",
href: "http://example.com/products/1234"
}
],
name: "Red Stapler",
price: {
currency: "EUR",
value: 3.14
},
availability: false
}
]
Ответы
Ответ 1
Вы можете реализовать управление версиями, добавив версию в тип контента:
application/vnd.acme.user-v1+xml
Или вы также можете использовать квалификатор в своем заголовке Accept
, таким образом, вы не трогаете свой тип контента:
application/vnd.acme.user+xml;v=1
Вы можете разделить свой тип контента application/vnd.acme.user+xml
на две части: первая (application/vnd.acme.user
) описывает тип носителя, а второй (xml
) - формат ответа. Это означает, что вы можете использовать другой формат, например json
: application/vnd.acme.user+json
.
В мире HATEOAS XML лучше, чем JSON для удобочитаемости и семантических целей, если вы хотите использовать JSON, вас может заинтересовать эта спецификация: https://github.com/kevinswiber/siren.
Ответ 2
Самый чистый способ, который я знаю, - использовать профили. Для этого есть IETF RFC (RFC 6381).
Используя заголовок accept, укажите, какой тип ответа вы ожидаете. Вы также можете использовать квалификаторы. Вы можете запросить соответствие одному или нескольким профилям, разделенным запятыми, но вы должны использовать кавычки, если вы указываете несколько профилей.
Принять: application/json; Профили = "http://profiles.acme.com/user/v/1"
Используя заголовок типа контента, сервер может реагировать одинаково:
Content-Type: application/json; Профили = "http://profiles.acme.com/user/v/1"