首頁 > php框架 > Laravel > 主體

怎麼在Laravel中動態隱藏API字段

藏色散人
發布: 2021-03-25 09:02:32
轉載
2252 人瀏覽過

下面由laravel教學欄位給大家介紹怎麼在 Laravel 中動態隱藏 API 字段,希望對需要的朋友有幫助!

怎麼在Laravel中動態隱藏API字段

在Laravel 中動態隱藏API 欄位

我最近在Laravel Brasil 社群中看到一個問題,結果比看起來更有趣。想像你有一個UsersResource 用下面的實作:

<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class UsersResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            &#39;id&#39; => $this->id,
            'name' => $this->name,
            'email' => $this->email
        ];
    }
}
登入後複製

出於某種原因,您可能希望在另一個端點上重新使用該資源類,但隱藏email 欄位。這篇文章就是告訴你如何實現這一點的。
如果你不知道  API Resources 是什麼,請查看我之前關於這個的文章。

  • First Impression on API Resources
  • API Resources with Nested Relationship

1- 初始化專案

#有趣的東西從第3節開始.

composer create-project --prefer-dist laravel/laravel api-fields
cd api-fields
touch database/database.sqlite
登入後複製

編輯.env文件,刪除資料庫設定並使用SQLite

DB_CONNECTION=sqlite
登入後複製

繼續設定項目

php artisan migrate
php artisan make:resource UsersResource
php artisan make:resource --collection UsersResourceCollection 
php artisan make:controller UsersController
php artisan tinker
factory(App\User::class)->times(20)->create();
quit
登入後複製

2- 路由

確保在api.php 檔案中建立一個路由。

Route::apiResource('/users', 'UsersController');
登入後複製

3- 控制器

控制器代表了期望的目標。在這個例子中,讓我們假設在使用者清單中,我們只想要所有使用者的名字,而在使用者顯示中,我們只想隱藏電子郵件地址。

<?php
namespace App\Http\Controllers;
use App\Http\Resources\UsersResource;
use App\User;
class UsersController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param User $user
     * @return \Illuminate\Http\Response
     */
    public function index(User $user)
    {
        return UsersResource::collection($user->paginate())->hide(['id', 'email']);
    }
    /**
     * Display a user.
     *
     * @param User $user
     * @return \Illuminate\Http\Response
     */
    public function show(User $user)
    {
        return UsersResource::make($user)->hide(['id']);
    }
}
登入後複製

為了達到這個目的,我們需要 UsersResourceCollectionUsersResource 同時知道如何處理  hide 呼叫。

4-  UsersResource 類別

讓我們從 show 方法開始. UsersResource::make 將會傳回  UsersResource 的物件. 因此,我們應該揭開 hide 的神秘面紗,它可以儲存我們期望從回應中移除的鍵.

<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class UsersResource extends Resource
{
    /**
     * @var array
     */
    protected $withoutFields = [];
   
     /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return $this->filterFields([
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email
        ]);
    }
    /**
     * Set the keys that are supposed to be filtered out.
     *
     * @param array $fields
     * @return $this
     */
    public function hide(array $fields)
    {
        $this->withoutFields = $fields;
        return $this;
    }
    /**
     * Remove the filtered keys.
     *
     * @param $array
     * @return array
     */
    protected function filterFields($array)
    {
        return collect($array)->forget($this->withoutFields)->toArray();
    }
}
登入後複製

大功告成! 現在我們可以存取http: //api.dev/api/users/1 ,你會發現回應中已經沒有id 欄位了。

{
 "data": {
  "name": "Mr. Frederik Morar",
  "email": "darryl.wilkinson@example.org"
 }
}
登入後複製

5-  UsersResourceCollection 類別

執行專案集合中的index 方法, 我們需要做出以下修改:

  • #(1) 確保UsersResource::collection 回傳 UsersResourceCollection 實例
  • (2)  在 UsersResourceCollection 上公開 hide 方法
  • #(3) 傳遞隱藏的欄位給 
UsersResource

#關於(1), 我們只需要重寫  UsersResource

# 中的

collection  方法

<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class UsersResource extends Resource
{
    public static function collection($resource)
    {
        return tap(new UsersResourceCollection($resource), function ($collection) {
            $collection->collects = __CLASS__;
        });
    }
    
    /**
     * @var array
     */
    protected $withoutFields = [];
    /**
     * Transform the resource into an array.
     * 将资源转换为一个数组
     * 
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return $this->filterFields([
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email
        ]);
    }
    /**
     * Set the keys that are supposed to be filtered out.
     *  设置需要隐藏过滤掉的键
     *  
     * @param array $fields
     * @return $this
     */
    public function hide(array $fields)
    {
        $this->withoutFields = $fields;
        return $this;
    }
    /**
     * Remove the filtered keys.
     * 删除隐藏的键
     * 
     * @param $array
     * @return array
     */
    protected function filterFields($array)
    {
        return collect($array)->forget($this->withoutFields)->toArray();
    }
}
登入後複製
關於(2) 和(3) 我們需要修改 UsersResourceCollection 檔案. 讓我們公開 

hide 方法並使用隱藏欄位處理集合。 .

<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UsersResourceCollection extends ResourceCollection
{
    /**
     * @var array
     */
    protected $withoutFields = [];
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return $this->processCollection($request);
    }
    public function hide(array $fields)
    {
        $this->withoutFields = $fields;
        return $this;
    }
    /**
     * Send fields to hide to UsersResource while processing the collection.
     *  将隐藏字段通过 UsersResource 处理集合
     * 
     * @param $request
     * @return array
     */
    protected function processCollection($request)
    {
        return $this->collection->map(function (UsersResource $resource) use ($request) {
            return $resource->hide($this->withoutFields)->toArray($request);
        })->all();
    }
}
登入後複製
就是這麼簡單! 現在我們訪問http://api.dev/api/users  看到回傳結果中沒有了id 和 # email 字段瞭如在

UsersController

 中的指定方法.

{
 "data": [{
  "name": "Mr. Frederik Morar"
 }, {
  "name": "Angel Daniel"
 }, {
  "name": "Brianne Mueller"
 }],
 "links": {
  "first": "http://lab.php71/api-fields-2/public/api/users?page=1",
  "last": "http://lab.php71/api-fields-2/public/api/users?page=7",
  "prev": null,
  "next": "http://lab.php71/api-fields-2/public/api/users?page=2"
 },
 "meta": {
  "current_page": 1,
  "from": 1,
  "last_page": 7,
  "path": "http://api-fields.lab.php71/api/users",
  "per_page": 3,
  "to": 3,
  "total": 20
 }
}
登入後複製
6- 總結本文目標是讓Resource類別透過隱藏一些在其他介面允許暴露的欄位從而變得更加靈活。例如當我們請求/users介面時回應的資料是不包含avatar欄位的,但是當請求/users/99時回應的資料裡包含

avatar

欄位。
我不建議過度重複去請求API資源,因為它很可能會把簡單的事情變得更加複雜,所以說在請求的時候隱藏某些特定的字段是更簡單、更合理的解決方案。

推薦:
最新的五個Laravel影片教學
#########

以上是怎麼在Laravel中動態隱藏API字段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板