fomvasss
@fomvasss
PHP developer

Как правильно возвращать JSON с контроллеров Laravel для API приложения?

Разрабатываю приложения с RESTFull API на Laravel. Посоветуйте, как правильнее будет реализовать форматирование и возврат данных в JSON формате с контроллеров Laravel ?
В большинстве обучающих примеров, которые я видел, возвращалась просто модель:
public function show($id)
{
   $post =  \App\Models\Post::findOrFail($id);
   return $post;
}


В результате на фронте получаем JSON-массив:
{
    "id": 1,
    "name": "Пример статьи",
    "slug": "primer,
    "body":"",
    "category_id":1
    "created_at": "2017-08-23 14:26:41",
    "updated_at": "2017-08-23 14:26:41",
    "deleted_at": null,  
}


Еще делают так:
public function create(Request $request)
{
   //...
   return response()->json(['success' => true, 'data' = 'Данные успешно сохранены']);
}


Проблемы и вопросы при таком подходе:
1. В большинстве случаев, на фронтенде нам не надо показывать всех полей таблицы (category_id, updated_at, deleted_at,...). Каждый раз вручную массив в каждом контроллере, мне кажется не совсем будет правильно...
2. А что, если нам нужно, например к статьям вытянуть все комментарии (только также без лишних полей)
3. Нужно вытянуть все категории -> их статьи -> их комментарии
4. Нужно определенные поля вывести в определенном формате, например дату.

Для работы с данными использую паттерн "репозиторий". На фронтенде, пока что планируется, сайт на vue.js.

Может кто-то использует пакет spatie/laravel-fractal , какие будут отзывы, рекомендации.

Хотелось бы увидеть хорошие примере разработки таких систем и какие инструменты там используются.
  • Вопрос задан
  • 5365 просмотров
Решения вопроса 1
Alex_Wells
@Alex_Wells
PHP/Kotlin
Использую laravel-fractal. В последней версии league/fractal, на основе которого и построен spatie/fractalistic, добавили тип primitive и все стало на свои места.

Конечно, не обошлось без танцев с бубном: я сделал для нужных моделей трейт Transform, который добавляет метод toApi (хотя лучше бы назвал transform), берущий класс из переменной $transformer:
87111fa7d0a346ff90c34a7c902d37b5.png
И пришлось написать макрос для collection ларавельной, тоже toApi(). Хотя без обеих этих фич можно обойтись, используя fractal($items, $transformer).

В остальном же полностью доволен.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Kostik_1993
Web Developer
1. Для того чтобы какие-то поля модели не отображались нужно использовать переменную hidden, с помощью нее мы указываем какие поля не должны отображаться в JSON ответе.
protected $hidden = [
        'type_id',
        'created_at',
        'updated_at',
    ];

2. У каждой модели вы должны указать свои поля которые должны быть скрыты
protected $hidden = [
        'type_id',
        'created_at',
        'updated_at',
    ];

3. Category::with('posts.comments')->get();
4. Для этого также есть специальные переменные и методы.
Также доступен такой метод
public function getDateAttribute () {
        return date('Y-M-D', $this->date);
    }
public function getUrlAttribute () {
        return url($this->slug);
    }

этот метод выведет $post->date в нужном формате
чтобы такой метод был доступен в json нужно указать его в
protected $appends = [
        'url',
        'topic',
    ];
Ответ написан
Комментировать
@artemmityushov
Оба предложенных варианта имеют свои плюсы и минусы. Добавил бы 3 вариант вывода через Formatters, мы его в основном используем, как минимум чтобы точно контролировать что приходит на апи.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы