Я работаю над REST API. Ключевыми объектами ( "существительные" ) являются "элементы", и каждый элемент имеет уникальный идентификатор. Например. для получения информации об элементе с идентификатором foo:
GET http://api.example.com/v1/item/foo
Новые элементы могут быть созданы, но клиент не может выбрать идентификатор. Вместо этого клиент отправляет некоторую информацию, которая представляет этот элемент. Итак, чтобы создать новый элемент:
POST http://api.example.com/v1/item/
hello=world&hokey=pokey
С помощью этой команды сервер проверяет, есть ли у нас элемент для информации hello=world&hokey=pokey
. Итак, здесь есть два случая.
Случай 1: элемент не существует; он создан. Этот случай прост.
201 Created
Location: http://api.example.com/v1/item/bar
Случай 2: элемент уже существует. Здесь, где я борюсь... не знаю, какой лучший код перенаправления использовать.
301 Moved Permanently
? 302 Found
? 303 See Other
? <Удаp > 307 Temporary Redirect
Забастовкa > Location: http://api.example.com/v1/item/foo
Я изучил описания Википедии и RFC 2616, и ни один из них не кажется идеальным. Вот конкретные характеристики, которые я ищу в этом случае:
Перенаправление является постоянным, так как идентификатор никогда не изменится. Таким образом, для эффективности клиент может и должен делать все будущие запросы на конечную точку ID напрямую. Это предполагает 301, так как остальные три должны быть временными.
Редирект должен использовать GET, хотя этот запрос является POST. Это предлагает 303, так как все остальные технически предполагается повторно использовать метод POST. На практике браузеры будут использовать GET для 301 и 302, но это REST API, а не веб-сайт, предназначенный для обычного пользователя в браузерах.
Он должен быть широко используемым и простым в использовании. В частности, 303 - это HTTP/1.1, тогда как 301 и 302 - HTTP/1.0. Я не уверен, насколько это проблема.
В этот момент я склоняюсь к 303 только для того, чтобы быть семантически правильным (используйте GET, не возвращайте POST) и просто сосать его на "временную" часть. Но я не уверен, что 302 будет лучше, поскольку на практике это было такое же поведение, как 303, но без HTTP/1.1. Но если я схожу с этой линии, то я задаюсь вопросом, является ли 301 еще лучше по той же причине плюс "постоянная" часть.
Мысли оценили!
Изменить: Позвольте мне лучше объяснить семантику этой операции "получить или создать" с более конкретным примером: сокращение URL. Это все равно гораздо ближе к моему приложению.
Для сокращений URL наиболее распространенной операцией является получение по идентификатору. Например. для http://bit.ly/4Agih5, бит .ly получает идентификатор 4Agih5 и должен перенаправить пользователя на соответствующий URL-адрес.
bit.ly уже имеет API, но это не действительно RESTful. Для примера позвольте мне составить более RESTful API. Например, запрос ID может возвращать всю информацию об этом (например, аналитика):
GET http://api.bit.ly/item/4Agih5
Теперь, если я хочу отправить новый URL-адрес в bit.ly, чтобы сократить, я не знаю ID моего URL-адреса заранее, поэтому я не могу использовать PUT. Вместо этого я бы использовал POST.
POST http://api.bit.ly/item/
url=http://stackoverflow.com/
(но закодирован)
Если bit.ly ранее не видел этот URL, он создаст для него новый идентификатор и перенаправит меня через 201 Создан для нового идентификатора. Но если он увидит этот URL-адрес, он все равно перенаправит меня без внесения изменений. Таким образом, я могу попасть в это место перенаправления, чтобы получить информацию/метаданные по сокращенному URL.
Как и этот пример сокращения URL-адресов, в моем приложении столкновения не имеют значения. Один URL-адрес сопоставляется с одним ID и что он. Поэтому не имеет значения, был ли URL укорочен раньше или нет; в любом случае, имеет смысл указать клиенту идентификатор для него, нужно ли сначала создать этот идентификатор или нет.
Поэтому я, вероятно, не буду менять этот подход; Я просто спрашиваю о лучшем методе перенаправления для него. Спасибо!