LINUX.ORG.RU

Какой код вы используете в REST API для ненайденных ресурсов?

 ,


0

4

Вроде бы рекомендуют не использовать 404, потому что это слишком общий код ошибки:

There are many layers of software that can return 404 to a request, some of which you may have no control over:

Misconfigured client hitting the wrong URL

Misconfigured proxies (client end and server end)

Misconfigured load balancers

Misconfigured routing tables in the server application

Returning HTTP 404 for «thing not found» is almost like returning HTTP 500 - it could mean the thing doesn’t exist, or it could mean something went wrong; the client cannot be sure which.

https://github.com/stickfigure/blog/wiki/How-to-(and-how-not-to)-design-REST-APIs#rule-8-dont-use-404-to-indicate-not-found

Поэтому в проектах используем 410 для обозначения ситуации, когда объект не найден.

Но сегодня столкнулся с проблемой: Safari закешировал ответ 410 на конкретную GET ручку с двумя параметрами, один из которых входит в путь ручки в виде uuid, а второй - необязательная дата после знака “?”.

Проект на fastapi, и для тестирования запросов используется встроенный swagger.

Путь у ручки вот такой: «/{uuid}/test?date_=2025-06-02», где дату можно не указывать по дефолту.

Указываешь дату - запрос корректно работает, а не указываешь - получаешь 410.

В итоге потратил час на отладку, пока не выяснилось, что в хроме ручка в Swagger работает корректно и возвращает результат при пустой дате вместо ошибки 410.

Какие коды для обозначения ненайденных ресурсов вы используете в своих веб-сервисах с REST API и почему?


Вроде бы рекомендуют не использовать 404, потому что это слишком общий код ошибки

Не слушай дурачков, используй 404. 410 тут вообще не к месту.

ox55ff ★★★★★
()
  • 404 не найдено
  • 401 неверный логин или пароль
  • 403 нет прав
  • 200 обычный ответ
  • 206 что-то сделано, но ответ не подразумевается
  • 400 любая ошибка
  • 500-е это ошибки самого nginx и не должны применяться

можешь еще 400-ую использовать. такое много где практикуется

rtxtxtrx ★★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)

Safari закешировал ответ 410

HTTP response status code 410 Gone is a client error that is returned by the server to indicate that the requested resource is permanently unavailable. This is similar to 404 Not Found, although it more specifically indicates that it did exist, but is unavailable and this is expected to be permanent.

LGTM.

anonymous
()
Ответ на: комментарий от rtxtxtrx

стандарты как раз для того и существуют чтобы на них забивать

Точно. Используешь, например, какой-нибудь REST API, а там ошибки с кодом 200, и надо проверять, не пустой ли массив ошибок в JSON body. Дебилы.

anonymous
()
Ответ на: комментарий от rtxtxtrx

Тут 206 на 204 заменить надо.

Молодец. Вот так, мало-помалу, с моей помощью, с визгом и сопротивлением, но все-таки ты когда-нибудь утратишь хвост. Не останавливайся.

thesis ★★★★★
()

The HTTP 410 Gone client error response status code indicates that the target resource is no longer available at the origin server and that this condition is likely to be permanent. A 410 response is cacheable by default.

goingUp ★★★★★
()

Только POST в запросах, только 200 в ответах. Всё, что предполагается быть ошибкой, раскрывается в теле в том формате, который удобен проекту.

Иначе получается, что сначала долго выбираем HTTP-статусы, а потом страдаем с кешами да с браузерами.

anonymous
()
Ответ на: комментарий от anonymous

Только POST в запросах, только 200 в ответах. Всё, что предполагается быть ошибкой, раскрывается в теле в том формате, который удобен проекту.

Это уже далековато от того, чтобы REST называться…

По теме принципом наименьшего удивления 404 самое то. Если интересует подноготная ошибки - можно отдельно запросить GET /error?transactionId=...

necromant ★★
()

Вроде бы рекомендуют не использовать 404, потому что это слишком общий код ошибки:

А что мешает нужную инфу в заголовках передавать вместо натягивания совы на глобус?

Поэтому в проектах используем 410 для обозначения ситуации, когда объект не найден.

Цитату с MDN тебе уже анон привёл, а тебе оттуда же добавлю (может так яснее будет):

A 410 response is cacheable by default.

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от necromant

rest - это не про глаголы (методы) http, а про отсутствие хранения состояния в экземпляре приложения. чтобы картреджечисты, ныне именуемые себя девжопсами, могли с десяток инстансов одного приложения поднять, обеспечив горизонтальное масштабирование, что и позволяет скриптовые языки типа java или php успешно применять в твитторах/фейсбуках.

вопросы про «правильные» статусы из той же серии от незнания основ, истории, отсутствия опыта. rest на глаголах с разными статусами - это лишь один из вариантов, graphql - другой и тп

rtxtxtrx ★★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 2)

Для всех постоянных ошибок использую код 400. Код ошибки (человекочитаеый) возвращаю в теле сообщения.

HTTP 400
Content-Type: text/plain

User not found

Для временных ошибок использую код 500.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от necromant

если у него api,которое все отдает через post-запросы с 200 кодом, то это тоже особо никак не мешает. главное чтобы ошибки хотя бы поле error содержали. там все равно обертку для работы с api писать и все проверять. это просто старый подход, когда через get/post - без разницы все можно было передавать в query string, body, multipart и даже куках (особенности старых версий php). потому начали для получения чего-либо GET использовать, а для остального POST и тело в JSON. потом какой-то умник вылез и заявил, что вы все мудаки, а я д’артаньян и научил использовать PATCH/PUT/DELETE… много чего меняли. Rest и restless разделяли и тп. Всякие JSON API придумывали и пр спецификации. Graphql из которых - это самое лучшее для разработки по аджайлу (без планирования)

rtxtxtrx ★★★
()

Какие коды для обозначения ненайденных ресурсов вы используете в своих веб-сервисах с REST API и почему?

Никакие! Модную ерунду не использую.

firkax ★★★★★
()
Ответ на: комментарий от rtxtxtrx

если у него api,которое все отдает через post-запросы с 200 кодом, то это тоже особо никак не мешает

так я не говорю как делать - я говорю лучше это REST не называть. Работает и ладно, главное чтоб всем понятно и все согласны в команде работать.

главное чтобы ошибки хотя бы поле error содержали

вам возвращаться должен к примеру ресурс/объект user - разве у него должно быть поле error? Если у вас добавляется логика и поле появляется динамически или в ответ на какой-то путь у вас возвращается разный тип объектов, это уже нехорошо имхо.

necromant ★★
()
Ответ на: комментарий от necromant

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

абсолютно неверно.

Никто никому ничего не должен. Ресурс может возвращать:

// Объект user
{
  "id": 123
  "name": "Lox"
}


// Можно с envelop
{
  "user": {
    "id": 123
    "name": "Lox"
  }
}


// Список ресурсов
{
  "page": 2,
  "pages": 3,
  "per_page": 5,
  "results": [User1, User2, ...]
}

// С envelop
{
  "page": 2,
  // ...
  "users": [User1, User2, ...]
}

// Ошибку (объект типа Егоr)
{
  "error": "NotFound",
  "description": "User not found",
}

// Иногда добавляют какое-то бесполезное поле
{
  "success": true,
  // Тут поля ошибки или объекта
  // Иногда могут обернуть
  "data": { /* ... */ },
  // Иногда data и error всегда присутствуют
  "error": null,
}

Стандартов нет. Все делают по аналогии, чтобы не изобретать велосипед. Берут за основу что-то от бигтеха и пародий на него. Ковыряй:


Что надо отметить: так то, что все со временем менялось. Эти «стандарты» идеального API. Изначально все писали на похапе, где ++"42" вполне себе валидный код, поэтому тело запроса могло кодироваться как application/x-www-form-urlencoded. Но в той джаббе на которую многие переползли с пхп, или в питоне, так нельзя. Поэтому тело начали в JSON кодировать, так как он типизированный ({"foo": 42}). Да и всякие фильтры для поиска чего-то тоже делают в JSON типа /api/users?q="{\"age\":{\"gt\":18}}"… А всякие особые статусы и пр извращение — они фактически никому не нужны, это хотелки перфекционистов либо придурков, которые Фаулера начитались и тп. Сделали - хорошо, не сделали - без разницы. Тут читаемость не важна, конечные пользователи не будут эти json’инины редактировать, тут все упирается в хотелки и возможности фронтенда на JavaScript, где JSON — единственный доступный формат из коробки, а чтобы использовать какие-то BSON и тп — JS банально не имеет каких-то «сырых» строк, где каждый символ-байтик (в PHP строки - это набор байт, а на фронте - кодепоинты «юникода»)

rtxtxtrx ★★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 3)
Ответ на: комментарий от necromant

Ты волен делать как угодно. Делать мне больше нечего как еще клиентский код писать.

Вы же в курсе, что миллионы мух не ошибаются, да?

Ага можно не дышать, а то вдруг мухи ошибаются и кислород не нужен

rtxtxtrx ★★★
()
Ответ на: комментарий от rtxtxtrx

картреджечисты, ныне именуемые себя девжопсами

Горением удовлетворен. Сильные эмоции обостряют память, хотя бы пару кодов запомнишь теперь. No pain - no gain, как говорится.

thesis ★★★★★
()
Ответ на: комментарий от rtxtxtrx

Ты волен делать как угодно. Делать мне больше нечего как еще клиентский код писать.

а что так? В чём сложность? 😁😁😁

«Я навалял, а вы гребитесь» in vivo.

necromant ★★
()

Нормальные load balancer'ы и proxy возвращают 502/503/504, если у них неверный URL бекэнда, к которому они не смогли подключиться.

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

Плюс если load balancer будет выдавать 404, он будет выдавать эту ошибку на все эндпойнты, включая те, где 404 мы не ждём (например, авторизация или проверка сессии, где уместнее 401/403 при инвалидных учётных данных). Так что мы заметим, что что-то не так и примем меры.

А 99% времени load balancer настроен корректно, иначе бы сервисом было невозможно пользоваться.

Лично использую 404 для not found и везде где работал использовали его. За игнорирование стандартов коллеги и смежники спасибо не скажут.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 5)
Ответ на: комментарий от vbr

ты прав браузер ничего не кэширует без спроса (кроме днс-запросов). там только гуглобот может после какого-то количества безуспешных попыток посетить страницу, выбросить ее из индекса. но ему срать на статусы эндпоинтов api, он выполняет js, и сохраняет готовый хтмл в своей базе.

rtxtxtrx ★★★
()

Misconfigured whaddayawant

Это 5xx.

[business domain] thing not found

Это 404.

Или, в общем случае: неправ сервер (или другая инфра) — это 5хх, неправ клиент — 4хх. По желанию можно добавлять коды/сообщения конкретных ошибок, например, в тело ответа.

Что тут может быть непонятного и неоднозначного — тайна сия велика есть.

я просто хотел быть креативным, но Safari закешировал ответ 410 на конкретную GET ручку, создал токсичное окружение и нет сил это больше терпеть

Яйца, двери, щемить.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 2)

Вроде бы рекомендуют не использовать 404

Одни рекомендуют чушь, другие - слепо исполняют.

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

Нужно просто использовать 404 и не выделываться.

Obezyan
()
Ответ на: комментарий от Nervous

Или, в общем случае: неправ сервер (или другая инфра) — это 5хх, неправ клиент — 4хх. По желанию можно добавлять коды/сообщения конкретных ошибок, например, в тело ответа.

https://redirect.li/http/status/group/500/. 500-ая ошибка от Nginx означает, что у тебя приложение свалилось и нужно его перезапустить, если ты будешь своим приложением его возвращать, то только создашь путаницу, когда неясно нужно ли что-то перезапускать. Больше слушай картиджечистов они свои неправильные взгляды отстаивают как фанатики. Ну как мем был типа «не жри дерьмо… а ты попробуй мне запрети»

rtxtxtrx ★★★
()
Ответ на: комментарий от rtxtxtrx

вопросы про «правильные» статусы из той же серии от незнания основ, истории, отсутствия опыта

Покажите на кукле в виде анонимуса в каком месте вас трогали рестовики.

Obezyan
()