Laravel 11:API 资源

10 阅读3分钟

Laravel 中的 API 资源充当转换层,位于 Eloquent 模型和实际返回给应用程序用户的 JSON 响应之间。它们使您可以完全控制 API 返回的 JSON 结构,而无需修改模型。

在 Laravel 中定义 API 资源

php artisan make:resource UserResource

UserResource 类位于 Laravel 项目的 app/Http/Resources 目录中。

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            // You can include other model properties or even relationships
        ];
    }
}
?>

在 Controller 中使用 API 资源

定义 API 资源后,您可以在控制器中使用它来返回模型数据。API 资源会自动将模型转换为您在 toArray 方法中定义的 JSON 结构。

下面是一个在 UserController 中使用 UserResource 的示例:

<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Http\Resources\UserResource;

class UserController extends Controller
{
    public function show($id)
    {
		// Check if there is a user with that id
        $user = User::findOrFail($id);

        // Return a single user as a resource
        return new UserResource($user);
    }
}
?>

除了单个资源之外,Laravel 还提供了一种返回资源集合的便捷方法。可以使用 UserResource::collection 方法包装模型集合,将转换应用于集合中的每个项。 return UserResource::collection(User::paginate());

上面的代码将返回一个分页的用户列表,每个用户都由 UserResource 转换。

Create API Resources 创建 API 资源

首先,我们需要为模型创建 API 资源。打开终端并运行以下命令:

php artisan make:resource UserResource
php artisan make:resource PostResource

现在,在位于 app/Http/Resources 的相应文件中定义每个资源的结构。

UserResource.php
<?php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'posts' => PostResource::collection($this->whenLoaded('posts')),
        ];
    }
}
PostResource.php
<?php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
            'author' => new UserResource($this->whenLoaded('user')),
        ];
    }
}

在 app/Http/Controllers 目录中创建一个 API 文件夹来存储您的 API 控制器。

Create API Controllers 创建 API 控制器

生成控制器并将其放置在 API 文件夹中:

php artisan make:controller API/UserController
php artisan make:controller API/PostController

打开每个控制器文件,并使用 API 资源定义必要的方法。

API/UserController.php
<?php
namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        return UserResource::collection(User::all());
    }

    public function show($id)
    {
        $user = User::with('posts')->findOrFail($id);
        return new UserResource($user);
    }
}
API/PostController.php
<?php
namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Http\Resources\PostResource;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        return PostResource::collection(Post::with('user', 'tags')->paginate());
    }

    public function show($id)
    {
        $post = Post::with('user', 'tags')->findOrFail($id);
        return new PostResource($post);
    }
}

我们需要使用以下命令安装 API 路由,Laravel 将处理其余的工作。它将为我们安装 Laravel Sanctum,并在 routes 文件夹中创建 API 路由文件 routes/api.php 。 php artisan install:api
PHP Artisan 安装:API

Update API Routes 更新 API 路由

Modify your routes/api.php file to use the new API controllers:
修改 routes/api.php 文件以使用新的 API 控制器:

<?php
use App\Http\Controllers\API\UserController;
use App\Http\Controllers\API\PostController;

// User API routes
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);

// Post API routes
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{id}', [PostController::class, 'show']);

为简单起见,我们将这些路由保持为公共且不受保护,以便您可以轻松测试它们。您可以导航到 http://blog.test/api/users 以查看在您的应用程序中注册的所有用户。 或者,您可以导航到 http://blog.test/api/users/1 以查看 ID 为 1 的用户的数据。 但是,您可能希望保护 API 路由并仅允许某些应用程序访问它们。我们将解释如何包含用于路由保护的中间件,以及如何安装 Laravel Sanctum 以简化 API 流程。