0

I need to format the data field of the Laravel API response in order to make it a dictionary. I am using Laravel Resources.

At the moment the result is

{
    "data": [
        {
            "id": 1,
            "title": "Qui enim rerum."
        },
        {
            "id": 2,
            "title": "Vel praesentium sit."
        },
        ....
    ],
    "links": {
        "first": "http://localhost:8000/api/articles?page=1",
        "last": "http://localhost:8000/api/articles?page=6",
        "prev": null,
        "next": "http://localhost:8000/api/articles?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 6,
        "path": "http://localhost:8000/api/articles",
        "per_page": 5,
        "to": 5,
        "total": 30
    }
}

And I am pretty fine with all the json.

But I want the 'data' field to be a dictionary-like:

"data": {
        "1", {
            "id": 1,
            "title": "Qui enim rerum."
        },
        "2", {
            "id": 2,
            "title": "Vel praesentium sit."
        },
        ....
    }

Doing so, I can access directly to the item I want without iterate over the array. Is there a way to do this using Laravel Resource (maybe not, but keeping the "links" and "meta")?

Thanks.

Yaser Darzi
  • 1,480
  • 12
  • 24

2 Answers2

1

Laravel API Resources are intended as a layer between Eloquent and the JSON response. So they follow the "rules" of the Model / Collection classes since the final scope is to have a JSON representation "out of the box" of these two classes.

In order to achieve your goal you should not use the API Resources, but you can always create a "default" way for all your collections. In my opinion the best way is creating a trait so you can reuse it in each controller you need. Something like this:

trait CustomJsonResponse
{

  function toJsonResponse($collection)
  {
    $data = [];

    foreach($collection as $model) {
      $data[$model->id] = $model->toArray
    }

    return response()->json([
      'data' => $model
      'links' => [...],
      'meta' => [...]
    ])
  }
}

For the links and the meta part, just have a look at the PaginatedResourceResponse source code so you can reuse the part of code required to reproduce the same result.

IlGala
  • 3,331
  • 4
  • 35
  • 49
  • Seems to be the best solution, can you be more specific about the links and the meta fields? – Massimo Lavermicocca Oct 02 '19 at 14:01
  • Well the "easy way" is to copy&paste the `paginationLinks` and `meta` methods from the `PaginatedResourceResponse` as well as the code in the `paginationInformation` method (the `return ['links' => $this->paginationLinks($paginated), 'meta' => $this->meta($paginated),];`) – IlGala Oct 02 '19 at 14:09
0

You can format the JSON however you want by building it out as an array in PHP and json_encode()ing it for the return (which Laravel does for you if you return only the data). Something like this (caveat: untested, coding while in the browser):

$results = Model::all();

$data = [];

foreach($results as $entry)
{
    $data[strval($entry->id)] = [
        'id' => $entry->id,
        'title' => $entry->title,
        'other' => $entry->other
    ];
}

return $data;   // or explicitly: return json_encode($data);
Erich
  • 2,408
  • 18
  • 40