> For the complete documentation index, see [llms.txt](https://capsbold.gitbook.io/guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://capsbold.gitbook.io/guide/rest-api.md).

# REST API

Руководств по созданию отзывчивого REST API

REST становится общим подходом для представления сервисов окружающему миру. Причина его популярности заключается в его простоте, легкости использования, доступе через HTTP и другие.

## Версионность

Любое программное обеспечение развивается с течением времени. Это может потребовать различных версий для всех существенных изменений в приложении. Когда дело доходит до версии REST приложения, то оно становится одной из самых обсуждаемых тем среди сообщества разработчиков REST.

* `api/v1/`
* `api/v2/`

...и так далее.

## Документация

Ваш REST API должен быть хорошо задокументирован. В этом вам поможет Postman. [См. руководство Postman](https://learning.postman.com/docs/getting-started/introduction/).

<figure><img src="https://1460737902-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Flmcyf2jqPljzBUS6Qodz%2Fuploads%2FTxjLiPliLoFwLcnMufrK%2Fimage.png?alt=media&amp;token=a5b782ee-7c57-40ab-93b5-cbee3927bb99" alt=""><figcaption><p>Скриншот документации API одного из проектов</p></figcaption></figure>

## HTTP методы

Ниже представлены две характеристики, которые должны быть определены перед использованием HTTP метода:

* **Безопасность:** HTTP метод считается безопасным, когда вызов этого метода не изменяет состояние данных. Например, когда вы извлекаете данные с помощью метода GET, это безопасно, потому что этот метод не обновляет данные на стороне сервера.
* **Идемпотентность:** когда вы получаете один и тот же ответ, сколько раз вы вызываете один и тот же ресурс, он известен как идемпотентный. Например, когда вы пытаетесь обновить одни и те же данные на сервере, ответ будет таким же для каждого запроса, сделанного с одинаковыми данными.

Не все методы являются безопасными и идемпотентными. Ниже представлен список методов, которые используются в REST приложениях и показаны их свойства:

| HTTP метод | Безопасный | Идемпотентный |
| ---------- | :--------: | ------------- |
| GET        |      ✅     | ✅             |
| POST       |      ❌     | ❌             |
| PUT        |      ❌     | ✅             |
| DELETE     |      ❌     | ✅             |
| OPTIONS    |      ✅     | ✅             |
| HEAD       |      ✅     | ✅             |

Ниже приведен краткий обзор каждого метода и рекомендации по их использованию:

* GET: этот метод является безопасным и идемпотентным. Обычно используется для извлечения информации и не имеет побочных эффектов.
* POST: этот метод не является ни безопасным, ни идемпотентным. Этот метод наиболее широко используется для создания ресурсов.
* PUT: этот метод является идемпотентным. Вот почему лучше использовать этот метод вместо POST для обновления ресурсов. Избегайте использования POST для обновления ресурсов.
* DELETE: как следует из названия, этот метод используется для удаления ресурсов. Но этот метод не является идемпотентным для всех запросов.
* OPTIONS: этот метод не используется для каких-либо манипуляций с ресурсами. Но он полезен, когда клиент не знает других методов, поддерживаемых для ресурса, и используя этот метод, клиент может получить различное представление ресурса.
* HEAD: этот метод используется для запроса ресурса c сервера. Он очень похож на метод GET, но HEAD должен отправлять запрос и получать ответ только в заголовке. Согласно спецификации HTTP, этот метод не должен использовать тело для запроса и ответа.

#### Различия между PUT и PATCH

Запрос `PUT` заменит все содержимое ресурса в приложении, в то время как запрос `PATCH` используется для внесения изменений в часть ресурса, редко используется.

## Использование SSL

SSL должен быть! Вы всегда должны применять SSL для своего REST приложения. Доступ к вашему приложения будет осуществляется из любой точки мира, и нет никакой гарантии, что к нему будет обеспечен безопасный доступ. С ростом числа инцидентов с киберпреступностью мы обязательно должны обеспечить безопасность своему приложению.

Стандартные протоколы проверки аутентификации облегчают работу по защите вашего приложения. Не используйте базовый механизм аутентификации. Используйте OAuth2 для лучшей безопасности ваших сервисов.

## Best Practice

### Шаблоны конечных точек URL

#### CRUD - `модель` в множественном числе

```
// Все посты
[GET] /posts

// Конкретный пост
[GET] /posts/:id

// Добавление поста
[POST] /posts

// Изменение поста
[PUT] /posts/:id

// Удаление поста
[DELETE] /posts/:id
```

#### Нестандартные методы - `действие` + `модель` ИЛИ `тип данных`

```
// экспорт всех постов с указанием формата
[GET] /export/posts?type=xml

// массовое удаление постов
[DELETE] /delete/posts?id=1,2,5,7

// добавление в друзья
[PUT] /friends/:uid

// удаление из друзей 
[DELETE] /friends/:uid

// добавление товара в избранное
[POST] /product-favorites
```

### Пагинация

Отправка большого объема данных через HTTP не очень хорошая идея. Безусловно, возникнут проблемы с производительностью, поскольку сериализация больших объектов JSON станет дорогостоящей. Best practice является разбиение результатов на части, а не отправка всех записей сразу. Предоставьте возможность разбивать результаты на странице с помощью `_limit` или `_page` параметров.

### Коды ответов HTTP

HTTP определяет различные коды ответов для указания клиенту различной информации об операциях. Ваше REST приложение могло бы эффективно использовать все доступные HTTP-коды, чтобы помочь клиенту правильно настроить ответ. Далее представлен список кодов ответов HTTP:

* 200 OK — это ответ на успешные GET, PUT, PATCH или DELETE. Этот код также используется для POST, который не приводит к созданию.
* 201 Created — этот код состояния является ответом на POST, который приводит к созданию.
* 204 Нет содержимого. Это ответ на успешный запрос, который не будет возвращать тело (например, запрос DELETE)
* 304 Not Modified — используйте этот код состояния, когда заголовки HTTP-кеширования находятся в работе
* 400 Bad Request — этот код состояния указывает, что запрос искажен, например, если тело не может быть проанализировано
* 401 Unauthorized — Если не указаны или недействительны данные аутентификации. Также полезно активировать всплывающее окно auth, если приложение используется из браузера
* 403 Forbidden — когда аутентификация прошла успешно, но аутентифицированный пользователь не имеет доступа к ресурсу
* 404 Not found — если запрашивается несуществующий ресурс
* 405 Method Not Allowed — когда запрашивается HTTP-метод, который не разрешен для аутентифицированного пользователя
* 410 Gone — этот код состояния указывает, что ресурс в этой конечной точке больше не доступен. Полезно в качестве защитного ответа для старых версий API
* 415 Unsupported Media Type. Если в качестве части запроса был указан неправильный тип содержимого
* 422 Unprocessable Entity — используется для проверки ошибок
* 429 Too Many Requests — когда запрос отклоняется из-за ограничения скорости

Возможно, что-то упустили в списке. Думайте также сами.

### Время в формате ISO 8601

формат: YYYY-MM-DDTHH:MM:SSZ

### `snake_case` имена полей

Например, `created_at`, `has_like`, `display_name`

### Согласованный ответ API

Ваше REST API приложение должно возвращать всегда ответ в виде:

```json
{
    "data": [], // и {}/null, если сущность одна
    "message": "Локализированное сообщение API",
    "status": 200
}
```

### Ошибки валидации вида `errors.prop[]`

Ошибки валидации выдавать в виде:

```json
{
    "errors": {
        "name": [
            "Поле Имя Обязательно для заполнения.",
            "Поле Имя должно иметь больше 6 символов."
        ]
    },
    "message": "Ошибка валидации",
    "status": 422
}
```

## GET-параметры по общему функционалу

Имена, приведённые ниже, совпадают с полями [json-server](https://www.npmjs.com/package/json-server), что упростит и ускорит разработку FrontEnd специалистам.

### Пагинация

```
GET /posts?_page=7
GET /posts?_page=7&_limit=20
```

### Фильтр

Использовать `.` для доступа к глубинным свойствам

```
GET /posts?title=json-server&author=typicode
GET /posts?id=1&id=2
GET /comments?author.name=typicode
```

### Сортировка

```
GET /posts?_sort=views&_order=asc
GET /posts/1/comments?_sort=votes&_order=asc
```

### Срез

Добавьте `_start` и `_end` или `_limit` (также включите `X-Total-Count` заголовок в ответ)

```
GET /posts?_start=20&_end=30
GET /posts/1/comments?_start=20&_end=30
GET /posts/1/comments?_start=20&_limit=10
```

### Операторы

Добавьте `_gte` или `_lte` для получения диапазона

```
GET /posts?likes_gte=10&likes_lte=20
```

Добавьте `_ne`, чтобы исключить значение

```
GET /posts?id_ne=1
```

Добавить `_like` в фильтр (поддержка RegExp)

```
GET /posts?title_like=server
```

### Поиск текста

Добавьте `q`

```
GET /posts?q=internet
```

### Отношения

Чтобы включить дочерние ресурсы, добавьте `_embed`

```
GET /posts?_embed=comments
GET /posts/1?_embed=comments
```

Чтобы включить родительский ресурс, добавьте `_expand`

```
GET /comments?_expand=post
GET /comments/1?_expand=post
```

Чтобы получить или создать вложенные ресурсы (по умолчанию один уровень, добавьте пользовательские маршруты для большего)

```
GET  /posts/1/comments
GET /user/1/posts
```
