1.  安裝一個干凈的 Laravel 5.5 項目

· 使用 Composer 命令 composer create-project laravel/laravel responses dev-develop 來創(chuàng)建一個 Laravel 5.5 項目。這個命令會從 Laravel 官方的存儲庫中下載最新版本的 Laravel 5.5 代碼并安裝到名為 “responses” 的文件夾中。

· cd responses: 進入到新創(chuàng)建的 “responses” 文件夾中。

· touch database/database.sqlite: 創(chuàng)建一個 SQLite 數(shù)據(jù)庫文件,用于存儲數(shù)據(jù)。

php artisan make:model Post -mf: 創(chuàng)建一個名為 “Post” 的 Eloquent 模型,并生成相應(yīng)的遷移文件和工廠。

· php artisan make:resource UsersWithPostsResource: 創(chuàng)建一個名為 “UsersWithPostsResource” 的資源類,用于對用戶及其posts進行處理。

· php artisan make:resource PostsResource: 創(chuàng)建一個名為 “PostsResource” 的資源類,用于對posts進行處理。

· php artisan make:controller UsersController –resource: 創(chuàng)建一個名為 “UsersController” 的控制器,添加了 CRUD(創(chuàng)建、讀取、更新、刪除)操作的資源路由。

· 修改 .env 文件,使用 SQLite 數(shù)據(jù)庫,并刪除其他數(shù)據(jù)庫相關(guān)的變量。

· 添加或修改 DB_CONNECTION=sqlite 來指定 Laravel 使用 SQLite 作為數(shù)據(jù)庫連接。

這些步驟旨在建立一個基本的 Laravel 5.5 項目,并做了一些初始化設(shè)置,包括創(chuàng)建模型、資源類和控制器,并配置使用 SQLite 作為數(shù)據(jù)庫。

2.  準(zhǔn)備數(shù)據(jù)庫

·posts遷移 database/migrations/______create_posts_table.php

Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('body');
$table->unsignedInteger('user_id');
$table->timestamps();
});

這涉及創(chuàng)建posts模型的數(shù)據(jù)庫表結(jié)構(gòu)。在 database/migrations 目錄下的create_posts_table.php 的文件,定義了posts表的字段和結(jié)構(gòu)。這個文件包含了使用 Laravel 的遷移(Migration)功能創(chuàng)建數(shù)據(jù)庫表的代碼。

· posts工廠database/factories/PostFactory.php

<?php
use Faker\Generator as Faker;
$factory->define(App\Post::class,
function (Faker $faker) {
return [
'title' => $faker->sentence,
'body' => $faker->paragraph,
'user_id' => function () {
return factory(\App\User::class);
}
];
});

這一步驟是為了創(chuàng)建一個posts的工廠,用于生成測試數(shù)據(jù)或者用于種子數(shù)據(jù)填充。在 database/factories 目錄下的 PostFactory.php 文件中,你會定義創(chuàng)建posts模型時所用的數(shù)據(jù)格式和規(guī)則。

· 用戶擁有posts的關(guān)系 app/User.php

public function posts(){return $this->hasMany(Post::class);}

這是在用戶模型(User)中定義與posts模型的關(guān)系。也就是在 app 目錄下的 User.php 文件中,你會定義用戶和posts之間的關(guān)聯(lián)關(guān)系,比如一對多關(guān)系(一個用戶有多個posts)或其他關(guān)系。

· 避免批量賦值 app/Post.php

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Post extends Model{protected $guarded = [];}

在 app 目錄下的 Post.php 文件中,通常會有一個模型類,即posts模型(Post)。避免批量賦值是指使用 Laravel 的屬性來指定哪些字段可以被批量賦值,以防止不受控制的數(shù)據(jù)注入。

· 播種數(shù)據(jù)庫

<?php 
artisan migrate:freshphp artisan
tinkerfactory(App\Post::class)->times(2)->create();
factory(App\Post::class)->times(2)->create(['user_id' => 1]);

數(shù)據(jù)庫種子用于向數(shù)據(jù)庫中填充測試數(shù)據(jù)或初始數(shù)據(jù)。這是在開發(fā)或測試階段常用的操作,可以使用 Laravel 的 Seeder 來填充數(shù)據(jù)庫表,確保數(shù)據(jù)庫中有一些初始數(shù)據(jù)可用于開發(fā)和測試。

3.  設(shè)置路由

Route::apiResource('/users', 'UsersController');

4.  重命名資源(修復(fù)遺留問題)

之前創(chuàng)建了一個名為 UsersWithPostsResource 的資源。讓我們將其重命名為 UsersResource,并了解如何在以下步驟中重用它。

5.  在控制器內(nèi)使用API資源

<?php

/**
* Display a listing of the resource.
*
* @param User $user
* @return \Illuminate\Http\Response
*/
public function index(User $user)
{
return UsersResource::collection($user->with('posts')->paginate());
// If you don't want to include the relationship in your response, don't use with()
// return UsersResource::collection($user->paginate());
}

靜態(tài) collection 方法將采用要轉(zhuǎn)換的記錄集合,并確保為每個記錄實例化一個新的UsersResource

6.  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 [
'name' => $this->name,
'email' => $this->email,
'posts' => PostsResource::collection($this->whenLoaded('posts'))
];
}
}

這里的兩個關(guān)鍵部分:屬性訪問器可選的嵌套轉(zhuǎn)換。

Resource 中,可以通過 $this 直接訪問模型的屬性。這個神奇的功能是通過 DelegatesToResource trait 在基礎(chǔ)資源類中實現(xiàn)的。簡單來說,這意味著資源類中可以直接使用 $this->attributeName 的方式訪問模型中的屬性,而不必每次都通過模型實例去獲取屬性。

能夠在資源類中進行關(guān)系的轉(zhuǎn)換,但是有條件:如果數(shù)據(jù)是可用的(已經(jīng)預(yù)加載),就可以進行轉(zhuǎn)換;如果數(shù)據(jù)尚未加載,可以選擇忽略這個轉(zhuǎn)換。這樣做有利于避免 N+1 查詢問題(在獲取關(guān)聯(lián)數(shù)據(jù)時出現(xiàn)的效率問題),同時可以使用單個資源類處理不同的情況。如果關(guān)聯(lián)數(shù)據(jù)不可用,資源類會忽略它;反之,如果可用,資源類會將其包含在返回的數(shù)據(jù)中。

7.  Posts Resource

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class PostsResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'title' => $this->title,
'body' => $this->body
];
}
}

結(jié)論

1.簡化和逐步進行
本文著重于學(xué)習(xí)如何使用 Resource::collection 而不是手動實例化類,并將關(guān)系數(shù)據(jù)的提供(或不提供)責(zé)任委托給控制器。通過在控制器中簡單地移除 with(‘posts’),API 將不再在響應(yīng)中包含每個用戶的posts數(shù)據(jù)。

2.對比 Fractal 和 Laravel 的資源
本文提到 Fractal 在轉(zhuǎn)換層(Transformer)提供了默認(rèn)和可用的包含(includes)功能,但是 Laravel 的原生 API 資源更傾向于讓控制器處理這個邏輯。畢竟,控制器的工作是理解請求。這暗示著對于數(shù)據(jù)包含的處理,Laravel 更多地依賴于控制器層面的邏輯,而不是在資源轉(zhuǎn)換層實現(xiàn)。

總體而言,本文聚焦于利用 Laravel 中的 Resource::collection,并強調(diào)控制器對于處理數(shù)據(jù)關(guān)系包含的重要性。

參考鏈接:

First?impressions?on?Laravel?API?Resources?|?HackerNoon

具有嵌套關(guān)系的可重用?API?資源?—?Laravel?5.5?|由?Marco?Aurélio?Deleu?|HackerNoon.com?|中等?(medium.com)

上一篇:

實踐案例:通過API優(yōu)化加快上市時間

下一篇:

如何在Java、Python、PHP中使用人臉比對API?
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費