Transformers 本文未发布 发布文章

未匹配的标注

Definition & Principles

Read from the Porto SAP Documentation (#Transformers).

Rules

  • All API responses MUST be formatted via a Transformer.
  • Every Transformer SHOULD extend from App\Ship\Parents\Transformers\Transformer.
  • Each Transformer MUST have a transform() function.

Folder Structure

 - app
    - Containers
        - {container-name}
            - UI
                - API
                    - Transformers
                        - UserTransformer.php
                        - ...

Code Samples

Reward Transformer with Country relation:

<?php

namespace App\Containers\Item\UI\API\Transformers;

use App\Containers\Item\Models\Item;
use App\Ship\Parents\Transformers\Transformer;

class ItemTransformer extends Transformer
{

    protected $availableIncludes = [
        'images',
    ];

    protected $defaultIncludes = [
        'roles',
    ];

    public function transform(Item $item)
    {
        $response = [
            'object'      => 'Item',
            'id'          => $item->getHashedKey(),
            'name'        => $item->name,
            'description' => $item->description,
            'price'       => (float)$item->price,
            'weight'      => (float)$item->weight,
            'created_at'  => $item->created_at,
            'updated_at'  => $item->updated_at,
        ];

        // add more or modify data for Admins only
        $response = $this->ifAdmin([
            'real_id'    => $user->id,
            'deleted_at' => $user->deleted_at,
        ], $response);

        return $response;
    }

    public function includeImages(Item $item)
    {
        return $this->collection($item->images, new ItemImageTransformer());
    }

    public function includeRoles(User $user)
    {
        return $this->collection($user->roles, new RoleTransformer());
    }
}

Usage from Controller (Single Item)

<?php

// getting any Model
$user = $this->getUser();

// building the response with the transformer of the Model
$this->response->item($user, new UserTransformer());

// in case of collection of data
$this->response->collection($user, new UserTransformer());

// in case of Array
$this->response->array([
    'custom_field'  =>  'whatever',
    'email'         =>  $user->email,
]);

// more options are available

Usage from Controller (Multiple Items/Collection)

<?php

// getting many Models Paginated
$rewards = $this->getRewards();

// building the response with the transformer of the Model
return $this->response->paginator($rewards, new RewardTransformer());

Relationships (include)

Loading relationships with the Transformer (calling other Transformers):
This can be done in 2 ways:

  1. By the User, he can specify what to relations to return in the response.
  2. By the Developer, define what relations to include at run time.

From Front-end

You can request data with their relationships directly from the API call using include=tags,user. But first the Transformer need to have the availableIncludes defined with their functions like this:

<?php

namespace App\Containers\Account\UI\API\Transformers;

use App\Ship\Parents\Transformers\Transformer;
use App\Containers\Account\Models\Account;
use App\Containers\Tag\Transformers\TagTransformer;
use App\Containers\User\Transformers\UserTransformer;

class AccountTransformer extends Transformer
{
    protected $availableIncludes = [
        'tags',
        'user',
    ];

    public function transform(Account $account)
    {
        return [
            'id'       => (int)$account->id,
            'url'      => $account->url,
            'username' => $account->username,
            'secret'   => $account->secret,
            'note'     => $account->note,
        ];
    }

    public function includeTags(Account $account)
    {
        // use collection with `multi` relationship
        return $this->collection($account->tags, new TagTransformer());
    }

    public function includeUser(Account $account)
    {
        // use `item` with single relationship
        return $this->item($account->user, new UserTransformer());
    }

}

Now to get the Tags with the response when Accounts are requested pass the ?include=tags parameter with the [GET] request.
To get Tags with User use the comma separator: ?include=tags,user.

From Back-end

From the controller you can dynamically set the DefaultInclude using (setDefaultIncludes) anytime you want.

<?php

return $this->response->paginator($rewards, (new ProductsTransformer())->setDefaultIncludes(['tags']));

You need to have includeTags function defined on the transformer. Look at the full examples above.
If you want to include a relation with every response from this transformer you can define the relation directly in the transformer on ($defaultIncludes)

<?php

protected $availableIncludes = [
    'users',
];

protected $defaultIncludes = [
    'tags',
];

// ..

You need to have includeUser and includeTags functions defined on the transformer. Look at the full examples above.

Transformer Available helper functions:

  • user() : returns current authenticated user object.
  • ifAdmin($adminResponse, $clientResponse) : merges normal client response with the admin extra or modified results, when current authenticated user is Admin.
    For more information about the Transformers read this.

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~