3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
Laravel Eloquent API Resources PHP:7.2 Laravel:5.8 當我們利用 Laravel 在設計 API 時,通常都會透過 Eloquent Model 取得資料,並將資料轉換成 JSON 格式輸出。 比如在 Controller 中就會像這樣回傳: return response()->json([ 'status' => 200, 'data' => [ 'meta' => SongModel::find($songID) ] ]); 然而,這裡隱藏著幾個缺點: 重複的格式定義: 類似的 endpoint 可能都有類似的格式定義,可是卻散落在 Controller 各處。 format 不固定: 因為是直接將 model 輸出,如果資料表有更動的話,API 會直接受到衝擊。 為了因應以上問題,Laravel 在 5.5 之後提供了 API Resources 讓大家更方便的自訂輸出格式,建立 Model 與 Output 之間的橋樑。 Basic Usage Artisan 提供了命令列可以直接建立 Resource。 php artisan make:resource SongResource 產生後便可以在 app\Http\Resources 看到 SongResource 檔案。 namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class SongResource extends JsonResource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return parent::toArray($request); } } 由於 Resource 是繼承自 JsonResource,因此輸出就會是 JSON 的格式內容,而我們要做的就是修改 toArray() method 當中的格式: public function toArray($request) { return [ 'song_id' => $this->song_id, 'song_name' => $this->song_name, 'artist_id' => $this->artist_id, 'album_id' => $this->album_id, ]; } 接著只要在 Route 或 Controller 中直接輸出就可以了。 Controller namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Song; use App\Http\Resources\SongResource; class TestController extends Controller { public function test() { $model = SongModel::find($songID); // 直接 return Resource return new SongResource($model); // 也可以自行設定 HTTP code return (new SongResource($model)) ->response() ->setStatusCode(200); } } Route use App\Song; use App\Http\Resources\SongResource; Route::get('/songs/{song}', function(Song $song) { return new SongResource($song); }); Output { "data":{ "song_id":301231008, "song_name":"TEST", "artist_id":3182, "album_id":30497178, } } Collection 接下來問題來了,很多時候我們會取得資源的清單,比如說 SongModel::all(),直接使用 Resource 會出現錯誤訊息,因為丟進去的是一個 Collection ,並不是物件本身。 此時需要搭配 Resource::collection() 使用,它會將 Collection 中的所有 Model 物件自動套用 Resource 的格式。 Controller Exmaple namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Song; use App\Http\Resources\SongResource; class TestController extends Controller { public function test() { $collection = SongModel::all(); return SongResource::collection($collection); } } 當然,也可以定義一些 Collection 的資料在 Resource 之中: app/Http/Resources/SongResource public function toArray($request) { return [ // 傳入 collection 'data' => $this->collection, 'count' => $this->collection->count() ]; } Relationships 既然用到了 Eloquent Model,必定會用到一些 relation 去取得不同張表的資料;對於 Resource 來說,我們必須將這些資源都一一拆開,一來具備開發彈性、二來這些資源也可重複使用。 舉例來說,如果透過 SongModel 關聯出 Album 跟 Artist,可以設計成以下這樣: app/Http/Resources/ArtistResource public function toArray($request) { return [ 'artist_id' => $this->artist_id, 'artist_name' => $this->artist_name ]; } app/Http/Resources/AlbumResource public function toArray($request) { return [ 'album_id' => $this->album_id, 'album_name' => $this->album_name ]; } app/Http/Resources/SongResource public function toArray($request) { return [ 'song_id' => $this->song_id, 'song_name' => $this->song_name, 'artist_id' => $this->artist_id, 'album_id' => $this->album_id, 'artist' => new Artist($this->artist), 'album' => new Album($this->album) ]; } Controller Exmaple namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Song; use App\Http\Resources\SongResource; class TestController extends Controller { public function test() { $collection = SongModel::with(['album', 'artist'])->all(); return SongResource::collection($collection); } } Categories: Laravel Tags: LaravelPHP 分類 Android AngularJS API Blueprint Chrome Database MySQL DataStructure Editor Vim Firefox Git Hadoop Language Go Java JavaScript jQuery jQueryChart Node.js Vue PHP Laravel ZendFramework Python Mac Network Cisco DLink Juniper Oauth Server Apache Share Unix FreeBSD Linux WebDesign Bootstrap CSS HTML Wordpress Search 搜尋:

本文由blogjohnsonluorg提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦