mercredi 3 avril 2019

Laravel resources

I'm trying to figure out a bit on how to use React or Vue with Laravel. The biggest change is returning all your request with json.

So I started looking up some documentation and found information about API Resources

Now my biggest concern is that in my application for example I have following database structure:

  • Invoices
  • Clients
  • Client_contacts
  • Client_contacts_phones

So a client can have multiple invoices as they can have multiple contacts and each contact can have multiple phone numbers.

Now, the reason where I'm stuck is: You can have a list view of all your invoices, but I would love to have the name of the company in one of the table fields and using the same resource file have the full property list on detail view.

Using resources, I've done the following:

InvoicesCollection:

namespace App\Modules\Invoices\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class InvoicesCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return [
            'data' => InvoiceResource::collection($this->collection),
            'meta' => ['invoice_count' => $this->collection->count()],
        ];
    }
}

InvoiceResource:

<?php

namespace App\Modules\Invoices\Resources;

use App\Modules\Clients\Resources\ClientResource;
use Illuminate\Http\Resources\Json\JsonResource;

class InvoiceResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'invoice_id' => $this->invoice_id,
            'client' => new ClientResource($this->client),
            'finalized_at' => $this->finalized_at,
            'payed_at' => $this->payed_at
        ];
    }

    public function with($request)
    {
        return [
            'data' => [
                'client_billing' => $this->client_billing,
                'client_shipping' => $this->client_shipping,
                'line_items' => $this->lineItems,
                'notes' => $this->notes
            ],
        ];
    }
}

ClientsCollection:

<?php

namespace App\Modules\Clients\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ClientsCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return [
            'data' => ClientResource::collection($this->collection),
            'meta' => ['client_count' => $this->collection->count()],
        ];
    }
}

ClientResource:

<?php

namespace App\Modules\Clients\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ClientResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'vat' => $this->vat,
            'contacts' => $this->contacts
        ];
    }

    public function with($request)
    {
        return [
            'data' => [
                'website' => $this->website,
                'phone' => $this->phone,
                'email' => $this->email
            ],
        ];
    }
}

So to clarify, I'm using the with() function. Which states:

Sometimes you may wish to only include certain meta data with a resource response if the resource is the outer-most resource being returned. Typically, this includes meta information about the response as a whole. To define this meta data, add a with method to your resource class. This method should return an array of meta data to be included with the resource response only when the resource is the outer-most resource being rendered


Questions:

  1. Is this the correct way to do this? When you want to exclude info for lists and have a all info on a detailed view?

  2. Is there more control to it? As you can see in my clientResource, I have contacts, when importing them, they'll have all the information. If I add a contact Resource/Collection, I have a third layer, which means I won't be able to have all the data using the ContactResource with() on the same Client-detail page.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire