January 27, 2021

Что такое API Resource в моих проектах Laravel

На примере списка фотографий я расскажу как работает API Resource.

При работе с API предполагается, что всегда передаются заголовки:

Content-Type: application/json
Accept: application/json

Для маршрутов, которые требуют авторизации:

Authorization: Bearer {token}

Где {token} - токен авторизации

Для Front программистов передается ссылка на API Resource, ссылка передается относительно домена сайта.

Пример: /photos

Вот какие URL при этом будут работать:

  • GET /photos, функция index: Получить список всех элементов с пагинацией. Параметры, по которым можно осуществлять фильтрацию будут указаны в блоке meta-filters, там же будет показан пример-объяснение как именно будет примеряется фильтр при передачи значения.
  • GET /photos/create, функция create. Получить пустой экземпляр элемента (его нужно заполнить и передать в функцию store). Это что-то вроде болванки от элемента от index, без заполненных данных.
  • POST /photos, функция store. Создать новый элемент.
  • GET /photos/{id}, функция show. Получить элемент по id. Как правило, внутри show параметров показывается существенно больше, чем в index. Пример: для index будет показан только name (название фото) + preview (адрес маленькой картинки), а уже в show - будут показаны и автор, и характеристики фотографии и другие дополнительные параметры
  • PUT /photos/{id}, функция update. Обновить элемент.
  • DELETE /photos/{id}, функция destroy. Удалить элемент

Если в описании API указано, например, вот так:

api/counties - получить список стран, только index

Это значит, что для этого метода доступно только получение списка

Если в описании написано:

api/counties - получить список стран, только index,show

Значит кроме списка - можно получить еще и сам элемент по id, например:

GET api/counties/1

Описание структуры API ответа

При получении одного элемента тело ответа может выглядеть вот так:

{
   "id": 1,
   "name": "Подразделение 1",
   "short_name": "П1",
   "group_id": 1,
   "type_enum": "Подразделение",
   "division_type_enum": "Главное управление",
   "icon_enum": "-",
}

Или вот так, когда ответ завернут в блок data:

{
  "data": {
    "id": 1,
    "name": "Подразделение 1",
    "short_name": "П1",
    "group_id": 1,
    "type_enum": "Подразделение",
    "division_type_enum": "Главное управление",
    "icon_enum": "-",
  }
}

Второй вариант - предпочтительный, так как тогда и ответ в случае метода index (когда показываем список) - тоже будет завернут в блок data.

Пример ответа, когда мы показываем список элементов:

{
  "data": [
    {
      "id": 1,
      "short_name": "П1",
    },
    {
      "id": 2,
      "short_name": "П2",
    }  
  ],
    ...
}

Для функции index есть дополнительные функциональные блоки.

Блок meta-filters:

"meta-filters": {
    "country_id": "country_id = value",
    "per_page": "number of elements per page, default: per_page = 20"
  },

В блоке указано какие фильтры можно применять к списку.

В указанном выше примере - можно передать в качестве GET параметра country_id, что отфильтровать вывод по стране. В описании параметра указано, что будет искаться точное соответствие переданному значению.

per_page - управляет количеством выводимых элементов при постраничной навигации. По-умолчанию - 20.

Блок links:

 "links": {
    "self": "link-value",
    "first": "https://site.ru/api/regions?page=1",
    "last": "https://site.ru/api/regions?page=3",
    "prev": null,
    "next": "https://site.ru/api/regions?page=2"
  },

first - ссылка на получение первой страницы списка
last - ссылка на последнюю страницу списка
prev - ссылка на предыдущую страницу списка
next - ссылка на следующую страницу

Если ссылки нет (например это первая/последняя страница) - то в переменной будет 0

Блок meta:

"meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 1,
    "path": "https://site.ru/api/regions",
    "per_page": 20,
    "to": 3,
    "total": 3
  }

current_page - текущая страница
last_page - номер последней страницы
per_page - сколько элементов на страницу выводить
total - сколько всего страниц

Целиком ответ на метод index может выглядеть, например, вот так:

{
  "data": [
    {
      "id": 1,
      "short_name": "П1",
    },
    {
      "id": 2,
      "short_name": "П2",
    }  
  ],
  "links": {
    "self": "link-value",
    "first": "https://site.ru/api/regions?page=1",
    "last": "https://site.ru/api/regions?page=3",
    "prev": null,
    "next": "https://site.ru/api/regions?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 3,
    "path": "https://site.ru/api/regions",
    "per_page": 20,
    "to": 20,
    "total": 56
  }
  "meta-filters": {
    "country_id": "country_id = value",
    "per_page": "number of elements per page, default: per_page = 20"
  },
}