Правильный ответ REST для пустой таблицы?


106

Допустим, вы хотите получить список пользователей, вызвав GETк api/users, но в данный момент таблица была обрезана , так что нет пользователей. Каков правильный ответ для этого сценария: 404или 204?


19
Я бы ответил 200 и пустой коллекцией (не пустым телом ответа, а скорее коллекцией без элементов внутри, это будет выглядеть по-разному в зависимости от возвращаемого формата)
toniedzwiedz

4
404 в этом контексте, вероятно, лучше подходит для «таблица не найдена». Я бы сказал, верните пустой список.
mata


2
@EJoshuaS Это не так. Оба вопроса мои и очень старые. Они похожи, но не дублируются.
IMB

1
@EJoshuaS Очевидно, они не дубликаты. Этот вопрос о том, /api/usersа тот о /api/users/1.
Франклин Ю

Ответы:


230

Я бы сказал, ни то, ни другое.

Почему не 404 (не найдено)?

Код состояния 404 следует зарезервировать для ситуаций, в которых ресурс не найден. В этом случае ваш ресурс - это совокупность пользователей . Эта коллекция существует, но в настоящее время она пуста. Лично я, как автор клиента для вашего приложения, был бы очень сбит с толку, если бы получил 200один день и 404другой день только потому, что кто-то случайно удалил пару пользователей. Что я должен сделать? У меня неправильный URL? Кто-то изменил API и забыл оставить перенаправление.

Почему не 204 (без содержания)?

Вот отрывок из описания кода статуса 204 от w3c

Сервер выполнил запрос, но не должен возвращать тело объекта и может захотеть вернуть обновленную метаинформацию.

Хотя в данном случае это может показаться разумным, я думаю, что это также запутает клиентов. 204Предполагается, что символ A указывает на то, что некоторая операция была выполнена успешно и никаких данных возвращать не требуется. Это идеально подходит в качестве ответа на DELETEзапрос или, возможно, запуска какого-то скрипта, которому не нужно возвращать данные. В случае api/users, вы обычно ожидаете получить представление о вашей коллекции пользователей. Отправлять тело ответа один раз и не отправлять его в другой раз - непоследовательно и потенциально вводит в заблуждение.

Почему я бы использовал 200 (ОК)

По причинам, указанным выше (согласованность), я бы вернул представление пустой коллекции. Предположим, вы используете XML. Обычное тело ответа для непустой коллекции пользователей может выглядеть так:

<users>
  <user>
    <id>1</id>
    <name>Tom</name>
  </user>
  <user>
    <id>2</id>
    <name>IMB</name>
  </user>
</users>

и если список пуст, вы можете просто ответить примерно так (при этом все еще используя a 200):

<users/>

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

Вы можете сделать то же самое с JSON, HTML или любым другим форматом, который вы используете.


4
Однозначно согласен. И для отдыха, я бы просто отправить код статуса 200 с пустым массивом: [].
Чад Джонсон

Имеет смысл. Не нужно усложнять. 404 может сбить с толку.
Витольд Качурба

Предположим, API, который описывает монеты в вашем кармане, с конечными точками: GET /singleCoin- возвращает случайную монету из вашего кармана, GET /severalCoins- возвращает несколько монет из вашего кармана, которые вы можете схватить за один раз. Допустим, у вас сейчас нет монет в кармане. Когда вы попросите, GET /singleCoinвы получите 404 Not Found, но когда вы попросите, GET /severalCoinsвы получите 200 OKпустой список []. Один факт - у вас нет монет, описанных разными отзывами, почему? Я бы сказал, что лучше всегда получать 404 Not Found, потому что в кармане нет монет.
sempasha

1
@sempasha Это зависит от того, что вы имеете в виду GET /severalCoins. Если мандат , который GET /severalCoins должен вернуть несколько монет , то это не должно быть 200 , потому что это не в порядке; сервер не смог предоставить то, что хочет клиент. Для /singleCoinэтого, очевидно , потому что клиент не хочет ровно одну монету, не больше, не меньше. Это то же самое для /coins/7. В отличие от /coinsконечной точки, обычно клиенты не ожидают монеты, одной монеты или нескольких монет. Все они верный ответ. Если монеты нет, то они этого хотят. Это похоже на emply List<Coin>в Java вместо null.
Франклин Ю

15

Я бы ответил на один из двух кодов в зависимости от ситуации во время выполнения:

404 Не Найдено)

Этот ответ довольно правильный, если у вас нет таблицы. Не просто пустая таблица, но НЕТ ТАБЛИЦЫ ПОЛЬЗОВАТЕЛЯ. Подтверждает точную идею - ресурса нет. Дополнительные параметры - предоставить более подробную информацию, ПОЧЕМУ ваша таблица отсутствует, есть несколько более подробных кодов, но 404 довольно хорошо подходит для ситуации, когда у вас действительно нет таблицы.

200 (ОК)

Все случаи, когда у вас есть таблица, но она пуста или ваш обработчик запросов отфильтровал все результаты. Это означает: «ваш запрос правильный, все в порядке, но вы не соответствуете никаким данным только потому, что либо у нас нет данных, либо нет данных, соответствующих вашему запросу». Это должно отличаться от ответа об отказе безопасности. Я также голосую за возврат 200 в ситуации, когда у вас есть некоторые данные, и в целом вам разрешен доступ к таблице, но нет доступа ко всем данным, которые соответствуют вашему запросу (данные были отфильтрованы из-за безопасности на уровне объекта, но в целом вам разрешено запрос).


10

Если вы ожидаете список пользовательских объектов, лучшим решением будет возврат пустого списка ([]) с 200 OK, чем использование ответа 404 или 204.


2

определенно возвращает 200.

404 означает, что ресурс не найден. Но ресурс есть. А также, если ответ имеет статус 404. Как узнать, что список пользователей пуст или заполнен?


  • "/ users", если пусто, должно вернуть "200".
  • '/ users / 1', если идентификатор не найден. должен вернуть 404.

2

Должно быть 200 ОК с пустым списком.

Почему: пустая таблица означает, что таблица существует, но в ней нет записей.

404 Not Found означает, что запрошенная конечная точка не существует.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.