Стандартизация ответов API без трейтов
Проблема
Заметил я, что большая часть библиотек, созданных для апи респонса, реализованы через трейты, остальная часть — огромные библиотеки. В этих трейтах реализованы методы под всё, что только можно (response, accepted, created, forbidden...)
Таким образом, если в моём контроллере 1-2 метода, то, подключая такой трейт, я имею в классе кучу ненужного мусора. В паре больших библиотек на 700+ звёзд я вижу overengineering на уровне UX (для себя, как для пользователя библиотеки)
Что делать?
Написать свою библиотеку!
Я решил создать такую логику обработки данных, чтобы на пользовательском уровне требовалось:
минимум действий
имелась простота использования
читаемость
То есть для получение стандартизированного респонса, всё, что нам нужно, это вернуть респонс через объект библиотеки
Итого, базовый минимум, который у нас есть сразу после установки библиотеки, это:
Успешный ответ:
Ответ с ошибкой:
На выходе при успешном ответе имеем распаковку формата в виде: response.data.entities
По-умолчанию формат актуален в контексте REST, то есть для методов show()
и update()
ответ будет формата: response.data.entity
Глубокое погружение
Конечно, для любителей кастомизации и копания в конфигах я так же создал песочницу кода, с которым можно поиграться
Возможности
Любимый нами сахар
Обёртка над response()
метдом для пагинации:
Метод paginated()
принимает два основных параметра:
В своей логике резолвит их и добавляет в ответ по ключу meta
— ключ pagination
Интерфейсы ответа в соответствии с форматом, возвращаемым Laravel:
В итоге ответ получается формата:
Обёртка над response()
метдом для кодов ответа:
Работа с разными типами параметра
Первый аргумент метода response()
может быть типов array|Arrayable
, поэтому можно маппить данные перед передачей в метод в рамках этих типов. К примеру:
Кастомизация через конфиг
Сам конфиг:
отключение
using_for_rest
оставляет возвращаемый формат всегдаresponse.data.entities
(мн. ч.) не зависимо от метода, из которого происходит вызовс помощью
methods_for_singular_key
можно пополнить список методов, в которых будет возвращаться ключ в ед. ч.methods_for_singular_key
, собственно, добавляет заголовок в запросы по классике:$request->headers->set('Accept', 'application/json');
Кастомизация через атрибуты
Блокировка значений using_for_rest
и methods_for_singular_key
в конфиге для установки ключа ответа в соответствии с singular_data_key
По аналогии можно передать своё назавние ключа
В итоге
Осноанвя потребность закрыта: я хотел иметь возможность просто поставить библиотеку, и просто иметь из коробки лаконичный базис для стандартизации формата ответа. Без лишних движений.
И, конечно, как возможностей для лишних движений (кастомизация), так и ненасыпанного сахара — ещё очень много, так что в доработке библиотеки всё впереди) но основной посыл я точно сохраню! Ибо, как гласят великие мемы истории: