[{"data":1,"prerenderedAt":1024},["ShallowReactive",2],{"content:\u002F05-web\u002F03-rest-api":3},{"title":4,"description":5,"path":6,"body":7},"REST API","Эти три термина звучат на каждом собеседовании и в каждом описании вакансии. При этом многие разработчики используют их как синонимы, хотя это разные вещи. Разберём каждый по порядку.","\u002F05-web\u002F03-rest-api",{"type":8,"value":9,"toc":1007},"minimark",[10,15,18,21,26,33,36,47,50,56,63,65,69,79,82,87,90,96,100,103,109,112,116,119,125,131,137,143,154,163,167,170,172,176,179,264,274,278,281,287,298,300,304,310,313,315,319,322,328,334,340,342,346,349,355,361,367,370,372,376,385,393,401,421,437,452,474,482,484,488,544,795,1003],[11,12,14],"h1",{"id":13},"что-такое-api-rest-и-restful","Что такое API, REST и RESTful",[16,17,5],"p",{},[19,20],"hr",{},[22,23,25],"h2",{"id":24},"что-такое-api","Что такое API",[16,27,28,32],{},[29,30,31],"strong",{},"API"," (Application Programming Interface) — это интерфейс, через который одна программа общается с другой. Ключевое слово — интерфейс: набор правил и контрактов о том, как именно происходит общение.",[16,34,35],{},"Простая аналогия: вы приходите в ресторан. Вы не идёте на кухню и не говорите повару что готовить — вы общаетесь с официантом. Официант принимает заказ, передаёт на кухню, приносит результат. Вам не нужно знать как устроена кухня. Официант и есть API.",[37,38,43],"pre",{"className":39,"code":41,"language":42},[40],"language-text","Вы (клиент)  →  Официант (API)  →  Кухня (сервер\u002Fбаза данных)\n     ↑                                        │\n     └────────────────────────────────────────┘\n                    Готовое блюдо (ответ)\n","text",[44,45,41],"code",{"__ignoreMap":46},"",[16,48,49],{},"В мире программирования то же самое:",[37,51,54],{"className":52,"code":53,"language":42},[40],"Браузер\u002FПриложение  →  API  →  Сервер + База данных\n        ↑                               │\n        └───────────────────────────────┘\n                   JSON-ответ\n",[44,55,53],{"__ignoreMap":46},[16,57,58,59,62],{},"API бывают разные — не только веб. Операционная система предоставляет API для работы с файлами. Библиотека предоставляет API в виде функций. Но когда говорят \"сделать API\" в контексте backend — обычно имеют в виду ",[29,60,61],{},"веб-API",": интерфейс доступный через HTTP.",[19,64],{},[22,66,68],{"id":67},"что-такое-rest","Что такое REST",[16,70,71,74,75,78],{},[29,72,73],{},"REST"," (Representational State Transfer) — это не технология и не протокол. Это ",[29,76,77],{},"архитектурный стиль",": набор принципов того, как должен быть устроен веб-API.",[16,80,81],{},"Придумал REST Рой Филдинг в 2000 году в своей диссертации. Он описал 6 принципов, которым должна следовать система чтобы называться REST. На практике важны четыре из них.",[83,84,86],"h3",{"id":85},"принцип-1-клиент-сервер","Принцип 1: Клиент-сервер",[16,88,89],{},"Клиент и сервер разделены и развиваются независимо. Фронтенд не знает как устроена база данных. Бэкенд не знает как выглядит интерфейс. Они общаются только через API.",[37,91,94],{"className":92,"code":93,"language":42},[40],"Мобильное приложение ─┐\n                       ├──► API ──► База данных\nВеб-браузер ──────────┘\n\nТри разных клиента, один API — каждый развивается независимо\n",[44,95,93],{"__ignoreMap":46},[83,97,99],{"id":98},"принцип-2-stateless-без-состояния","Принцип 2: Stateless — без состояния",[16,101,102],{},"Каждый запрос самодостаточен. Сервер не помнит предыдущих запросов. Вся информация необходимая для обработки запроса содержится в самом запросе:",[37,104,107],{"className":105,"code":106,"language":42},[40],"\u002F\u002F Плохо — сервер помнит \"текущего пользователя\"\nGET \u002Fcurrent-user\u002Ftodos      ← кто текущий пользователь? сервер \"помнит\"\n\n\u002F\u002F Хорошо — всё необходимое в запросе\nGET \u002Fusers\u002F42\u002Ftodos\nAuthorization: Bearer eyJ...  ← идентификация в каждом запросе\n",[44,108,106],{"__ignoreMap":46},[16,110,111],{},"Stateless делает сервер масштабируемым: любой инстанс может обработать любой запрос, потому что не нужно разделять состояние между серверами.",[83,113,115],{"id":114},"принцип-3-единый-интерфейс","Принцип 3: Единый интерфейс",[16,117,118],{},"Это главный принцип REST. Он состоит из нескольких правил:",[16,120,121,124],{},[29,122,123],{},"Ресурсы идентифицируются через URL."," В REST всё — это ресурс. Пользователь, задача, заказ — ресурс. URL — это адрес ресурса:",[37,126,129],{"className":127,"code":128,"language":42},[40],"\u002Fusers          — коллекция пользователей\n\u002Fusers\u002F42       — конкретный пользователь\n\u002Fusers\u002F42\u002Ftodos — задачи конкретного пользователя\n",[44,130,128],{"__ignoreMap":46},[16,132,133,136],{},[29,134,135],{},"Действия определяются HTTP-методами",", а не URL:",[37,138,141],{"className":139,"code":140,"language":42},[40],"GET    \u002Ftodos      — получить список\nPOST   \u002Ftodos      — создать новую\nGET    \u002Ftodos\u002F1    — получить одну\nPUT    \u002Ftodos\u002F1    — обновить полностью\nPATCH  \u002Ftodos\u002F1    — обновить частично\nDELETE \u002Ftodos\u002F1    — удалить\n",[44,142,140],{"__ignoreMap":46},[16,144,145,146,149,150,153],{},"URL отвечает на вопрос ",[29,147,148],{},"\"что\"",", метод — на вопрос ",[29,151,152],{},"\"что сделать\"",".",[16,155,156,159,160,153],{},[29,157,158],{},"Представление ресурса отделено от самого ресурса."," Один и тот же ресурс может быть представлен по-разному — JSON, XML, HTML — в зависимости от того что запрашивает клиент через заголовок ",[44,161,162],{},"Accept",[83,164,166],{"id":165},"принцип-4-кешируемость","Принцип 4: Кешируемость",[16,168,169],{},"Ответы должны явно указывать можно ли их кешировать. GET-запросы как правило кешируются, POST\u002FPUT\u002FDELETE — нет. Это позволяет CDN и браузерам не делать лишние запросы к серверу.",[19,171],{},[22,173,175],{"id":174},"http-методы-и-статус-коды-в-контексте-rest","HTTP-методы и статус коды в контексте REST",[16,177,178],{},"REST использует HTTP как протокол, и семантика методов важна:",[180,181,182,198],"table",{},[183,184,185],"thead",{},[186,187,188,192,195],"tr",{},[189,190,191],"th",{},"Метод",[189,193,194],{},"Действие",[189,196,197],{},"Идемпотентен?",[199,200,201,215,228,240,252],"tbody",{},[186,202,203,209,212],{},[204,205,206],"td",{},[44,207,208],{},"GET",[204,210,211],{},"Получить ресурс",[204,213,214],{},"Да",[186,216,217,222,225],{},[204,218,219],{},[44,220,221],{},"POST",[204,223,224],{},"Создать ресурс",[204,226,227],{},"Нет",[186,229,230,235,238],{},[204,231,232],{},[44,233,234],{},"PUT",[204,236,237],{},"Заменить ресурс целиком",[204,239,214],{},[186,241,242,247,250],{},[204,243,244],{},[44,245,246],{},"PATCH",[204,248,249],{},"Обновить частично",[204,251,227],{},[186,253,254,259,262],{},[204,255,256],{},[44,257,258],{},"DELETE",[204,260,261],{},"Удалить ресурс",[204,263,214],{},[16,265,266,269,270,273],{},[29,267,268],{},"Идемпотентность"," — если выполнить запрос несколько раз, результат тот же что и от одного. ",[44,271,272],{},"DELETE \u002Ftodos\u002F1"," можно вызвать трижды — после первого раза задача удалена, следующие вызовы ничего не меняют (возвращают 404, но состояние системы не меняется).",[83,275,277],{"id":276},"статус-коды","Статус коды",[16,279,280],{},"Статус код — часть контракта REST. Клиент должен понимать что произошло без чтения тела ответа:",[37,282,285],{"className":283,"code":284,"language":42},[40],"2xx — успех\n  200 OK           — запрос выполнен\n  201 Created      — ресурс создан (ответ на POST)\n  204 No Content   — успех, тело пустое (ответ на DELETE)\n\n4xx — ошибка клиента\n  400 Bad Request  — неверный запрос (невалидные данные)\n  401 Unauthorized — не аутентифицирован\n  403 Forbidden    — аутентифицирован, но нет доступа\n  404 Not Found    — ресурс не найден\n  409 Conflict     — конфликт (например, email уже занят)\n  422 Unprocessable — данные валидны по формату, но не по логике\n\n5xx — ошибка сервера\n  500 Internal Server Error — что-то сломалось на сервере\n  503 Service Unavailable   — сервис временно недоступен\n",[44,286,284],{"__ignoreMap":46},[16,288,289,290,293,294,297],{},"Типичная ошибка новичков — возвращать ",[44,291,292],{},"200 OK"," с телом ",[44,295,296],{},"{\"error\": \"not found\"}",". Это нарушает контракт REST: клиент смотрит на статус код, а не парсит тело чтобы понять успех это или ошибка.",[19,299],{},[22,301,303],{"id":302},"что-такое-restful-api","Что такое RESTful API",[16,305,306,309],{},[29,307,308],{},"RESTful API"," — это веб-API, который следует принципам REST. Приставка \"-ful\" означает \"в полной мере\". Если API соответствует принципам Филдинга — его можно назвать RESTful.",[16,311,312],{},"На практике термины \"REST API\" и \"RESTful API\" используются как синонимы — разница только в степени строгости соответствия принципам.",[19,314],{},[22,316,318],{"id":317},"rest-vs-не-rest-на-примере-todo-api","REST vs не REST — на примере Todo API",[16,320,321],{},"Разница становится понятнее на конкретных примерах. Вот хорошие и плохие варианты для нашего Todo API:",[37,323,326],{"className":324,"code":325,"language":42},[40],"\u002F\u002F ❌ Не REST — действие в URL, игнорирование методов\nPOST \u002FgetTodos\nPOST \u002FcreateTodo\nPOST \u002FdeleteTodo?id=1\nPOST \u002FmarkTodoAsDone?id=1\nGET  \u002Ftodo\u002Fdelete\u002F1\n\n\u002F\u002F ✅ REST — URL это ресурс, метод это действие\nGET    \u002Fapi\u002Ftodos\nPOST   \u002Fapi\u002Ftodos\nDELETE \u002Fapi\u002Ftodos\u002F1\nPUT    \u002Fapi\u002Ftodos\u002F1\n",[44,327,325],{"__ignoreMap":46},[37,329,332],{"className":330,"code":331,"language":42},[40],"\u002F\u002F ❌ Не REST — всегда 200, ошибка в теле\nHTTP 200 OK\n{\"success\": false, \"error\": \"todo not found\"}\n\n\u002F\u002F ✅ REST — статус код отражает результат\nHTTP 404 Not Found\n{\"error\": \"todo not found\"}\n",[44,333,331],{"__ignoreMap":46},[37,335,338],{"className":336,"code":337,"language":42},[40],"\u002F\u002F ❌ Не REST — глагол в URL\nPOST \u002Fapi\u002Ftodos\u002F1\u002FmarkDone\nPOST \u002Fapi\u002Ftodos\u002F1\u002Farchive\nGET  \u002Fapi\u002FgetAllTodos\n\n\u002F\u002F ✅ REST — глагол выражен методом, URL — существительное\nPUT  \u002Fapi\u002Ftodos\u002F1        (с телом {\"done\": true})\nPUT  \u002Fapi\u002Ftodos\u002F1        (с телом {\"archived\": true})\nGET  \u002Fapi\u002Ftodos\n",[44,339,337],{"__ignoreMap":46},[19,341],{},[22,343,345],{"id":344},"когда-rest-не-подходит","Когда REST не подходит",[16,347,348],{},"REST хорош для большинства задач, но не универсален. Есть случаи когда выбирают другой подход:",[16,350,351,354],{},[29,352,353],{},"GraphQL"," — когда клиенту нужна гибкость в выборе полей. Вместо нескольких REST-запросов — один запрос с описанием нужных данных. Популярен в мобильных приложениях где важен трафик.",[16,356,357,360],{},[29,358,359],{},"gRPC"," — когда нужна высокая производительность и строгая типизация между сервисами. Использует бинарный протокол (protobuf) вместо JSON. Стандарт для межсервисного взаимодействия в микросервисах.",[16,362,363,366],{},[29,364,365],{},"WebSocket"," — когда нужна двусторонняя связь в реальном времени: чат, онлайн-игры, live-уведомления. REST работает по схеме запрос-ответ, WebSocket держит постоянное соединение.",[16,368,369],{},"На собеседовании на позицию backend-разработчика достаточно понимать REST и уметь объяснить почему выбирают альтернативы — это уже уровень осознанного выбора инструмента.",[19,371],{},[22,373,375],{"id":374},"вопросы-на-собеседовании","Вопросы на собеседовании",[16,377,378,381,384],{},[29,379,380],{},"Q: Что такое API? Чем веб-API отличается от любого другого API?",[382,383],"br",{},"\nA: API — интерфейс через который одна программа общается с другой: набор правил и контрактов взаимодействия. Веб-API — частный случай: интерфейс доступный по сети через HTTP. Любая библиотека тоже предоставляет API — в виде функций и классов, но не через сеть.",[16,386,387,390,392],{},[29,388,389],{},"Q: Что такое REST? Это протокол или технология?",[382,391],{},"\nA: Ни то ни другое. REST — архитектурный стиль: набор принципов проектирования веб-API, описанных Роем Филдингом в 2000 году. Главные: клиент-сервер, stateless, единый интерфейс (ресурсы в URL, действия в HTTP-методах), кешируемость.",[16,394,395,398,400],{},[29,396,397],{},"Q: Что значит stateless в контексте REST?",[382,399],{},"\nA: Сервер не хранит состояние между запросами. Каждый запрос самодостаточен — содержит всю информацию необходимую для обработки: идентификацию пользователя, параметры, данные. Это делает систему масштабируемой: любой сервер может обработать любой запрос.",[16,402,403,406,408,409,411,412,414,415,417,418,420],{},[29,404,405],{},"Q: Чем PUT отличается от PATCH?",[382,407],{},"\nA: ",[44,410,234],{}," заменяет ресурс целиком — нужно передать все поля. ",[44,413,246],{}," обновляет частично — только изменённые поля. ",[44,416,234],{}," идемпотентен: повторный вызов с теми же данными не меняет результат. ",[44,419,246],{}," технически нет, хотя на практике часто реализуют идемпотентно.",[16,422,423,429,431,432,293,435,153],{},[29,424,425,426,428],{},"Q: Почему нельзя возвращать 200 OK с телом ",[44,427,296],{},"?",[382,430],{},"\nA: Нарушает контракт REST и HTTP. Клиент (браузер, мобильное приложение, другой сервис) смотрит на статус код чтобы понять успех или ошибка — без парсинга тела. 200 означает успех. Middleware, прокси, CDN тоже ориентируются на статус коды. Правильно: ",[44,433,434],{},"404 Not Found",[44,436,296],{},[16,438,439,442,408,444,447,448,451],{},[29,440,441],{},"Q: Чем отличаются 401 и 403?",[382,443],{},[44,445,446],{},"401 Unauthorized"," — пользователь не аутентифицирован: не передал токен или токен невалидный. Буквально \"мы не знаем кто ты\". ",[44,449,450],{},"403 Forbidden"," — пользователь аутентифицирован, но у него нет прав на это действие. \"Мы знаем кто ты, но тебе нельзя\".",[16,453,454,457,459,460,462,463,462,465,467,468,470,471,473],{},[29,455,456],{},"Q: Что такое идемпотентность? Какие HTTP-методы идемпотентны?",[382,458],{},"\nA: Операция идемпотентна если повторное выполнение с теми же параметрами даёт тот же результат. ",[44,461,208],{},", ",[44,464,234],{},[44,466,258],{}," — идемпотентны. ",[44,469,221],{}," — нет: каждый вызов создаёт новый ресурс. ",[44,472,246],{}," — зависит от реализации.",[16,475,476,479,481],{},[29,477,478],{},"Q: Когда REST не лучший выбор?",[382,480],{},"\nA: Когда нужна гибкость запросов от клиента — GraphQL. Когда нужна высокая производительность и строгая типизация между сервисами — gRPC. Когда нужна двусторонняя связь в реальном времени — WebSocket.",[19,483],{},[22,485,487],{"id":486},"практика","Практика",[489,490,494,501,530],"quiz",{"answer":491,"id":492,"xp":493},"2","web-rest-q1","10",[16,495,496,497,500],{},"Какой статус обычно должен вернуть ",[44,498,499],{},"POST \u002Fapi\u002Ftodos",", если задача успешно создана?",[502,503,504],"template",{"v-slot:options":46},[505,506,507,513,519,525],"ul",{},[508,509,510,512],"li",{},[44,511,292],{},", потому что запрос завершился без ошибки",[508,514,515,518],{},[44,516,517],{},"201 Created",", потому что создан новый ресурс",[508,520,521,524],{},[44,522,523],{},"204 No Content",", потому что тело ответа не нужно",[508,526,527,529],{},[44,528,434],{},", потому что до запроса задачи ещё не было",[502,531,532],{"v-slot:explanation":46},[16,533,534,535,537,538,540,541,153],{},"Для успешного создания ресурса через ",[44,536,221],{}," обычно используют ",[44,539,517],{},". В ответ часто кладут созданный ресурс или хотя бы его ",[44,542,543],{},"id",[545,546,550,553,778],"predict",{"answer":547,"id":548,"xp":549},"201\\n204","web-rest-p1","15",[16,551,552],{},"Что выведет программа?",[502,554,555],{"v-slot:code":46},[37,556,560],{"className":557,"code":558,"language":559,"meta":46,"style":46},"language-go shiki shiki-themes github-dark","package main\n\nimport (\n    \"fmt\"\n    \"net\u002Fhttp\"\n)\n\nfunc successStatus(method string) int {\n    switch method {\n    case http.MethodPost:\n        return http.StatusCreated\n    case http.MethodDelete:\n        return http.StatusNoContent\n    default:\n        return http.StatusOK\n    }\n}\n\nfunc main() {\n    fmt.Println(successStatus(http.MethodPost))\n    fmt.Println(successStatus(http.MethodDelete))\n}\n","go",[44,561,562,575,582,592,605,615,621,626,654,663,672,681,689,697,706,714,720,726,731,742,759,773],{"__ignoreMap":46},[563,564,567,571],"span",{"class":565,"line":566},"line",1,[563,568,570],{"class":569},"snl16","package",[563,572,574],{"class":573},"svObZ"," main\n",[563,576,578],{"class":565,"line":577},2,[563,579,581],{"emptyLinePlaceholder":580},true,"\n",[563,583,585,588],{"class":565,"line":584},3,[563,586,587],{"class":569},"import",[563,589,591],{"class":590},"s95oV"," (\n",[563,593,595,599,602],{"class":565,"line":594},4,[563,596,598],{"class":597},"sU2Wk","    \"",[563,600,601],{"class":573},"fmt",[563,603,604],{"class":597},"\"\n",[563,606,608,610,613],{"class":565,"line":607},5,[563,609,598],{"class":597},[563,611,612],{"class":573},"net\u002Fhttp",[563,614,604],{"class":597},[563,616,618],{"class":565,"line":617},6,[563,619,620],{"class":590},")\n",[563,622,624],{"class":565,"line":623},7,[563,625,581],{"emptyLinePlaceholder":580},[563,627,629,632,635,638,642,645,648,651],{"class":565,"line":628},8,[563,630,631],{"class":569},"func",[563,633,634],{"class":573}," successStatus",[563,636,637],{"class":590},"(",[563,639,641],{"class":640},"s9osk","method",[563,643,644],{"class":569}," string",[563,646,647],{"class":590},") ",[563,649,650],{"class":569},"int",[563,652,653],{"class":590}," {\n",[563,655,657,660],{"class":565,"line":656},9,[563,658,659],{"class":569},"    switch",[563,661,662],{"class":590}," method {\n",[563,664,666,669],{"class":565,"line":665},10,[563,667,668],{"class":569},"    case",[563,670,671],{"class":590}," http.MethodPost:\n",[563,673,675,678],{"class":565,"line":674},11,[563,676,677],{"class":569},"        return",[563,679,680],{"class":590}," http.StatusCreated\n",[563,682,684,686],{"class":565,"line":683},12,[563,685,668],{"class":569},[563,687,688],{"class":590}," http.MethodDelete:\n",[563,690,692,694],{"class":565,"line":691},13,[563,693,677],{"class":569},[563,695,696],{"class":590}," http.StatusNoContent\n",[563,698,700,703],{"class":565,"line":699},14,[563,701,702],{"class":569},"    default",[563,704,705],{"class":590},":\n",[563,707,709,711],{"class":565,"line":708},15,[563,710,677],{"class":569},[563,712,713],{"class":590}," http.StatusOK\n",[563,715,717],{"class":565,"line":716},16,[563,718,719],{"class":590},"    }\n",[563,721,723],{"class":565,"line":722},17,[563,724,725],{"class":590},"}\n",[563,727,729],{"class":565,"line":728},18,[563,730,581],{"emptyLinePlaceholder":580},[563,732,734,736,739],{"class":565,"line":733},19,[563,735,631],{"class":569},[563,737,738],{"class":573}," main",[563,740,741],{"class":590},"() {\n",[563,743,745,748,751,753,756],{"class":565,"line":744},20,[563,746,747],{"class":590},"    fmt.",[563,749,750],{"class":573},"Println",[563,752,637],{"class":590},[563,754,755],{"class":573},"successStatus",[563,757,758],{"class":590},"(http.MethodPost))\n",[563,760,762,764,766,768,770],{"class":565,"line":761},21,[563,763,747],{"class":590},[563,765,750],{"class":573},[563,767,637],{"class":590},[563,769,755],{"class":573},[563,771,772],{"class":590},"(http.MethodDelete))\n",[563,774,776],{"class":565,"line":775},22,[563,777,725],{"class":590},[502,779,780],{"v-slot:hint":46},[16,781,782,784,785,788,789,791,792,153],{},[44,783,221],{}," создаёт ресурс — ",[44,786,787],{},"201",". ",[44,790,258],{}," часто возвращает пустое тело — ",[44,793,794],{},"204",[796,797,801,808,971],"code-task",{"expected":798,"id":799,"xp":800},"400\\n404\\n409","web-rest-ct1","20",[16,802,803,804,807],{},"Реализуй ",[44,805,806],{},"ErrorStatus",": функция должна сопоставить доменную ошибку с HTTP-статусом.",[502,809,810],{"v-slot:template":46},[37,811,813],{"className":557,"code":812,"language":559,"meta":46,"style":46},"package main\n\nimport (\n    \"fmt\"\n    \"net\u002Fhttp\"\n)\n\nfunc ErrorStatus(kind string) int {\n    return 0\n}\n\nfunc main() {\n    fmt.Println(ErrorStatus(\"bad_request\"))\n    fmt.Println(ErrorStatus(\"not_found\"))\n    fmt.Println(ErrorStatus(\"conflict\"))\n\n    _ = http.StatusBadRequest\n}\n",[44,814,815,821,825,831,839,847,851,855,875,884,888,892,900,918,935,952,956,967],{"__ignoreMap":46},[563,816,817,819],{"class":565,"line":566},[563,818,570],{"class":569},[563,820,574],{"class":573},[563,822,823],{"class":565,"line":577},[563,824,581],{"emptyLinePlaceholder":580},[563,826,827,829],{"class":565,"line":584},[563,828,587],{"class":569},[563,830,591],{"class":590},[563,832,833,835,837],{"class":565,"line":594},[563,834,598],{"class":597},[563,836,601],{"class":573},[563,838,604],{"class":597},[563,840,841,843,845],{"class":565,"line":607},[563,842,598],{"class":597},[563,844,612],{"class":573},[563,846,604],{"class":597},[563,848,849],{"class":565,"line":617},[563,850,620],{"class":590},[563,852,853],{"class":565,"line":623},[563,854,581],{"emptyLinePlaceholder":580},[563,856,857,859,862,864,867,869,871,873],{"class":565,"line":628},[563,858,631],{"class":569},[563,860,861],{"class":573}," ErrorStatus",[563,863,637],{"class":590},[563,865,866],{"class":640},"kind",[563,868,644],{"class":569},[563,870,647],{"class":590},[563,872,650],{"class":569},[563,874,653],{"class":590},[563,876,877,880],{"class":565,"line":656},[563,878,879],{"class":569},"    return",[563,881,883],{"class":882},"sDLfK"," 0\n",[563,885,886],{"class":565,"line":665},[563,887,725],{"class":590},[563,889,890],{"class":565,"line":674},[563,891,581],{"emptyLinePlaceholder":580},[563,893,894,896,898],{"class":565,"line":683},[563,895,631],{"class":569},[563,897,738],{"class":573},[563,899,741],{"class":590},[563,901,902,904,906,908,910,912,915],{"class":565,"line":691},[563,903,747],{"class":590},[563,905,750],{"class":573},[563,907,637],{"class":590},[563,909,806],{"class":573},[563,911,637],{"class":590},[563,913,914],{"class":597},"\"bad_request\"",[563,916,917],{"class":590},"))\n",[563,919,920,922,924,926,928,930,933],{"class":565,"line":699},[563,921,747],{"class":590},[563,923,750],{"class":573},[563,925,637],{"class":590},[563,927,806],{"class":573},[563,929,637],{"class":590},[563,931,932],{"class":597},"\"not_found\"",[563,934,917],{"class":590},[563,936,937,939,941,943,945,947,950],{"class":565,"line":708},[563,938,747],{"class":590},[563,940,750],{"class":573},[563,942,637],{"class":590},[563,944,806],{"class":573},[563,946,637],{"class":590},[563,948,949],{"class":597},"\"conflict\"",[563,951,917],{"class":590},[563,953,954],{"class":565,"line":716},[563,955,581],{"emptyLinePlaceholder":580},[563,957,958,961,964],{"class":565,"line":722},[563,959,960],{"class":590},"    _ ",[563,962,963],{"class":569},"=",[563,965,966],{"class":590}," http.StatusBadRequest\n",[563,968,969],{"class":565,"line":728},[563,970,725],{"class":590},[502,972,973],{"v-slot:hints":46},[505,974,975,983,990,997],{},[508,976,977,979,980],{},[44,978,914],{}," → ",[44,981,982],{},"http.StatusBadRequest",[508,984,985,979,987],{},[44,986,932],{},[44,988,989],{},"http.StatusNotFound",[508,991,992,979,994],{},[44,993,949],{},[44,995,996],{},"http.StatusConflict",[508,998,999,1000],{},"Для неизвестной ошибки можно вернуть ",[44,1001,1002],{},"http.StatusInternalServerError",[1004,1005,1006],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}",{"title":46,"searchDepth":577,"depth":577,"links":1008},[1009,1010,1016,1019,1020,1021,1022,1023],{"id":24,"depth":577,"text":25},{"id":67,"depth":577,"text":68,"children":1011},[1012,1013,1014,1015],{"id":85,"depth":584,"text":86},{"id":98,"depth":584,"text":99},{"id":114,"depth":584,"text":115},{"id":165,"depth":584,"text":166},{"id":174,"depth":577,"text":175,"children":1017},[1018],{"id":276,"depth":584,"text":277},{"id":302,"depth":577,"text":303},{"id":317,"depth":577,"text":318},{"id":344,"depth":577,"text":345},{"id":374,"depth":577,"text":375},{"id":486,"depth":577,"text":487},1781458320423]