Q:

Restructure Eloquent Collection for better API access

I'm working on a REST API based on Elequent ORM. 
My query returns something like this when requesting a single object:
$data = $this->select('objects.*')->where('id', '=', $id)->get();

The collection:
[
    {
        "id": 3414,
        "type": 3,
        "title": "Title",
        "shorttext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.", 
        "spacetext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.", 
        "description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." 

    }
]

So i would like to change the structure the API returns into something like this:
[
    {
        "id": 3414,
        "type": 3,
        "text" {
            "title": "Title",
            "shorttext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.", 
            "spacetext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.", 
            "description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." 
        }

    }
]

In that ways the structure is a bit more transparent for the access user.  This should of course work also when requesting not only a single object via GET but also a list of objects. 
I tried using eloquent mapping collections via mapToGroups() but i got nowhere.  
Before using Eloquent i was using Medoo.  There i just had to enter a schema array like this and everything was done:
$this->schema = [
        'id', 
        'type',
        'text' => [
            'title',
            'shorttext',
            'spacetext',
            'description'
        ],
        'prices' => [
            'baseprice',
            '...

Is there a good way of achieving this with eloquent? 

A:

It depends what version of Laravel you are using.  For older versions (5.4 and below) of Laravel there is a great simple package called Fractal that will help achieve what you are looking for.  

Fractal provides a presentation and transformation layer for complex
  data output, the like found in RESTful APIs, and works really well
  with JSON. 

Here is a sample of that code a work:
<? php namespace App\Transformer;

use Acme\Model\Book;
use League\Fractal\TransformerAbstract;

class BookTransformer extends TransformerAbstract
{
    /**
     * List of resources possible to include
     *
     * @var array
     */
    protected $availableIncludes = [
        'author'
    ];

    /**
     * Turn this item object into a generic array
     *
     * @return array
     */
    public function transform(Book $book)
    {
        return [
            'id'    => (int) $book->id,
            'title' => $book->title,
            'year'    => (int) $book->yr,
            'links'   => [
                [
                    'rel' => 'self',
                    'uri' => '/books/'.$book->id,
                ]
            ],
        ];
    }

    /**
     * Include Author
     *
     * @return \League\Fractal\Resource\Item
     */
    public function includeAuthor(Book $book)
    {
        $author = $book->author;

        return $this->item($author, new AuthorTransformer);
    }
}

In newer versions (5.5+) you can use the Eloquent Resources concept. 

A resource class represents a single model that
  needs to be transformed into a JSON structure.  For example, here is a
  simple resource class:

<? php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class SampleModel extends JsonResource
{
    /**
     * Transform the resource into an array. 
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'type' => $this->type,
            'text' => [
                'title' => $this->title,
                'short_text' => $this->short_text,
            ],
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

