Laravel API:在Laravel中建立和測試一個API

Laravel API:在Laravel中建立和測試一個API

Laravel Eloquent是一種簡單的方式來與你的資料庫互動. 它是一個物件關係對映器(ORM),通過提供一個與表互動的模型,簡化了資料庫的複雜性。

因此,Laravel Eloquent有很好的工具來建立和測試API來支援你的開發. 在這篇實踐文章中, 你將看到使用Laravel建立和測試API是多麼容易.

在這個演示中, 你將開始建立一個模型,你可以用它來建立API和資料庫表。然後, 你會看到如何新增一個控制器作為業務邏輯層和一個路由來完成API。然後,你將學習如何使用Postman來執行測試API,最後再重點討論認證和錯誤處理。

  1. 先決條件
  2. API基礎知識
  3. 如何建立一個控制器
  4. 如何建立一個路由
  5. 如何測試一個API
  6. 如何使用Sanctum認證一個API
  7. 如何處理API的錯誤

先決條件

要開始,這裡是你需要的東西:

API基礎知識

首先,使用<code>composer</code>建立一個新的Laravel專案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
composer create-project laravel/laravel laravel-api-create-test
composer create-project laravel/laravel laravel-api-create-test
composer create-project laravel/laravel laravel-api-create-test

要啟動伺服器,執行以下命令,在8000埠執行應用伺服器:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cd laravel-api-create-test
php artisan serve
cd laravel-api-create-test php artisan serve
cd laravel-api-create-test
php artisan serve

你應該看到以下螢幕:

Laravel

Laravel

然後,使用下面的程式碼建立一個帶有 -m 標誌的模型來進行遷移:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan make:model Product -m
php artisan make:model Product -m
php artisan make:model Product -m

現在升級遷移檔案以包括所需欄位。在資料庫/migrations/{date_stamp}_create_products_table.php檔案內新增產品模型的標題和描述欄位以及這兩個表欄位。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$table->string('title');
$table->longText('description');
$table->string('title'); $table->longText('description');
$table->string('title');
$table->longText('description');

下一步是使這些欄位可填充。在app/Models/Product.php中,使 title 和 description 成為可填充欄位。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
protected $fillable = ['title', 'description'];
protected $fillable = ['title', 'description'];
protected $fillable = ['title', 'description'];

如何建立一個控制器

現在,通過執行以下命令為產品建立一個控制器檔案。這將建立app/Http/Controllers/Api/ProductController.php檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan make:controller Api\\ProductController --model=Product
php artisan make:controller Api\\ProductController --model=Product
php artisan make:controller Api\\ProductController --model=Product

現在,新增建立和檢索產品的邏輯。在 index 方法中,新增以下程式碼來檢索所有產品:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$products = Product::all();
return response()->json([
'status' => true,
'products' => $products
]);
$products = Product::all(); return response()->json([ 'status' => true, 'products' => $products ]);
$products = Product::all();
return response()->json([
'status' => true,
'products' => $products
]);

之後,你必須新增一個 StoreProductRequest 類,用於將新產品儲存在資料庫中。在同一檔案的頂部新增以下類。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public function store(StoreProductRequest $request)
{
$product = Product::create($request->all());
return response()->json([
'status' => true,
'message' => "Product Created successfully!",
'product' => $product
], 200);
}
public function store(StoreProductRequest $request) { $product = Product::create($request->all()); return response()->json([ 'status' => true, 'message' => "Product Created successfully!", 'product' => $product ], 200); }
public function store(StoreProductRequest $request)
{
$product = Product::create($request->all());
return response()->json([
'status' => true,
'message' => "Product Created successfully!",
'product' => $product
], 200);
}

現在,你將建立請求,你可以通過執行以下命令來完成:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan make:request StoreProductRequest
php artisan make:request StoreProductRequest
php artisan make:request StoreProductRequest

如果你想新增驗證,你可以使用app/Http/Requests/StoreProductRequest.php檔案。在這個演示中,沒有任何驗證。

如何建立一個路由

測試API前的最後一步是新增一個路由。要做到這一點,在routes/api.php檔案中新增以下程式碼。在檔案的開頭新增 use 語句,在正文中新增 Route 語句:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
use App\Http\Controllers\Api\ProductController;
Route::apiResource('products', ProductController::class);
use App\Http\Controllers\Api\ProductController; Route::apiResource('products', ProductController::class);
use App\Http\Controllers\Api\ProductController;
Route::apiResource('products', ProductController::class);

在你開始測試API之前,確保products表在你的資料庫中。如果它不存在,用XAMPP這樣的控制面板建立一個。或者,你可以執行以下命令來遷移資料庫:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan migrate
php artisan migrate
php artisan migrate

如何測試一個API

在測試API之前,請確保app/Http/Requests/StoreProductRequest.php中的<code>authorize</code>方法設定為返回<code>true</code>。

現在,您可以使用Postman建立一個新產品。首先點選此URL的 POST 請求:http://127.0.0.1:8000/api/products/.因為這是一個建立新產品的 POST 請求,所以必須傳遞一個帶有標題和描述的JSON物件。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"title":"Apple",
"description":"Best Apples of the world"
}
{ "title":"Apple", "description":"Best Apples of the world" }
{
"title":"Apple",
"description":"Best Apples of the world"
}

在Postman中建立一個新產品

在Postman中建立一個新產品

點選Send按鈕後,你應該看到以下內容:

點選 "Send" 後

點選 “Send” 後

現在,使用 GET 請求來獲取所建立的產品。URL是一樣的。結果將如下所示:

通過GET請求獲取的產品

通過GET請求獲取的產品

如何使用Sanctum認證API

在保證API安全的情況下,認證是至關重要的。Laravel通過提供Sanctum令牌的功能使之變得簡單,你可以將其作為中介軟體使用。當使用者使用正確的憑證登入時,它可以使用生成的令牌來保護API的安全。記住,沒有令牌,使用者就不能訪問安全的API。

新增認證的第一步是使用下面的程式碼新增一個Sanctum包:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
composer require laravel/sanctum
composer require laravel/sanctum
composer require laravel/sanctum

然後,釋出Sanctum的配置檔案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

之後,新增Sanctum的token作為中介軟體。在app/Http/Kernel.php檔案中,使用以下類,並在受保護的中介軟體組的API中用以下程式碼替換 middlewareGroups

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];

下一步是建立一個 UserController ,並新增程式碼以獲取令牌進行認證。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan make:controller UserController
php artisan make:controller UserController
php artisan make:controller UserController

建立完 UserController 後,導航到app/Http/Controllers/UserController.php檔案,用以下程式碼替換現有程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
//
function index(Request $request)
{
$user= User::where('email', $request->email)->first();
// print_r($data);
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
$token = $user->createToken('my-app-token')->plainTextToken;
$response = [
'user' => $user,
'token' => $token
];
return response($response, 201);
}
}
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Illuminate\Support\Facades\Hash; class UserController extends Controller { // function index(Request $request) { $user= User::where('email', $request->email)->first(); // print_r($data); if (!$user || !Hash::check($request->password, $user->password)) { return response([ 'message' => ['These credentials do not match our records.'] ], 404); } $token = $user->createToken('my-app-token')->plainTextToken; $response = [ 'user' => $user, 'token' => $token ]; return response($response, 201); } }
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
// 
function index(Request $request)
{
$user= User::where('email', $request->email)->first();
// print_r($data);
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
$token = $user->createToken('my-app-token')->plainTextToken;
$response = [
'user' => $user,
'token' => $token
];
return response($response, 201);
}
}

在你測試認證之前,先建立一個採用種子機的使用者。下面的命令建立了一個UsersTableSeeder檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan make:seeder UsersTableSeeder
php artisan make:seeder UsersTableSeeder
php artisan make:seeder UsersTableSeeder

database/seeders/UsersTableSeeder.php檔案中,用下面的程式碼替換現有的程式碼,為使用者提供seed:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => 'John Doe',
'email' => 'john@doe.com',
'password' => Hash::make('password')
]);
}
}
<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; class UsersTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('users')->insert([ 'name' => 'John Doe', 'email' => 'john@doe.com', 'password' => Hash::make('password') ]); } }
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => 'John Doe',
'email' => 'john@doe.com',
'password' => Hash::make('password')
]);
}
}

現在用這個命令執行seeder:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan db:seed --class=UsersTableSeeder
php artisan db:seed --class=UsersTableSeeder
php artisan db:seed --class=UsersTableSeeder

認證流程中剩下的最後一步是使用建立的中介軟體來保護路由。導航到routes/api.php檔案,在中介軟體內新增產品路由。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
use App\Http\Controllers\UserController;
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::apiResource('products', ProductController::class);
});
Route::post("login",[UserController::class,'index']);
use App\Http\Controllers\UserController; Route::group(['middleware' => 'auth:sanctum'], function () { Route::apiResource('products', ProductController::class); }); Route::post("login",[UserController::class,'index']);
use App\Http\Controllers\UserController;
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::apiResource('products', ProductController::class);
});
Route::post("login",[UserController::class,'index']);

在向中介軟體新增路由後,如果你試圖獲取產品,你會得到一個內部伺服器錯誤。

新增路由後出現內部伺服器錯誤

新增路由後出現內部伺服器錯誤

但是,一旦你登入,得到一個令牌,並在標題中使用它,它就會認證你並開始工作。你可以向http://127.0.0.1:8000/api/login 傳送一個POST請求,其正文如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"email":"john@doe.com",
"password":"password"
}
{ "email":"john@doe.com", "password":"password" }
{
"email":"john@doe.com",
"password":"password"
}

認證成功

認證成功

使用收到的令牌作為承載令牌,並將其新增為授權頭。

新增承載者標記作為授權標頭

新增承載者標記作為授權標頭

如何處理API的錯誤

每當你向伺服器傳送請求時,它都會做出響應。隨著響應的進行,它也會根據響應的性質傳送一個狀態程式碼。例如,200狀態程式碼表明請求已經成功,而404則表明伺服器無法找到所請求的資源。

然而,一個狀態程式碼是不夠的。一個人類可讀的錯誤資訊是必需的。Laravel有很多方法來處理錯誤. 你可以使用try-catch塊, fallback方法, 或者傳送一個自定義的響應. 下面你新增到 UserController 中的程式碼演示了這一點。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
if (!$user || !Hash::check($request->password, $user->password)) { return response([ 'message' => ['These credentials do not match our records.'] ], 404); }
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}

小結

Laravel的Eloquent Model使得建立, 驗證, 和測試API變得毫不費力. 它的物件關係對映提供了一個直接的方法來與資料庫進行互動。

此外, 作為中介軟體, Laravel的Sanctum token可以幫助你快速確保你的API的安全.

評論留言