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

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

image.png

前言

本文内容主要围绕在 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

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

<?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

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

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

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

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model{protected $guarded = [];}

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

· 播种数据库

<?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. 设置路由

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

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

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

5. 在控制器内使用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());
}

静态collection方法将采用要转换的记录集合,并确保为每个记录实例化一个新的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'))
        ];
    }
}

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

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

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

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
        ];
    }
}

结论

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)

编译:幂简集成

相关文章
|
4月前
|
安全 API 持续交付
要利用阿里云控制API查询您的阿里云资源
【2月更文挑战第33天】要利用阿里云控制API查询您的阿里云资源
161 3
|
27天前
|
API 网络架构 开发者
【Azure API 管理】APIM服务资源删除后,为什么不能马上创建相同名称的APIM服务呢?
【Azure API 管理】APIM服务资源删除后,为什么不能马上创建相同名称的APIM服务呢?
|
2月前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之使用API调用ODPS SQL时,出现资源被定时任务抢占,该怎么办
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
28天前
|
API 开发工具 数据安全/隐私保护
【Azure Developer】Python 获取Micrisoft Graph API资源的Access Token, 并调用Microsoft Graph API servicePrincipals接口获取应用ID
【Azure Developer】Python 获取Micrisoft Graph API资源的Access Token, 并调用Microsoft Graph API servicePrincipals接口获取应用ID
|
2月前
|
搜索推荐 API UED
资源部署及场景API调用体验过程的引导与操作流畅性
资源部署及场景API调用体验过程的引导与操作流畅性
|
3月前
|
安全 前端开发 中间件
中间件在API跨域资源共享(CORS)
【6月更文挑战第16天】
53 7
|
4月前
|
消息中间件 监控 安全
探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)
探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)
665 0
|
10月前
|
设计模式 Java API
使用Spring框架创建一个RESTful API,实现学生信息的管理,包括资源的创建、读取、更新和删除。
在当今的Web应用程序开发中,RESTful API(Representational State Transferful Application Programming Interface)变得越来越重要。Spring框架提供了强大的工具和功能,以便轻松创建、读取、更新和删除(CRUD)资源。在这篇文章中,我们将深入探讨如何使用Spring框架创建一个RESTful API,并通过一个完整的示例演示。
292 0
|
JSON 监控 API
php对接小鹅通API开发高级实战案例解析:获取指定资源学习记录信息(单人单学习记录、单人多学习记录累计、返回数据格式确认)
php对接小鹅通API开发高级实战案例解析:获取指定资源学习记录信息(单人单学习记录、单人多学习记录累计、返回数据格式确认)
279 0