1. 程式人生 > >Laravel構建API伺服器之響應資料處理

Laravel構建API伺服器之響應資料處理

這篇文章主要講述在使用Laravel構建API服務時,如何利用Laravel生態社群中的第三方元件對響應的資料進行處理。

(不做相關詳細使用方法的介紹)

相關元件:

1. dingo/api:一個為了更加快速、方便的構建Restful API而生的Laravel、Luman元件:其中集成了API限流設定、API版本控制、根據註釋生成API文件、響應資料轉換(包含了對laravel-fractal的支援)等多項功能的元件。

2. spatie/laravel-fractal: 一個響應轉換器,為API響應的資料根據不同的邏輯、場景進行資料轉換。

首先對於多人開發的Laravel API應用,我們不得不考慮的是:

  1. 響應的資料格式是否統一

  2. 響應的資料格式對前端是否友好

  3. 後端人員在開發API時,如何更好的控制對於不同介面的資料響應格式

以上介紹到的元件很好的解決了這些問題,通過Fractal元件,對不同模型產生的資料編寫對應的Transformer資料轉換器,在整個Laravel API應用之中加入一個資料轉換層,讓我們的Controller只關注業務邏輯,而對於要響應什麼樣的資料、響應資料的敏感資訊的過濾(例如使用者密碼等)則轉交給Transformer層來進行統一處理,可以很大程度上降低程式碼耦合度以及對於不同介面響應的資料格式的統一處理。

程式碼片段:

1. 起步 

  安裝通過composer安裝 dingo/api 以及 spatie/laravel-fractal 元件 根據相關文件進行配置

2. 程式碼編寫

  假定我們目前在開發一個使用者列表介面,首先編寫控制器方法的邏輯

  UserController.php

namespace App\Http\Controllers\Api;

use App\User;
use App\Http\Controllers\Controller;

class UserController extends Controller
{

    /**
     * 使用者列表介面
     */
    public function index()
    {
      $users = User::all();
    }

}

   所有使用者資料已經通過Eloquent模型所查詢出,此時,建立我們的Transformer

   對於Transformer檔案的位置,我們可以自定義,我的做法是在app/Http目錄下建立Response/Transformers目錄,用以存放所有的Transformers

   UserTransformer.php:

<?php

namespace App\Http\Response\Transformers;

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

class UserTransformer extends TransformerAbstract
{
    public function transform(User $user)
    {
        // 返回的陣列則代表了真實要響應的json資料
        // 在這裡,你可以選擇響應該模型下的不同的資料欄位、更改響應的欄位名稱隱藏資料庫中真實的欄位名以及欄位值的其它轉換
        return [
            'id' => $user->id,
            'name' => $user->name,
            'signature' => $user->signature,
            'created_at' => $user->created_at->toDateTimeString()
        ];
    }
}

  使用這個Transformer:

namespace App\Http\Controllers\Api;

use App\User;
use App\Http\Controllers\Controller;

# 匯入Transformer名稱空間
use App\Http\Response\Transformers\UserTransformer;

class UserController extends Controller
{

    /**
     * 使用者列表介面
     */
    public function index()
    {
      $users = User::all();

      return $this->response->collection($users, new UserTransformer());
    }

}

響應:

{
    "data": [
        {
            "id": 1,
            "name": "張三",
            "signature": "Hello, World",
            "created_at": "2018-11-02 16:21:20"
        },
        {
            "id": 2,
            "name": "李四",
            "signature": "這個人很懶...什麼也沒有留下",
            "created_at": "2018-11-02 16:21:20"
        }
    ],
    "meta": {
        // ...自動生成的元資料,如果你查詢出的資料帶有分頁資料(laravel中的Paginate)
        // 那麼Transformer將會自動幫你把分頁資料加入在此處
    }
}