前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >具有嵌套关系的可重用API资源——Laravel5.5

具有嵌套关系的可重用API资源——Laravel5.5

作者头像
幂简集成
发布2024-01-08 09:58:03
1450
发布2024-01-08 09:58:03
举报
文章被收录于专栏:API技术

本文内容主要围绕在 Laravel 5.5 中使用 API 开发的重要步骤,着重介绍如何利用 Laravel 的 API 资源(Resource)和控制器(Controller)进行多因素身份验证(MFA)。尤其强调了利用 Resource::collection 方法简化数据提供过程,以及对比 Fractal 和 Laravel 的资源处理方式。

注:本文受到Laravel创始人Taylor Otwell介绍使用 Laravel5.5 开发API时如何替换 Fractal 的启发。

1. 安装一个干净的 Laravel 5.5 项目

· 使用 Composer 命令 composer create-project laravel/laravel responses dev-develop 来创建一个 Laravel 5.5 项目。这个命令会从 Laravel 官方的存储库中下载最新版本的 Laravel 5.5 代码并安装到名为 "responses" 的文件夹中。

· cd responses: 进入到新创建的 "responses" 文件夹中。

· touch database/database.sqlite: 创建一个 SQLite 数据库文件,用于存储数据。

php artisan make:model Post -mf: 创建一个名为 "Post" 的 Eloquent 模型,并生成相应的迁移文件和工厂。

· php artisan make:resource UsersWithPostsResource: 创建一个名为 "UsersWithPostsResource" 的资源类,用于对用户及其posts进行处理。

· php artisan make:resource PostsResource: 创建一个名为 "PostsResource" 的资源类,用于对posts进行处理。

· php artisan make:controller UsersController --resource: 创建一个名为 "UsersController" 的控制器,添加了 CRUD(创建、读取、更新、删除)操作的资源路由。

· 修改 .env 文件,使用 SQLite 数据库,并删除其他数据库相关的变量。

· 添加或修改 DB_CONNECTION=sqlite 来指定 Laravel 使用 SQLite 作为数据库连接。

这些步骤旨在建立一个基本的 Laravel 5.5 项目,并做了一些初始化设置,包括创建模型、资源类和控制器,并配置使用 SQLite 作为数据库。

2. 准备数据库

· posts迁移database/migrations/______create_posts_table.php

代码语言:javascript
复制
Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title');
    $table->string('body');
    $table->unsignedInteger('user_id');
    $table->timestamps();
});

这涉及创建posts模型的数据库表结构。在 database/migrations 目录下的create_posts_table.php 的文件,定义了posts表的字段和结构。这个文件包含了使用 Laravel 的迁移(Migration)功能创建数据库表的代码。

· posts工厂database/factories/PostFactory.php

代码语言:javascript
复制
<?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);
        }
    ];
});

这一步骤是为了创建一个posts的工厂,用于生成测试数据或者用于种子数据填充。在 database/factories 目录下的 PostFactory.php 文件中,你会定义创建posts模型时所用的数据格式和规则。

· 用户拥有posts的关系app/User.php

代码语言:javascript
复制
public function posts(){return $this->hasMany(Post::class);}

这是在用户模型(User)中定义与posts模型的关系。也就是在 app 目录下的 User.php 文件中,你会定义用户和posts之间的关联关系,比如一对多关系(一个用户有多个posts)或其他关系。

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

代码语言:javascript
复制
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

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

在 app 目录下的 Post.php 文件中,通常会有一个模型类,即posts模型(Post)。避免批量赋值是指使用 Laravel 的属性来指定哪些字段可以被批量赋值,以防止不受控制的数据注入。

· 播种数据库

代码语言:javascript
复制
<?php 
artisan migrate:freshphp artisan 
tinkerfactory(App\Post::class)->times(2)->create();
factory(App\Post::class)->times(2)->create(['user_id' => 1]);

数据库种子用于向数据库中填充测试数据或初始数据。这是在开发或测试阶段常用的操作,可以使用 Laravel 的 Seeder 来填充数据库表,确保数据库中有一些初始数据可用于开发和测试。

3. 设置路由

代码语言:javascript
复制
Route::apiResource('/users', 'UsersController');

4. 重命名资源(修复遗留问题)

之前创建了一个名为UsersWithPostsResource的资源。让我们将其重命名为UsersResource,并了解如何在以下步骤中重用它。

5. 在控制器内使用API资源

代码语言:javascript
复制
<?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());
}

静态collection方法将采用要转换的记录集合,并确保为每个记录实例化一个新的UsersResource。

6. UsersResource类

代码语言:javascript
复制
<?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'))
        ];
    }
}

这里的两个关键部分:属性访问器可选的嵌套转换

在Resource中,可以通过 $this 直接访问模型的属性。这个神奇的功能是通过 DelegatesToResource trait 在基础资源类中实现的。简单来说,这意味着资源类中可以直接使用 $this->attributeName 的方式访问模型中的属性,而不必每次都通过模型实例去获取属性。

能够在资源类中进行关系的转换,但是有条件:如果数据是可用的(已经预加载),就可以进行转换;如果数据尚未加载,可以选择忽略这个转换。这样做有利于避免 N+1 查询问题(在获取关联数据时出现的效率问题),同时可以使用单个资源类处理不同的情况。如果关联数据不可用,资源类会忽略它;反之,如果可用,资源类会将其包含在返回的数据中。

7. Posts Resource

代码语言:javascript
复制
<?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
        ];
    }
}

结论

1. 简化和逐步进行

本文着重于学习如何使用 Resource::collection 而不是手动实例化类,并将关系数据的提供(或不提供)责任委托给控制器。通过在控制器中简单地移除 with('posts'),API 将不再在响应中包含每个用户的posts数据。

2. 对比 Fractal 和 Laravel 的资源

本文提到 Fractal 在转换层(Transformer)提供了默认和可用的包含(includes)功能,但是 Laravel 的原生 API 资源更倾向于让控制器处理这个逻辑。毕竟,控制器的工作是理解请求。这暗示着对于数据包含的处理,Laravel 更多地依赖于控制器层面的逻辑,而不是在资源转换层实现。

总体而言,本文聚焦于利用 Laravel 中的 Resource::collection,并强调控制器对于处理数据关系包含的重要性。

参考链接:

First impressions on Laravel API Resources | HackerNoon

具有嵌套关系的可重用 API 资源 — Laravel 5.5 |由 Marco Aurélio Deleu |HackerNoon.com |中等 (medium.com)

编译:幂简集成

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 安装一个干净的 Laravel 5.5 项目
  • 2. 准备数据库
  • 3. 设置路由
  • 4. 重命名资源(修复遗留问题)
  • 5. 在控制器内使用API资源
  • 6. UsersResource类
  • 7. Posts Resource
  • 结论
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档