Как сделать версию REST URI - PullRequest
104 голосов
/ 10 июня 2009

Каков наилучший способ версии REST URI? В настоящее время у нас есть версия # в самом URI, то есть.

http://example.com/users/v4/1234/

для версии 4 этого представления.

Версия принадлежит к queryString? то есть.

http://example.com/users/1234?version=4

Или версионирование лучше всего выполнить другим способом?

Ответы [ 11 ]

191 голосов
/ 10 июня 2009

Не указывайте версии URL, потому что ...

  • вы нарушаете постоянные ссылки
  • Изменения в URL будут распространяться, как болезнь, через ваш интерфейс. Что вы делаете с представлениями, которые не изменились, но указывают на представление, которое изменилось? Если вы измените URL, вы сломаете старых клиентов. Если вы оставите URL-адрес, ваши новые клиенты могут не работать.
  • Версионные типы носителей - гораздо более гибкое решение.

Предполагая, что ваш ресурс возвращает какой-то вариант application / vnd.yourcompany.user + xml, все, что вам нужно сделать, - это создать поддержку для нового типа носителя application / vnd.yourcompany.userV2 + xml и с помощью магии согласования контента Ваши клиенты v1 и v2 могут мирно сосуществовать.

В интерфейсе RESTful наиболее близким к контракту является определение типов мультимедиа, которыми обмениваются клиент и сервер.

URL-адреса, которые клиент использует для взаимодействия с сервером, должны предоставляться сервером, встроенным в ранее полученные представления. Единственный URL-адрес, который должен знать клиент, - это корневой URL-адрес интерфейса. Добавление номеров версий в URL имеет смысл только в том случае, если вы создаете URL-адреса на клиенте, чего не следует делать с интерфейсом RESTful.

Если вам нужно изменить типы мультимедиа, которые сломают существующих клиентов, создайте нового и оставьте свои URL-адреса в покое!

И для тех читателей, которые в настоящее время говорят, что это не имеет смысла, если я использую application / xml и application / json в качестве медиа-типов. Как мы должны их версии? Вы не. Эти типы мультимедиа в значительной степени бесполезны для интерфейса RESTful, если вы не анализируете их с помощью загрузки кода, и на этом этапе версионирование является спорным вопросом.

30 голосов
/ 10 июня 2009

Я бы сказал, что лучше сделать его частью самого URI (вариант 1), поскольку v4 идентифицирует ресурс, отличный от v3. Параметры запроса, как во втором варианте, лучше всего использовать для передачи дополнительной информации (запроса), связанной с запросом , а не ресурсом .

21 голосов
/ 11 июня 2009

Ах, я снова надеваю свою старую сварливую шляпу.

С точки зрения ReST это не имеет значения вообще. Не колбаса.

Клиент получает URI, которому он хочет следовать, и обрабатывает его как непрозрачную строку. Положите в него все, что хотите, у клиента есть нет знаний о такой вещи, как идентификатор версии.

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

Но в любом случае клиент может обрабатывать документ только в том формате, который он понимает, и переходить по ссылкам в нем. Нужно знать о связи связей (переходов). Так что то, что в URI, совершенно не имеет значения.

Я бы лично проголосовал за http://localhost/3f3405d5-5984-4683-bf26-aca186d21c04

Совершенно действительный идентификатор, который не позволит дальнейшим разработчикам клиентов или лицам, касающимся системы, задаться вопросом, следует ли ставить v4 в начале или в конце URI (и я полагаю, что с точки зрения сервера вы не должны 4 версии, но 4 типа носителей).

11 голосов
/ 19 июля 2011

Вы НЕ должны указывать версию в URL, вы должны указать версию в заголовке Accept запроса - см. Мой пост в этой теме:

Рекомендации по управлению версиями API?

Если вы начнете вставлять версии в URL, вы получите глупые URL, как это: http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

И есть еще куча других проблем - смотрите мой блог: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

5 голосов
/ 10 июня 2009

Эти (менее конкретные) SO вопросы о версии REST API могут быть полезны:

2 голосов
/ 17 ноября 2013

Я хотел создать версионные API и нашел эту статью очень полезной:

http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

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

2 голосов
/ 13 ноября 2013

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

К сожалению, это решение работает только для API на основе аутентификации. Тем не менее, он хранит версии вне URI.

1 голос
/ 18 сентября 2018

Существует 4 различных подхода к управлению версиями API:

  • Добавление версии в путь URI:

    http://example.com/api/v1/foo
    
    http://example.com/api/v2/foo
    

    Если у вас есть критические изменения, вы должны увеличить версию, например: v1, v2, v3 ...

    Вы можете реализовать контроллер в своем коде так:

    @RestController
    public class FooVersioningController {
    
    @GetMapping("v1/foo")
    public FooV1 fooV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping("v2/foo")
    public FooV2 fooV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Запрос версии параметра:

    http://example.com/api/v2/foo/param?version=1
    http://example.com/api/v2/foo/param?version=2
    

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

    Реализация может быть похожа на это:

    @GetMapping(value = "/foo/param", params = "version=1")
    public FooV1 paramV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/param", params = "version=2")
    public FooV2 paramV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Передача пользовательского заголовка:

    http://localhost:8080/foo/produces
    

    С заголовком:

    headers[Accept=application/vnd.company.app-v1+json]
    

    или

    headers[Accept=application/vnd.company.app-v2+json]
    

    Самым большим преимуществом этой схемы является в основном семантика: вы не загромождаете URI чем-либо связанным с управлением версиями.

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

    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v1+json")
    public FooV1 producesV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v2+json")
    public FooV2 producesV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Изменение имен хостов или использование шлюзов API:

    По сути, вы перемещаете API с одного имени хоста на другое. Вы можете даже назвать это здание новым API для тех же ресурсов.

    Кроме того, вы можете сделать это с помощью API-шлюзов.

1 голос
/ 23 мая 2014

Если вы используете URI для управления версиями, тогда номер версии должен быть в URI корня API, поэтому его может включать каждый идентификатор ресурса.

Технически API REST не нарушается при изменении URL (результат ограничения унифицированного интерфейса). Он прерывается только тогда, когда связанная семантика (например, специфичный для API RDF-словарь) изменяется не обратно совместимым способом (редко). В настоящее время многие пользователи не используют ссылки для навигации (ограничение HATEOAS) и вокабу для аннотирования своих ответов REST (самоописательное ограничение сообщений), поэтому их клиенты ломаются.

Пользовательские типы MIME и управление версиями типов MIME не помогают, потому что помещение связанных метаданных и структуры представления в короткую строку не работает. Ofc. метаданные и структура часто меняются, поэтому номер версии тоже ...

Таким образом, чтобы ответить на ваш вопрос, лучше всего аннотировать ваши запросы и ответы с помощью вокабсов ( Hydra , связанных данных ) и забыть о версиях или использовать их только при несовместимых обратно изменениях вокаба (например, если вы хотите заменить вокаб другим).

1 голос
/ 10 июня 2009

Я бы включил версию в качестве необязательного значения в конце URI. Это может быть суффикс типа / V4 или параметр запроса, который вы описали. Вы можете даже перенаправить / V4 на параметр запроса, чтобы поддерживать оба варианта.

...