搜尋
首頁後端開發php教程PHP Fractal-使您的API json變得漂亮,永遠!

PHP Fractal - Make Your API's JSON Pretty, Always!

本文經Viraj Khatavkar同行評審。感謝所有SitePoint的同行評審員,使SitePoint的內容達到最佳狀態!


如果您之前構建過API,我敢打賭您習慣於直接將數據作為響應輸出。如果操作正確,這可能不會造成危害,但有一些實際的替代方案可以幫助解決這個問題。

其中一個可用的解決方案是Fractal。它允許我們在將模型作為響應返回之前,為模型創建一個新的轉換層。它非常靈活,易於集成到任何應用程序或框架中。

PHP Fractal - Make Your API's JSON Pretty, Always!

關鍵要點

  • PHP Fractal是一種解決方案,允許開發人員在將模型作為響應返回之前為其模型創建新的轉換層,從而使JSON數據更易於管理和保持一致性。
  • Fractal靈活且易於集成到任何應用程序或框架中。它的工作原理是使用Transformer將復雜的數據結構轉換為更簡單的格式,並使用Serializer來格式化最終輸出。
  • Fractal還允許在用戶請求時包含子資源(關係)到響應中,從而為數據呈現增加了另一層靈活性和控制。
  • 使用Fractal可以通過一次性急切加載關係來優化查詢性能,從而解決了Eloquent延遲加載經常遇到的n 1問題。

安裝

我們將使用Laravel 5.3應用程序來構建示例並將Fractal包與其集成,因此請繼續使用安裝程序或通過Composer創建一個新的Laravel應用程序。

<code>laravel new demo</code>

<code>composer create-project laravel/laravel demo</code>

然後,在文件夾內,我們需要Fractal包。

<code>composer require league/fractal</code>

創建數據庫

我們的數據庫包含users和roles表。每個用戶都有一個角色,每個角色都有一個權限列表。

// app/User.php

class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',
        'role_id',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function role()
    {
        return $this->belongsTo(Role::class);
    }
}
// app/Role.php

class Role extends Model
{
    protected $fillable = [
        'name',
        'slug',
        'permissions'
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function users()
    {
        return $this->hasMany(User::class);
    }
}

創建Transformer

我們將為每個模型創建一個Transformer。我們的UserTransformer類如下所示:

// app/Transformers/UserTransformer.php

namespace App\Transformers;

use App\User;
use League\Fractal\TransformerAbstract;

class UserTransformer extends TransformerAbstract
{
    public function transform(User $user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email
        ];
    }
}

是的,創建Transformer就這麼簡單!它只是以開發人員可以管理的方式轉換數據,而不是留給ORM或存儲庫。

我們擴展TransformerAbstract類並定義transform方法,該方法將使用User實例調用。 RoleTransformer類也是如此。

namespace App\Transformers;

use App\Role;
use League\Fractal\TransformerAbstract;

class RoleTransformer extends TransformerAbstract
{
    public function transform(Role $role)
    {
        return [
            'name' => $role->name,
            'slug' => $role->slug,
            'permissions' => $role->permissions
        ];
    }
}

創建控制器

我們的控制器應該在將數據發送回用戶之前轉換數據。我們現在將處理UsersController類,暫時只定義index和show操作。

// app/Http/Controllers/UsersController.php

class UsersController extends Controller
{
    /**
     * @var Manager
     */
    private $fractal;

    /**
     * @var UserTransformer
     */
    private $userTransformer;

    function __construct(Manager $fractal, UserTransformer $userTransformer)
    {
        $this->fractal = $fractal;
        $this->userTransformer = $userTransformer;
    }

    public function index(Request $request)
    {
        $users = User::all(); // 从数据库获取用户
        $users = new Collection($users, $this->userTransformer); // 创建资源集合转换器
        $users = $this->fractal->createData($users); // 转换数据

        return $users->toArray(); // 获取转换后的数据数组
    }
}

index操作將從數據庫查詢所有用戶,使用用戶列表和轉換器創建一個資源集合,然後執行實際的轉換過程。

{
  "data": [
    {
      "name": "Nyasia Keeling",
      "email": "crooks.maurice@example.net"
    },
    {
      "name": "Laron Olson",
      "email": "helen55@example.com"
    },
    {
      "name": "Prof. Fanny Dach III",
      "email": "edgardo13@example.net"
    },
    {
      "name": "Athena Olson Sr.",
      "email": "halvorson.jules@example.com"
    }
    // ...
  ]
}

當然,一次返回所有用戶是沒有意義的,我們應該為此實現分頁器。

分頁

Laravel傾向於簡化事情。我們可以像這樣實現分頁:

<code>laravel new demo</code>

但是為了使這與Fractal一起工作,我們可能需要添加一些代碼來轉換數據,然後再調用分頁器。

<code>composer create-project laravel/laravel demo</code>

第一步是從模型分頁數據。接下來,我們像以前一樣創建一個資源集合,然後在集合上設置分頁器。

Fractal為Laravel提供了一個分頁器適配器來轉換LengthAwarePaginator類,它還為Symfony和Zend提供了一個適配器。

<code>composer require league/fractal</code>

請注意,它為分頁詳細信息添加了額外的字段。您可以在文檔中閱讀更多關於分頁的信息。

包含子資源

現在我們已經熟悉了Fractal,是時候學習如何在用戶請求時包含子資源(關係)到響應中了。

我們可以請求包含額外資源到響應中,例如http://demo.vaprobash.dev/users?include=role。我們的轉換器可以自動檢測正在請求的內容並解析include參數。

// app/User.php

class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',
        'role_id',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function role()
    {
        return $this->belongsTo(Role::class);
    }
}

$availableIncludes屬性告訴轉換器我們可能需要包含一些額外的數據到響應中。如果include查詢參數請求用戶角色,它將調用includeRole方法。

// app/Role.php

class Role extends Model
{
    protected $fillable = [
        'name',
        'slug',
        'permissions'
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function users()
    {
        return $this->hasMany(User::class);
    }
}

$this->fractal->parseIncludes行負責解析include查詢參數。如果我們請求用戶列表,我們應該看到類似這樣的內容:

// app/Transformers/UserTransformer.php

namespace App\Transformers;

use App\User;
use League\Fractal\TransformerAbstract;

class UserTransformer extends TransformerAbstract
{
    public function transform(User $user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email
        ];
    }
}

如果每個用戶都有一個角色列表,我們可以將轉換器更改為如下所示:

namespace App\Transformers;

use App\Role;
use League\Fractal\TransformerAbstract;

class RoleTransformer extends TransformerAbstract
{
    public function transform(Role $role)
    {
        return [
            'name' => $role->name,
            'slug' => $role->slug,
            'permissions' => $role->permissions
        ];
    }
}

包含子資源時,我們可以使用點表示法嵌套關係。假設每個角色都有一個存儲在單獨表中的權限列表,並且我們想列出具有其角色和權限的用戶。我們可以這樣做include=role.permissions。

有時,我們需要默認包含一些必要的關聯,例如地址關聯。我們可以通過在轉換器中使用$defaultIncludes屬性來實現。

// app/Http/Controllers/UsersController.php

class UsersController extends Controller
{
    /**
     * @var Manager
     */
    private $fractal;

    /**
     * @var UserTransformer
     */
    private $userTransformer;

    function __construct(Manager $fractal, UserTransformer $userTransformer)
    {
        $this->fractal = $fractal;
        $this->userTransformer = $userTransformer;
    }

    public function index(Request $request)
    {
        $users = User::all(); // 从数据库获取用户
        $users = new Collection($users, $this->userTransformer); // 创建资源集合转换器
        $users = $this->fractal->createData($users); // 转换数据

        return $users->toArray(); // 获取转换后的数据数组
    }
}

我最喜歡Fractal包的一件事是能夠將參數傳遞給include參數。文檔中的一個很好的例子是按順序排列。我們可以將其應用到我們的示例中,如下所示:

{
  "data": [
    {
      "name": "Nyasia Keeling",
      "email": "crooks.maurice@example.net"
    },
    {
      "name": "Laron Olson",
      "email": "helen55@example.com"
    },
    {
      "name": "Prof. Fanny Dach III",
      "email": "edgardo13@example.net"
    },
    {
      "name": "Athena Olson Sr.",
      "email": "halvorson.jules@example.com"
    }
    // ...
  ]
}

這裡重要的部分是list($orderCol, $orderBy) = $paramBag->get('order') ?: ['created_at', 'desc'];,這將嘗試從用戶include獲取order參數,並將其應用於查詢構建器。

我們現在可以通過傳遞參數來按順序排列包含的用戶列表(/roles?include=users:order(name|asc))。您可以在文檔中閱讀更多關於包含資源的信息。

但是,如果用戶沒有任何關聯的角色會怎樣?它將停止並出現錯誤,因為它期望的是有效數據而不是null。讓我們從響應中刪除該關係,而不是顯示其null值。

<code>laravel new demo</code>

急切加載

因為Eloquent在訪問模型時會延遲加載模型,所以我們可能會遇到n 1問題。這可以通過一次性急切加載關係來解決,以優化查詢。

<code>composer create-project laravel/laravel demo</code>

這樣,在訪問模型關係時,我們將不會有任何額外的查詢。

結論

我在閱讀Phil Sturgeon撰寫的《構建你不會討厭的API》時偶然發現了Fractal,這是一本很棒且內容豐富的讀物,我強烈推薦。

您在構建API時是否使用過轉換器?您是否有任何首選的執行相同工作的包,或者您只是使用json_encode?請在下面的評論部分告訴我們!

PHP Fractal常見問題解答

什麼是PHP Fractal,為什麼它很重要?

PHP Fractal是一個強大的工具,有助於為API呈現和轉換數據。它很重要,因為它提供了一種標準化的方法來輸出複雜、嵌套的數據結構,確保API的數據輸出一致、結構良好且易於理解。這使得開發人員更容易使用您的API,並減少了出錯的可能性。

PHP Fractal是如何工作的?

PHP Fractal的工作原理是獲取複雜的數據結構並將其轉換為更易於使用的格式。它通過兩個主要組件來實現:Transformer和Serializer。 Transformer負責將復雜的數據轉換為更簡單的格式,而Serializer則格式化最終輸出。

PHP Fractal中的Transformer是什麼?

PHP Fractal中的Transformer是定義應用程序數據應如何在API響應中輸出的類。它們獲取複雜的數據結構並將它們轉換為更簡單、更易於使用的格式。這允許您精確控制API響應中包含哪些數據以及數據的結構。

PHP Fractal中的Serializer是什麼?

PHP Fractal中的Serializer負責格式化API的最終輸出。它們獲取已由Transformer轉換的數據,並將其格式化為特定的結構。這允許您確保API的輸出一致且易於理解。

我如何在項目中實現PHP Fractal?

在項目中實現PHP Fractal包括通過Composer安裝Fractal庫,為數據創建Transformer,然後使用Fractal類使用Transformer轉換數據。然後,您可以使用Fractal的Serializer之一輸出轉換後的數據。

我可以將PHP Fractal與任何PHP項目一起使用嗎?

是的,PHP Fractal是一個獨立的庫,可以與任何PHP項目一起使用。它不依賴於任何特定的框架或平台,這使得它成為任何PHP開發人員的通用工具。

使用PHP Fractal的好處是什麼?

使用PHP Fractal提供了許多好處。它確保API的輸出一致且結構良好,使開發人員更容易使用。它還提供了一種標準化的方法來轉換複雜的數據結構,減少了出錯的可能性,並使代碼更容易維護。

PHP Fractal與其他數據轉換工具相比如何?

PHP Fractal以其簡單性和靈活性而脫穎而出。它提供了一種直接的方法來轉換複雜的數據結構,並且它使用Transformer和Serializer允許高度定制。這使得它成為任何使用API的開發人員的強大工具。

我可以自定義PHP Fractal的輸出嗎?

是的,PHP Fractal是高度可定制的。您可以創建自定義Transformer來精確控制數據的轉換方式,並且您可以使用不同的Serializer以不同的方式格式化輸出。這允許您根據您的特定需求調整API的輸出。

我在哪裡可以了解更多關於PHP Fractal的信息?

有很多資源可以幫助您了解更多關於PHP Fractal的信息。官方PHP League網站提供了全面的文檔,並且網上有許多教程和博文。此外,PHP Fractal GitHub存儲庫是一個探索代碼並查看其使用方法示例的好地方。

以上是PHP Fractal-使您的API json變得漂亮,永遠!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
高流量網站的PHP性能調整高流量網站的PHP性能調整May 14, 2025 am 12:13 AM

TheSecretTokeEpingAphp-PowerEdwebSiterUnningSmoothlyShyunderHeavyLoadInVolvOLVOLVOLDEVERSALKEYSTRATICES:1)emplactopCodeCachingWithOpcachingWithOpCacheToreCescriptexecution Time,2)使用atabasequercachingCachingCachingWithRedataBasEndataBaseLeSendataBaseLoad,3)

PHP中的依賴注入:初學者的代碼示例PHP中的依賴注入:初學者的代碼示例May 14, 2025 am 12:08 AM

你應該關心DependencyInjection(DI),因為它能讓你的代碼更清晰、更易維護。 1)DI通過解耦類,使其更模塊化,2)提高了測試的便捷性和代碼的靈活性,3)使用DI容器可以管理複雜的依賴關係,但要注意性能影響和循環依賴問題,4)最佳實踐是依賴於抽象接口,實現鬆散耦合。

PHP性能:是否可以優化應用程序?PHP性能:是否可以優化應用程序?May 14, 2025 am 12:04 AM

是的,優化papplicationispossibleandessential.1)empartcachingingcachingusedapcutorediucedsatabaseload.2)優化的atabaseswithexing,高效Quereteries,and ConconnectionPooling.3)EnhanceCodeWithBuilt-unctions,避免使用,避免使用ingglobalalairaiables,並避免使用

PHP性能優化:最終指南PHP性能優化:最終指南May 14, 2025 am 12:02 AM

theKeyStrategiestosigantificallyBoostPhpaPplicationPerformenCeare:1)UseOpCodeCachingLikeLikeLikeLikeLikeCacheToreDuceExecutiontime,2)優化AtabaseInteractionswithPreparedStateTementStatementStatementAndProperIndexing,3)配置

PHP依賴注入容器:快速啟動PHP依賴注入容器:快速啟動May 13, 2025 am 12:11 AM

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增強codemodocultion,可驗證性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

PHP中的依賴注入與服務定位器PHP中的依賴注入與服務定位器May 13, 2025 am 12:10 AM

選擇DependencyInjection(DI)用於大型應用,ServiceLocator適合小型項目或原型。 1)DI通過構造函數注入依賴,提高代碼的測試性和模塊化。 2)ServiceLocator通過中心註冊獲取服務,方便但可能導致代碼耦合度增加。

PHP性能優化策略。PHP性能優化策略。May 13, 2025 am 12:06 AM

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)啟用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替換loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

PHP電子郵件驗證:確保正確發送電子郵件PHP電子郵件驗證:確保正確發送電子郵件May 13, 2025 am 12:06 AM

phpemailvalidation invoLvesthreesteps:1)格式化進行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器