Лекция Тесты
REST — это стиль архитектуры программного обеспечения для построения распределенных масштабируемых веб-сервисов. Рой выступал за использование стандартных HTTP методов так, чтобы придавать запросам определенный смысл.
REST (сокр. от англ. Representational State Transfer — «передача состояния представления») — архитектурный стиль взаимодействия компонентов распределенного приложения в сети. REST представляет собой согласованный набор ограничений, учитываемых при проектировании распределенной гипермедиа-системы. В определенных случаях (интернет-магазины, поисковые системы, прочие системы, основанные на данных) это приводит к повышению производительности и упрощению архитектуры. В широком смысле компоненты в REST взаимодействуют наподобие взаимодействия клиентов и серверов во Всемирной паутине. REST является альтернативой RPC .

1) лучше использовать простой минимальный и типичный и стандартный путь / запрос REST API для
1.1 получение каждого списк должен выполняться так:
GET {base_url}/v1/categories
GET {base_url}/v1/items
с параметрами фильтров и не использовать слова внутри путей (все, фильтр и т. д.)
каждый endpoint со списком может состоять из параметров фильтров или затребуемых полей (если испольуются - то нужно их описать)
тоесть нужно использовать чистые (без отображения реализации URL)

1.2 для получеания одной сущности :
GET {base_url}/v1/item/{id}
для создания
POST {base_url}/v1/item + params
для обновления
PUT/PATCH /{base_url}/v1/item/{id} + params
для удаления
DELETE {base_url}/v1/item/{id}
2) каждый ответ (респонс) от сервера должен быть типовым:
2.1 если возвращаемые данные - список
{
"items/or/data" :
[
{"id":1, name:"intellect.icu"} ,
{…}
],
"page" : 1,
"total/or/totalpage” :12
}
2.2 если возвращается одна сущность
{
"id":1,
"name":"intellect.icu" ...
}
2.3 если возвращается сложный зависимый список (это очень редко но возможно)
{
"items/or/data" : [
…. list of entities
{
"id":1,
name:"intellect.icu",
"sublist":["item1","item2"]} ,
{…}
],
"page" : 1,
"total/or/totalpage” :12
}
3. все ошибки валидации должны иметь одинаковаую структуру
HTTP код 422 и тело ответа:
{
"message": "Could not to add a new item.",
"errors": {
"name_field1": ["The text message for this field."],[...],
"name": ["The name is required"]
}
}
В сети Интернет вызов удаленной процедуры может представлять собой обычный HTTP-запрос (обычно «GET» или «POST»; такой запрос называют «REST-запрос»), а необходимые данные передаются в качестве параметров запроса.

Для веб-служб, построенных с учетом REST (то есть не нарушающих накладываемых им ограничений), применяют термин «RESTful».
В отличие от веб-сервисов (веб-служб) на основе SOAP, не существует «официального» стандарта для RESTful веб-API. Дело в том, что REST является архитектурным стилем, в то время как SOAP является протоколом. Несмотря на то, что REST не является стандартом сам по себе, большинство RESTful-реализаций используют стандарты, такие как HTTP, URL, JSON и XML.
Взаимодействие REST API осуществляется через endpoint.
Communication endpoint Конечная точка связи является типом сети связи узла . Это интерфейс, предоставляемый взаимодействующей стороной или каналом связи. Примером последнего типа конечной точки связи является тема Publish–subscribe (публикации-подписки) или группа в системах групповой связи .


Рой Филдинг предложил использовать Web не только для общения между человеком и машиной, но и для общения между машинами.REST задуман так, что если правильно применять, то можно построить приложение (с API), которое будет работать и масштабироваться веками.. Здесь нет ни слова об API, HTTP или красивых URL. однако на практике расширяют это понятие на прмере api, url, методов.
Таким образом, данные HTTP-запросы будут иметь различный смысловую нагрузку в REST:

Выше только некоторые виды запросов, а вот весь их список: CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE.

Итак, одна транзакция по RESTful API будет состоять, как минимум, из следующего:
Задумаемся на минуту, что же происходит, когда мы набираем в браузере строку somestring и нажимаем . Браузер посылает серверу запрос somestring? Нет, конечно. Все немного сложнее. Он анализирует строку, выделяет из нее имя сервера и порт (а также имя протокола, но нам это сейчас не интересно), устанавливает соединение с Web-сервером по адресу сервер:порт и посылает ему что-то вроде следующего:
GET somestring HTTP/1.0\n ...другая информация... \n\n
Здесь \n означает символ перевода строки, а \n\n — два обязательных символа новой строки, которые являются маркером окончания запроса (точнее, окончания заголовков запроса). Пока мы не пошлем этот маркер, сервер не будет обрабатывать наш запрос.
Как видим, после GET-строки могут следовать и другие строки с информацией, разделенные символом перевода строки. Их обычно формирует браузер. Такие строки называются заголовками (headers), и их может быть сколько угодно. Протокол HTTP как раз и задает правила формирования и интерпретации этих заголовков. Вот мы и начинаем знакомство с протоколом HTTP. Как видите, он представляет собой ни что иное, как просто набор заголовков, которыми обмениваются сервер и браузер, и еще пару соглашений насчет метода POST, которые мы вскоре рассмотрим.
Не все заголовки обрабатываются сервером — некоторые просто пересылаются запускаемому сценарию с помощьюпеременных окружения.
Переменные окружения представляют собой именованные значения параметров, которые операционная система (точнее, процесс-родитель) передает запущенной программе. Программа может с помощью специальных функций получить значение любой установленной переменной окружения, указав ее имя. Именно так и должен поступать CGI-сценарий, когда захочет узнать значение того или иного заголовка запроса. К сожалению, набор передаваемых сценарию заголовков ограничен стандартами, и некоторые заголовки нельзя получить из сценария никаким способом (ему просто недоступна соответствующая переменная окружения). Такие случаи мы будем оговаривать особо.
Ниже приводятся некоторые заголовки запросов с их описаниями, а также имена переменных окружения, которые использует сервер для передачи их CGI-сценарию.
Формат запроса:
GET сценарий?параметры HTTP/1.0
>>> Переменные окружения: REQUEST_URI; в переменной QUERY_STRING сохраняется значение и параметры, в переменной REQUEST_METHOD — ключевое слово GET.
Этот заголовок является обязательным (если только не применяется метод POST) и определяет адрес запрашиваемого документа на сервере. Также задаются параметры, которые пересылаются сценарию (если сценарию ничего не передается, или же это обычная статическая страница, то все символы после знака вопроса и сам знак опускаются). Вместо строки HTTP/1.0 может быть указан и другой протокол - например, HTTP/1.1. Именно его соглашения и будут учитываться сервером при обработке данных, поступивших от пользователя, и других заголовков.
Строка
сценарий?параметры
задается в том же самом формате, в котором она входит в URL. Неплохо было бы назвать эту строку как-нибудь более реалистично, чтобы учесть возможность присутствия в ней командных параметров. Такое название действительно существует и звучит как URI (Universal Resource Identifier - Универсальный идентификатор ресурса). Очень часто его смешивают с понятием URL (вплоть до того, что это происходит даже в официальной документации по стандартам HTTP). Под словом URL мы понимаем полный путь к некоторой Web-странице вместе с параметрами без фрагмента, а relative reference (относительный URI) это path + query + fragment
URL — это частный случай URI
Формат запроса:
POST сценарий?параметры HTTP/1.0
>>> Переменная окружения: REQUEST_URI; в переменной QUERY_STRING сохраняется значение и параметры, в переменной REQUEST_METHOD — слово POST.
Настал момент рассмотреть метод POST. Приведем сразу практический пример метода запроса POST:
POST /script.cgi HTTP/1.0\n Content-length: 8\n \n Hello!!!
Сервер начнет обработку запроса, не дожидаясь передачи данных после маркера конца заголовков. Иными словами, сценарий запустится сразу же после отправки \n\n, а уж ждать или не ждать, пока придет строка Hello! длиной 6 байт - его дело. Последнее означает, что сервер никак не интерпретирует POST-данные (точно так же, как он не интерпретирует некоторые заголовки), а пересылает их непосредственно сценарию. Но как же сценарий узнает, когда данные кончаются, т. е. когда ему прекращать чтение информации, поступившей от браузера? В этом ему поможет переменная окружения Content-Length, и именно на нее следует ориентироваться.
Зачем нужен метод POST?
В основном для того, чтобы передавать большие объемы данных. Например, при загрузке файлов через Web или при обработке больших форм. Кроме того, метод POST часто используют для эстетических целей: дело в том, что при применении GET, как вы, наверное, уже заметили, URL сценария становится довольно длинным и неизящным. Переданные сценарию параметры не отображаются в окне браузера, POST-запрос оставляет URL без изменения.
Архитектура REST описывается шестью ограничениями. Эти ограничения, применительно к архитектуре, первоначально были представлены Роем Филдингом (Roy Fielding) в его докторской диссертации и определяют основы RESTful стиля.
Шесть ограничений архитектуры REST :
Единый интерфейс определяет интерфейс между клиентами и серверами. Это упрощает и отделяет архитектуру, которая позволяет каждой части развиваться самостоятельно.
Четыре принципа единого интерфейса:
Отдельные ресурсы определяются в запросе, для чего используется URI, как идентификаторы ресурсов. Сами ресурсы концептуально отделены от представлений, которые возвращаются клиенту. Например, сервер не отправляет свою базу данных, а, скорее, некоторые HTML, XML или JSON, которые представляет некоторые записи в базе данных, например, на финском языке и в UTF-8, в зависимости от деталей запроса и реализации сервера.
Когда пользователь имеет представление о ресурсе, в том числе о связанных метаданных, он имеет достаточно информации для изменения или удаления ресурса на сервере, если у него есть на это разрешение
Каждое сообщение содержит достаточно информации для описания того, как его выполнить. Например, вызываемый парсер может описываться с помощью Internet media type (так же известным как MIME) Ответы также явно указывают на их способность кешировать.
Клиенты предоставляют статус через содержимое body, параметры строки запроса, заголовки запросов и запрашиваемый URI (имя ресурса). Это называется гипермедиа (или гиперссылки с гипертекстом)
Наряду с приведенным выше описанием, HATEOS также означает, что, в случае необходимости ссылки содержатся в теле ответа (или заголовках) для поддержки URI извлечения самого объекта или запрошенных объектов. Позднее, мы затронем эту тему глубже.
Единый интерфейс так же означает, что любой REST сервис должен обеспечивать его фундаментальный дизайн.
Так как REST это акроним для REpresentational State Transfer, отсутствие состояний является важной чертой. Таким образом, это значит, что необходимое состояние для обработки запроса содержится в самом запросе, либо в рамках URI, параметрах строки запроса, тела или заголовках. URI уникально идентифицирует ресурс и тело содержит состояние (или изменение состояния) этого ресурса. Затем, после того, как сервер завершит обработку, состояние или его часть(и) отдается обратно клиенту через заголовки, статус и тело ответа.
Большинство из нас, кто был в этой отрасли, привыкли к программированию в контейнере, который дает нам понятие "Сессия, которая поддерживает состояние нескольких HTTP запросов. В REST, клиент должен включать всю информация для сервера для выполнения запроса, перепосылая состояние по необходимости, если это состояние должно охватывать несколько запросов. Отсутствие состояний обеспечивает большую масштабируемость, так как сервер не должен поддерживать или общаться через состояние сеанса. Кроме того, балансировщику нагрузки не придется беспокоиться о связанности сессии и системы.
Так в чем различие между состоянием и ресурсом? Состояние или состояние приложения, это то, что сервер заботится выполнить запрос для получения данных необходимых для текущей сессии или запроса. Ресурсное состояние, или ресурс, это данные, которые определяют представление ресурса, например, данные хранящиеся в базе данных. Рассмотрим состояние приложения как данные, которые могут варьироваться в зависимости от клиента и запроса. С другой стороны, состояние ресурсов постоянно по каждому клиенту, который запрашивает его.
Каждый встречал проблему с кнопкой "Назад" в своем веб приложении, когда оно ведет себя по разному в одной точке, потому что ожидались действия в определенном порядке? Такое происходит, когда нарушен принцип отсутствия состояний. Есть случаи, когда не соблюдается принцип отсутствия состояний, например, three-legged OAuth, ограничение скорости вызова API и т.д. Однако, приложите максимум усилий, чтобы состояние приложения не занимало несколько запросов к вашему сервису.
Как и в World Wide Web, клиент может кэшировать ответы. Таким образом, ответы явно или неявно определяют себя как кешируемые или нет, для предотвращения повторного использования клиентами устаревших или некорректных данных в ответ на дальнейшие запросы. Хорошо спроектированное кэширование частично или полностью устраняет некоторые клиент-серверные взаимодействия, способствуя дальнейшей масштабируемости и производительности.
Единый интерфейс отделяет клиентов от серверов. Разделение интерфейсов означает, что, например, клиенты не связаны с хранением данных, которое остается внутри каждого сервера, так что мобильность кода клиента улучшается. Серверы не связаны с интерфейсом пользователя или состоянием, так что серверы могут быть проще и масштабируемы. Серверы и клиенты могут быть заменяемы и разрабатываться независимо, пока интерфейс не изменяется.
Обычно клиенты не могу сказать - они подключены напрямую к серверу или общаются через посредника. Промежуточный сервер может улучшить масштабируемость системы, обеспечивая балансировку нагрузки и предоставляя общий кэш. Слои также могут отвечать за политику безопасности.
Серверы могут временно расширять или кастомизировать функционал клиента, передавая ему логику, которую он может исполнять. Например, это могут быть скомпилированные Java-апплеты или клиентские скрипты на Javascript

Рис. Ограничения архитектуры REST
таблица по основным HTTP-методам и их собенностям.
| HTTP метод | Краткое обозначение | Краткая суть | Запрос имеет тело | Успешный ответ имеет тело | Безопасный | Идемпотентный | Кешируемый | Допускается в HTML-формах |
|---|---|---|---|---|---|---|---|---|
| GET | Получить | Чтение ресурса | Нет | Да | Да | Да | Да | Да |
| HEAD | Получить заголовки | Как GET, но без тела ответа | Нет | Нет | Да | Да | Да | Нет |
| POST | Создать / отправить | Отправка данных, создание ресурса или запуск действия | Да | Да | Нет | Нет | Да, но редко*** | Да |
| PUT | Полностью заменить | Полная замена ресурса по URI | Да | Может | Нет | Да | Да, но редко*** | Нет |
| PATCH | Частично изменить | Частичное обновление ресурса | Да | Может | Нет | Нет* | Да, но редко*** | Нет |
| DELETE | Удалить | Удаление ресурса | Обычно нет, Может | Может быть | Нет | Да | Нет | Нет |
| OPTIONS | Узнать возможности | Какие методы и параметры поддерживает ресурс | Обычно нет, Может | Может | Да | Да | Обычно нет | Нет |
| TRACE | Диагностика | Возвращает запрос так, как его увидел сервер | Нет | Да | Да | Да | Нет | Нет |
| CONNECT | Установить туннель | Создает туннель к серверу, обычно для HTTPS через proxy | Обычно нет | Нет** | Нет | Нет | Нет | Нет |
* PATCH иногда может быть идемпотентным, но в общем случае считается неидемпотентным.
** У CONNECT при успешном ответе обычно нет обычного HTTP body, потому что дальше начинается туннель.
*** Только если включена информация о дате последнего изменения
Филдинг указывал, что приложения, не соответствующие приведенным условиям, не могут называться REST-приложениями. Если же все условия соблюдены, то, по его мнению, приложение получит следующие преимущества
, мы позволяем распределенной системе любого типа иметь такие свойства как: производительность, расширяемость, простота, обновляемость, понятность, портативность и надежность.
Замечание Единственным необязательным ограничением для RESTful архитектуры - это "код по требованию". Если сервис не проходит по любым другим условиям, то его совершенно точно нельзя назвать RESTful.
У REST API есть много плюсов, но и недостатки тоже заметные.
Проблемы с несколькими связанными действиями
REST хорошо подходит для CRUD:
Но хуже подходит для сложных бизнес-операций, например:
Для таких вещей endpoint-ы часто становятся не очень “REST-овыми”.
Слабая типизация контракта
Без дополнительных инструментов клиенту не всегда ясно:
Поэтому часто нужен Swagger / OpenAPI.
Если кратко, то REST API особенно хорош для простых и понятных CRUD-сценариев, но начинает проигрывать, когда:
Способы решения недастатков
| Недостаток | Пример проблемы | Чем решают |
|---|---|---|
| Over-fetching (лишние данные) | Нужен только name, а приходит весь объект пользователя | GraphQL (запрашиваешь только нужные поля) |
| Under-fetching (не хватает данных) | Для одного экрана нужно 3–5 запросов (/user, /posts, /comments) | GraphQL или агрегационные endpoint-ы (/user-full) |
| Много endpoint-ов | API разрастается: /users, /users/{id}/orders, /users/{id}/reviews | GraphQL или BFF (Backend For Frontend) |
| Сложные фильтры и выборки | URL становится огромным: /products?price_gt=10&sort=desc&category=... | GraphQL или POST с query DSL |
| Плохая поддержка сложной бизнес-логики | /orders/123/confirm-and-pay выглядит “не REST-ово” | RPC-подход (action-based API), gRPC |
| Версионирование (v1, v2...) | Нужно поддерживать несколько версий API | Versioning через headers, GraphQL (эволюция схемы) |
| Stateless (нет состояния) | Нужно помнить шаги пользователя (checkout flow) | Хранение состояния в БД / Redis, сессии, workflow-сервисы |
| Не подходит для real-time | Чат или live-обновления лагают при polling | WebSocket, Server-Sent Events |
| Слабая типизация | Клиент не знает структуру ответа | OpenAPI / Swagger, GraphQL |
| Сложность кэширования | Данные часто меняются, кэш устаревает | CDN, cache invalidation стратегии, ETag |
| Часто “нечистый REST” | Используются GET/POST как попало | API-гайды, стандарты, линтеры |
| Много сетевых запросов | Мобильное приложение тормозит | Batch-запросы, GraphQL, gateway-агрегация |


Существует 2 основных типа ресурса в архитектуре REST: коллекция и элемент коллекции.
Коллекция представляет собой набор самостоятельных и самодостаточных элементов.
Пример ссылки на коллекцию пользователей:
/api/users
Элемент коллекции пользователей, или конкретный пользователь, в таком случае, может быть представлен в виде:
/api/users/ae1111
Существительные — хорошо, глаголы — плохо.
Имена коллекций должны представлять сущности (существительные во множественном числе), и они должны быть максимально конкретными и понятными (самодокументирующимися). Если речь идет о собаках, то это должны быть собаки, а не просто животные.
Каждым ресурсом в RESTful API управляет несколько определенных минимально необходимых глаголов. Для большинства случаев достаточно 4 основных глагола (HTTP метода):
Идемпотентность означает, что сколько бы раз мы не вызывали такой метод — результат будет один и тот же.
| Ресурс | POST | GET | PUT | DELETE |
|---|---|---|---|---|
| /users | Создать пользователя | Показать список всех пользователей | Обновить список всех пользователей | Удалить всех пользователей |
| /users/111111 | Ошибка | Показать Василия Пупкина | Если есть, обновить Пупкина, если нет Ошибка | Удалить Василия Пупкина |
Если необходимо показать иерархическую связь между объектами, делаем так.
Коллекция машин пользователя:
/api/users/11111/cars
Конкретная машина 1 пользователя 1111:
/api/users/1111/cars/1
Не стоит писать длинные адреса — это плохо:
/api/users/11111/cars/33333/door/2222
Такие адреса нелегко читать и искать в документации, часто это вообще не имеет смысла — идентификаторы уникальные и «/cars/33333» абсолютно однозначно относится к «/users/111111». Данный вариант следует сократить:
/api/cars/33333/door/22222
Следует различать 2 основных семейства статус кодов (HTTP Status Code):
4xx — проблема возникла на стороне пользователя и он сам может ее исправить, правильно введя необходимую для запроса информацию.
5xx — проблема возникла на сервере и для ее решения пользователь может отправить запрос к службе поддержки.
Ошибки должны быть четко описаны, чтобы не только пользователь знал, что ему необходимо сделать, но и вы легко ориентировались, если пользователь присылает вам запрос для решения проблемы.
Пример хорошо написанного ответа на ошибку:
HTTP Status Code: 401
{«status»: 401, «message»: «Authentication Required», «code»: 20003, «more_info»: «http://www.example.com/docs/errors/20003»}
Помните! Вы пишете API для таких же разработчиков как и Вы.
Используйте необходимый минимум статус кодов в приложении.
Иногда может быть достаточно 3:
Если мало, дополняйте по мере необходимости:
Старайтесь оценить пользу от каждого добавленного Вами элемента для пользователя. Помните, что большое количество, особенно ненужных элементов, способно запутать даже опытных разработчиков.
В некоторых случаях полезно иметь параметр для подавления статус кода ошибки, что бы клиент всегда, при необходимости, мог получить код 200, например.
PUT /api/users/111111?supress_status_code=200
Это добавит нелишней гибкости Вашему API.
Обязательно указывайте номер версии, даже если не планируете изменение интерфейса — все может быстро измениться.
варианты осуществления версионности

в урл, в заголовках
Версию можно указать в строке адреса:
/api/v2/users/11111
или в параметрах запроса:
/api/users/11111?v=2
Нет смысла делать длинными названия версий, вставлять в них точки: v1.03
Версии интерфейса должны меняться максимально редко, в то время как внутреннюю логику работы API можно менять, как только появилась необходимость. В реальности настоящая версия API может быть, например, v2.011-beta2, но версия интерфейса, и, соответственно, представленная в адресе версия будет просто 2.
Любая коллекция, какой бы маленькой, по Вашему мнению, она не была должна отдаваться постранично. Определитесь с форматом выдачи коллекции, например, Content-Type: application/json {«data»:{}, «paging»: {«limit»: 50, «offset»: 0, «total»: 150}} старайтесь всегда использовать одинаковый формат во всех ответах приложения — облегчите жизнь и себе и разработчикам клиентского ПО.
Стоит выбрать какие-то дефолнные значения для параметров «limit», «offset», и, скорее всего, ограничивать максимальное значение для «limit».
Если в Вашем GET запросе необходимо использовать различные фильтры — поместите их за знаком вопроса (в параметрах URL):
GET /api/users?limit=10&offset=4&age=30&height=180&weight=80
Позвольте клиенту получать только те поля в запросе, которые ему нужны:
GET /api/users/11111?fields=fitst_name,last_name,age,gender,finger_count
Не ограничивайтесь каким-то одним форматом. Сделайте опционально несколько, например, json и xml. Таким легким способом можно значительно упростить разработку для клиентов, и отпадет необходимость выбора чего-то одного. Формат возвращаемых данных можно описывать как в HTTP заголовках, так и в строке запроса:
ACCEPT: application/json
GET /api/users/11111.json
И обязательно стоит выбрать какой-то формат по умолчанию.
Так же существуют Бинарные и более современные технологии: BSON, CBOR, MessagePack.
Требования к формату представления данных, используемые в REST API:
бинарный;
быстрый (с поддержкой Zero-copy);
без схемы;
поддерживаются существующие в JSON типы для конвертации.
Например MessagePack, позволяет ускорить прак тически на половину относительно JSON, что позволит увеличить вовлеченность или конверсию.
BSON хранит длины для строк и бинарных данных, позволяя пропускать атрибуты, которые нам не интересны. JSON же последовательно считывает данные и не может попускать элемент, не прочитав его значение до конца. Таким образом, если мы будем хранить большие объемы бинарных данных внутри формата, данная особенность может сыграть для нас важную роль
Формат полностью совместим с JSON, It’s like JSON. but fast and small. При конвертации данных из MessagePack в JSON мы не потеряем данные, чего нельзя сказать, например, про формат BSON. Правда, есть ряд ограничений, накладываемых на различные типы данных:


Компромиссы каждого варианта кодирования и сжатия можно сравнить друг с другом на диаграмме рассеяния. Эффективность по Парет , показанный красной линией на графике, потенциально дает нам наиболее оптимальные решения: Эффективность по Парето По сути, нижний левый угол — это то, к чему мы стремились: небольшой размер и короткое время кодирования и декодирования.
Это один из немногих видов ресурса, которому суждено остаться глаголом. Имею в виду глобальный поиск.
GET /api/search?q=some+text+to+find+now
Опять же в зависимости от системы используемого поискового движка можно применять различные фильтры.
Какой-то локальный поиск, в пределах коллекции, можно осуществить и простыми фильтрами:
GET /api/users?q=some+users+to+find+now
Используйте, по возможности, последнюю версию OAuth — OAuth 2.0 — эта система хорошо известна разработчикам, и хорошо себя зарекомендовала. Зачем выдумывать велосипед?
Это один из самых важных аспектов хорошего API. Время, потраченное на хорошую документацию, с лихвой окупятся долгими месяцами работы службы поддержки. Фокус прост — опишите сжато и четко все получаемые и отдаваемые данные, а также назначение методов. Помните! Вы пишете для программистов. Не стоит описывать какие-то очевидные моменты. Приведите все отдаваемые статус коды; перечислите все принимаемые параметры опишите их, где необходимо; давайте ссылки на более подробный материал; приводите примеры получаемых данных, если это уместно, с их описанием.
Старайтесь отдавать в ответах ссылки на все связанные ресурсы, если хотите соответствовать принципу HATEOAS, и называться RESTful. За это Вас будут очень любить разработчики клиентских программ — им не придется самим генерировать эти ссылки.
Фасад Паттерн для API.
Разработку любого API следует начинать с детальной проработки интерфейса. Фактически к началу написания кода на руках должны быть все URI Вашего API с подробной документацией всех параметров каждого доступного для данного URI метода, со всеми возвращаемыми статус кодами и форматами возвращаемых данных. В идеале, этот интерфейс уже не должен меняться в ходе дальнейшей разработки. Такой подход в значительной степени облегчает и ускоряет работу над основным кодом API, и позволяет параллельно писать клиентское ПО уже на самых начальных этапах разработки.
Помните! Интерфейс API должен быть максимально простым и понятным, только так можно достичь счастья и гармонии.
Термин HATEOAS означает фразу «Hypermedia As The Engine Of Application State» (Гипермедиа как двигатель состояния приложения). Чтобы понять это глубже, нам сначала нужно понять значение гипермедиа. Взгляните на следующую веб-страницу:

Когда браузер загружает страницу, вы определенно можете увидеть весь контент, который может предложить эта страница. Что еще более интересно, страница также позволяет вам выполнять множество действий с этими данными, например:
Теперь давайте посмотрим, как ведут себя наши REST API:
Если вы посмотрите на типичный запрос GET к RESTful серверу, такой как этот:

Запрос GET localhost:8080/users получает набор данных трех пользователей в этом случае. Отправив запрос с помощью GET localhost:8080/users/1, вы получите сведения только о первом пользователе. Как правило, когда мы выполняем запрос REST, мы получаем только данные, а не какие-либо действия с ними. Вот где HATEOAS восполняет пробел. Запрос HATEOAS позволяет вам не только отправлять данные, но и указывать связанные действия:

Этот пример был в формате JSON. Формат XML для другого примера будет выглядеть примерно так:

Когда вы отправляете этот запрос для получения данных учетной записи, вы получаете оба:
С HATEOAS запрос на REST ресурс дает мне как данные, так и действия, связанные с данными.
Единственная самая важная причина для HATEOAS — слабая связь (loose coupling). Если потребителю службы REST необходимо жестко закодировать все URL-адреса ресурсов, он тесно связан с реализацией вашей службы. Вместо этого, если вы вернете URL-адреса, которые он может использовать для действий, он будет слабосвязанным. Нет строгой зависимости от структуры URI, так как она указана и используется в ответе. Несколько важных тем, связанных с HATEOAS:
При разработке службы RESTful необходимо указать, как возвращать данные и ссылки, соответствующие запросу. HAL — это формат, который обеспечивает простой и согласованный способ гиперссылки между ресурсами в вашем REST API. Вот пример:

С HAL у вас есть несколько категорий представлений:
Если вам довелось использовать Spring Framework для разработки REST сервиса, то Spring HATEOAS — хороший механизм для вашего сервиса.
swagger.io Swagger уже разрабатывают достаточно давно. Это программное решение для генерации документации .
В качестве разметки используется JSON которую можно сгенерировать из PHP docs, так же на основе этого JSON файла можно автоматически сгенерировать как код клиента так и код сервера (прототипный ) на разных языках програаамирования, что существуенно ускорит разработку или внедрение тестирования.

postman.com Платформа совместной работы для разработки API и многие другие
Чтобы оценить, насколько ваш API соответствует REST‑принципам, Леонард Ричардсон предложил модель зрелости из четырех уровней (см. рис. 2).

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

2. Какой HTTP-метод используется для полного обновления существующего ресурса в REST API?
Подсказка PUT обычно заменяет ресурс полностью.
3. Какой HTTP-метод применяется для удаления ресурса?
Подсказка DELETE удаляет ресурс по указанному URI.
4. Какой формат данных чаще всего используется для обмена данными в REST API?
Подсказка JSON является наиболее распространенным форматом для REST API.
5. Какой статус-код HTTP означает успешное создание ресурса?
Подсказка 201 Created используется после успешного создания ресурса.
6. Какой статус-код означает, что ресурс не найден?
Подсказка 404 возвращается, если ресурс отсутствует.
7. Какая функция Laravel используется для регистрации API маршрутов?
Подсказка apiResource автоматически создает REST маршруты для API контроллера.
8. В каком файле Laravel обычно определяются API маршруты?
Подсказка файл routes/api.php предназначен для API маршрутов.
9. Какой класс в Laravel используется для создания API ресурсов (трансформации моделей)?
Подсказка JsonResource используется для форматирования ответа API.
10. Какой HTTP статус-код обычно возвращается при успешном запросе GET?
Подсказка 200 OK означает успешное выполнение запроса.
11. Какой метод контроллера в Laravel обычно отвечает за создание нового ресурса через API?
Подсказка store используется для сохранения нового ресурса.
12. Какой метод контроллера используется для получения одного ресурса?
Подсказка show возвращает конкретный ресурс по ID.
13. Какой middleware в Laravel чаще всего используется для защиты API с токенами?
Подсказка auth:api используется для аутентификации API запросов.
14. Какой метод Eloquent используется для создания новой записи в базе?
Подсказка create создает новую запись в таблице.
15. Какой метод используется для частичного обновления ресурса в REST API?
Подсказка PATCH обновляет только часть ресурса.
16. Что означает принцип stateless в REST API?
Подсказка Stateless означает, что сервер не хранит состояние клиента между запросами.
17. Какой HTTP-заголовок сообщает серверу формат данных, который ожидает клиент?
Подсказка Accept используется для указания желаемого формата ответа.
18. Какой HTTP-заголовок используется для передачи типа данных тела запроса?
Подсказка Content-Type указывает формат данных, например application/json.
19. Какой helper Laravel используется для возврата JSON ответа?
Подсказка response()->json() формирует JSON ответ для API.
20. Какой HTTP метод чаще всего используется для создания нового ресурса в REST API?
Подсказка POST используется для создания новых ресурсов.
21. Какой метод контроллера Laravel обычно отвечает за обновление ресурса?
Подсказка update используется для изменения существующего ресурса.
22. Какой метод контроллера используется для удаления ресурса?
Подсказка destroy является стандартным методом REST контроллеров Laravel.
23. Какой artisan-командой создается API контроллер?
Подсказка параметр --api создает контроллер без методов create и edit.
24. Какой механизм Laravel используется для проверки входящих данных в API?
Подсказка Validation проверяет данные перед сохранением.
25. Какой класс Laravel используется для создания кастомных правил валидации?
Подсказка класс Rule позволяет создавать собственные правила проверки.
26. Какой middleware защищает API маршруты с помощью токена Laravel Sanctum?
Подсказка Sanctum используется для аутентификации API через токены.
27. Какой метод Eloquent используется для поиска записи по ID?
Подсказка find() возвращает модель по первичному ключу.
28. Какой метод Eloquent возвращает первую найденную запись?
Подсказка first() возвращает первый результат запроса.
29. В чем основное отличие между HTTP-запросами GET и POST?
GET передает данные в теле запроса, а POST — в URL.GET используется для получения данных, а POST — для отправки данных на сервер. *GET всегда безопасен и идемпотентен, а POST всегда небезопасен и неидемпотентен.GET поддерживается только браузерами, а POST — только API.Подсказка
GET: применяется для получения данных. Параметры передаются в строке запроса (URL).
POST: используется для отправки данных на сервер. Данные передаются в теле запроса.
Важно: GET считается безопасным и идемпотентным, а POST — неидемпотентным, так как может изменять состояние сервера.
30. Какой принцип REST означает, что у каждого ресурса есть уникальный URL?
Подсказка Uniform Interface предполагает уникальные URI для ресурсов.
31. Если REST API возвращает список пользователей по адресу /users, какой адрес логично использовать для получения пользователя с ID = 25?
Подсказка В REST ресурсы обычно имеют иерархическую структуру URL.
32. Если API возвращает HTTP статус 401, что это обычно означает?
Подсказка 401 означает, что пользователь не авторизован.
33. Какой из следующих URL лучше соответствует REST стилю для получения заказов пользователя?
Подсказка В REST вложенные ресурсы отражают иерархию данных.
34. Если API возвращает код 500, где скорее всего проблема?
Подсказка 500 означает внутреннюю ошибку сервера.
35. Какой из следующих ответов лучше подходит для успешного удаления ресурса?
Подсказка При удалении часто возвращают статус без тела ответа.
36. Если Laravel API должен вернуть ошибку валидации, какой HTTP код наиболее корректен?
Подсказка 422 используется при некорректных данных запроса.
37. Представьте API интернет-магазина. Какой маршрут наиболее логичен для получения товаров категории?
Подсказка REST строит URI вокруг ресурсов.
38. Если API возвращает слишком много данных, какой подход лучше использовать?
Подсказка Пагинация ограничивает количество записей в ответе.
39. Какой параметр Laravel запроса чаще всего используется для пагинации?
Подсказка page используется стандартной пагинацией Laravel.
40. Если API возвращает HTTP код 403, что это означает?
Подсказка 403 означает, что доступ запрещен.
41. Если клиент отправил PATCH /users/10, что логично ожидать от сервера?
Подсказка PATCH изменяет только часть ресурса.
42. Если API возвращает JSON массив, что чаще всего это означает?
Подсказка Массив обычно используется для списков данных.
43. Если разработчик делает API для мобильного приложения, какой подход лучше?
Подсказка JSON удобен для большинства клиентских приложений.
44. Если API должен быть масштабируемым, какой принцип REST помогает этому?
Подсказка Stateless упрощает горизонтальное масштабирование.
45. Если Laravel API должен вернуть ответ после создания ресурса, что лучше вернуть?
Подсказка REST API обычно возвращает созданный объект в JSON.
46. Если API должен позволять клиенту получить только нужные поля объекта (например только name и price), какой подход наиболее логичен?
Подсказка Многие API позволяют выбирать поля через query параметры.
47. Если клиент отправляет слишком много запросов за короткое время, какой механизм обычно применяют?
Подсказка Rate limiting ограничивает количество запросов.
48. Если API возвращает код 429, что это означает?
Подсказка 429 Too Many Requests связан с ограничением запросов.
49. Представьте API картографии. Какой URL лучше описывает координаты города?
Подсказка REST использует ресурсы и вложенность.
50. Если API должен позволять клиенту фильтровать результаты, какой способ наиболее типичен?
Подсказка Например /products?price_min=10.
51. Если API возвращает заголовок ETag, для чего он используется?
Подсказка ETag помогает клиенту понять, изменился ли ресурс.
52. Если API должен позволять клиенту получать только новые данные после последнего запроса, какой подход наиболее логичен?
Подсказка Например параметр updated_after.
53. Представьте API социальной сети. Какой URL лучше отражает лайки поста?
Подсказка В REST действия обычно выражаются через ресурсы.
54. Если API возвращает HTTP код 304, что это означает?
Подсказка 304 используется при проверке кэша.
55. Если API должен поддерживать разные языки ответов, какой подход лучше?
Подсказка Accept-Language позволяет клиенту указать язык.
56. Если API должен передавать большие файлы, какой подход лучше использовать?
Подсказка Передача частями помогает работать с большими файлами.
57. Если API должен позволять клиенту сортировать данные, какой параметр логичен?
Подсказка Например /products?sort=price.
58. Представьте API библиотеки. Какой URL лучше отражает книги автора?
Подсказка REST использует вложенные ресурсы.
59. Если API должен возвращать ошибки в стандартном формате, что обычно используют?
Подсказка Часто используется структура error + message.
60. Если API должен поддерживать разные версии, какой подход наиболее распространен?
Подсказка Например /api/v1/users.
61. Передаются ли данные фрагмента после символа # (анкора) в URL на сервер при HTTP-запросе?
62. Какие методы HTTP считаются идемпотентными?
Объяснение: Идемпотентные методы — это такие, которые при многократном выполнении одного и того же запроса не изменяют состояние сервера. К ним относятся:
GET (чтение ресурса),HEAD (чтение заголовков),PUT (обновление ресурса по URI),DELETE (удаление ресурса),OPTIONS (запрос доступных методов),TRACE (диагностика).Важно понимать: идемпонентность относится к состоянию ресурса, а не к ответу сервера. Ответы могут отличаться (например, первый DELETE вернет 200 OK, а второй — 404 Not Found), но итоговое состояние системы одинаково — ресурса больше нет.
Метод POST не является идемпотентным, так как каждый вызов может создавать новые ресурсы или изменять состояние сервера по-разному.
63. Какие методы HTTP относятся к безопасным (safe)?
Безопасные методы — это такие, которые не изменяют состояние сервера. Они предназначены только для получения информации или диагностики:
GET — получение ресурса.HEAD — получение заголовков.OPTIONS — запрос доступных методов.TRACE — диагностический метод.
Методы POST, PUT, DELETE, PATCH изменяют состояние сервера и поэтому не считаются безопасными.
64. Безопасные методы — это такие, которые не изменяют состояние сервера. Они предназначены только для получения информации или диагностики:
Методы POST, PUT, DELETE, PATCH изменяют состояние сервера и поэтому не считаются безопасными.
Объяснение:
В HTML спецификации для form допустимы только два значения атрибута method:
GET — данные формы добавляются в строку запроса (query string).
POST — данные формы отправляются в теле запроса.
Другие методы (PUT, DELETE, OPTIONS) не поддерживаются напрямую в стандартных HTML-формах. Их можно использовать только через JavaScript (например, с fetch или XMLHttpRequest).
65. Почему метод HTTP PATCH считается не идемпотентным по сравнению с идемпотентным PUT?
66. Как обычно решается недостаток REST API, связанный с Over-fetching (лишние данные) и Under-fetching (не хватает данных)?

67. Как решается проблема большого количества endpoint-ов в REST API?

69. Как обычно решается проблема плохой поддержки сложной бизнес-логики в REST API (например, /orders/123/confirm-and-pay, что выглядит не REST-ово)?
70. Как обычно решается проблема большого количества сетевых запросов, из-за которых мобильное приложение может тормозить?

Комментарии
Оставить комментарий
Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)