3分鍾短文:太爽了,用Laravel寫API接口!


引言

我們一直在講,通過路由傳達到控制器,處理好數據並渲染到視圖,但是對於現代的應用,
前后端分離的情況下,后端寫個接口就完事兒了。

img

本期為大家說一說用laravel寫restful風格的API,看看能有多簡單。

以路由開端

寫API接口,與傳統的渲染前端模板頁面有什么區別?少了視圖,只需要准備好數據,
並按照規則格式化,返回就可以了。

laravel默認的api接口路由在 routes/api.php 文件內定義,默認的情況下預定義了一個資源類型的api接口,代碼如下:

Route::middleware('auth:api')->get('/user', function (Request $request) {
	return $request->user();
});

調用了 auth:api 中間件用於驗證用戶的授權,如果授權通過,聲明的get方法獲取用戶的信息,並返回 User 模型。這在之前的章節是很常見的操作,我們不做贅述了。

那么這個路由文件,是什么時候加載上去的呢?在文件 app/Providers/RouteServiceProvider.php 內,看這樣一段:

protected function mapApiRoutes()
{
    Route::prefix('api')
        ->middleware('api')
        ->namespace($this->namespace)
        ->group(base_path('routes/api.php'));
}

該服務提供者聲明路由使用 api 字符前綴,並調用 api 中間件,該中間件定義在 app/Http/Kernel.php 文件內:

protected $middlewareGroups = [
    'api' => [
        'throttle:60,1',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

至於命名空間 $this->namespace 一般返回 App\Http\Controllers,我們為了區分API與其他應用,在目錄 app/Http/Controller 下創建 API 目錄,用於存儲所有API相關的控制器。

那么上述的 RouteServiceProvider.php 文件內 mapApiRoutes 方法內的 namespace 需要這樣寫:

->namespace($this->namespace . '\API')

仍然以 Event 模型作為示例,在 routes/api.php 文件內聲明一個資源類型的路由:

Route::resource('/events', 'API\EventsController');

注意命名空間上多出來的前綴 API\ ,這說明我們是把 EventController 文件放在了 API 目錄下。

用戶權限

讓我們把目光還聚焦在系統默認聲明的那條路由:

Route::middleware('auth:api')->get('/user', function (Request $request) {
	return $request->user();
});

注意中間件 auth:api,因為api請求是無狀態的,每次請求之間沒有任何關聯,所以使用用戶權限區分資源的返回。那么我們怎么拿到用戶授權呢?這在 config/auth.php 文件內定義,看系統自帶的這一段配置代碼:

'guards' => [
    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],
],

這一段定義了我們使用何種方式認證用戶的身份。默認的驅動 token 定義在框架文件 laravel/framework/src/Illuminate/Auth/TokenGuard.php 內。長話短說,默認構造類傳入的字段如下:

UserProvider $provider,
Request $request,
$inputKey = 'api_token',
$storageKey = 'api_token',
$hash = false

簡單說,就是使用 users 表的 api_token 字段用戶鑒權。那么默認我們 users 表顯然缺少一個這樣的字段,現在使用遷移文件補上:

php artisan make:migration add_api_token_field_to_users_table --table=users

首先是遷移方法 up 函數:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
    	$table->string('api_token', 60)->unique();
    });
}

還有回滾使用的 down 方法:

public function down()
{
    Schema::table('users', function (Blueprint $table) {
    	$table->dropColumn('api_token');
    });
}

這些都是常規操作,我們在之前的章節,使用了N多次了。執行指令遷移數據庫:

php artisan migrate

看看效果

准備好了路由,而且路由內聲明了一個get方法返回用戶模型數據。也准備好了數據庫表字段 api_token。我們在數據庫表內找到一個用戶數據,把api_token值設置為 1234,用於測試。

現在在瀏覽器內請求類似如下的url地址:

http://www.example.com/api/user?api_token=1234

如無異常,順利會輸出一個 json 字符串,

{
    "id":1,
    "provider":null,
    "provider_id":null,
    "first_name":"Tom",
    "last_name":"Hanks",
    "email":"tom@admin.com",
    "city":"",
    "state_id":null,
    "zip":"43016",
    "lat":null,"lng":null,
    "timezone":"America\/New_York",
    "title":"Laravel Developer",
    "created_at":"2020-10-14 17:46:19",
    "updated_at":"2020-10-14 17:46:20",
    "last_login_at":null,
    "is_admin":0,
    "api_token":"1234"
}

這個json格式的數據是怎么來的呢?是在路由內,$request->user() 方法返回的User模型,使用 toArray() 格式化方法獲得的。為了演示,很多字段與實際可能有所出入。

特別需要注意的是,關鍵的密碼字段,以及 token 字段,是默認隱藏的,這得益於 User 模型內 $hiden 屬性的定義:

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

這些字段都對對外不公開訪問。

寫在最后

本文介紹了如何聲明api地址,已經解釋了api從中間件到路由的由來,明白了api授權的方式,可以為我們更靈活地定制授權方式提供便利。這在laravel內都是可插拔的,替換為我們的邏輯代碼就可以愉快工作了。

Happy coding 😃

我是@程序員小助手,專注編程知識,圈子動態的IT領域原創作者


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM