文章转发在专业的Laravel开发者社区,原始链接:https://learnku.com/laravel/t...
在过去的2年时间里,我一直使用 Fractal 来进行 API 开发。
如果说一个我最希望 Laravel可以增加的功能的话,无疑是方便的数据转换,以便开发更好的 API 接口。
别误会, Fractal 很好用,然而我总是希望能只用框架进行开发。如果可以的话,我尽可能不使用类库!我不喜欢使用第三方类库使得开发复杂化。
在过去的一年里,我喜欢使用一些前端框架如 Vue 和 React 来进行开发。因此,我选择只使用 Laravel来建立 API 接口。 而当我需要建立 API 接口 的时候,Fractal是我首选的类库。 现在,情况发生了变化。
在 Laravel 5.5 中,我们有了 API 资源,对此,我真的是非常的兴奋。
在2小时前,Laravel 5.5 发布了,当时我正和朋友一起喝咖啡。当我在半小时前读到这条推的时候,脑子里的第一个想法就是用 API 资源来发布我的第一篇博客文章,我也确实这么做了。
Laravel 的 API 资源是基于 Fractal , 因此,我并没有花太多时间来了解如何使用它。 所以,让我们开始来了解它吧 ...
创建 Laravel 应用
用常用的命令行来创建 Laravel 应用
composer create-project laravel/laravel Laravel55Api
应用创建完成后,将 .env.example
重命名为 .env
并用以下命令生成 Laravel 密钥。
php artisan key:generate
启动服务
php artisan serve
很好,接下来是什么呢?
创建一个 Product 资源
API 资源是在 Laravel 中将你的模型以及模型集合转换为 JSON 的新特性。接下来让我们创建一个 Product 的资源。
php artisan make:resource Product
你可以在 app/Http/Resources
目录下看到你刚刚生成的 Product 资源
当然我们还需要 Product 的数据库迁移、模型和控制器。我们能用这个命令快速的创建这些。
php artisan make:model Product -mc
打开数据库迁移文件然后像这样修改 up
方法里面的内容:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('price');
$table->timestamps();
});
}
注意这里的价格字段是整型的。 我拜托你们,永远不要用浮点型存储你的价格数据!
一定要用整型来存储!
现在用你的 Laravel 应用连接数据库并运行这个迁移以生成数据表。
本文不是 Laravel 一对一教学贴,所以我不会在连接数据库的问题上浪费你过多的时间。
接下来?
到目前为止,我们已经有模型,控制器,数据库迁移以及用以转换模型和模型集合为 JSON 的资源类。那么接下来呢?
在这之前,什么是资源类?我们在 resources
文件夹中创建的 Product 类又是什么?一个资源类表示了单个模型转换为 JSON 的结构。
结合上面所阐述的,让我们来打开 Product.php 资源类文件。
这里有一个 toArray 方法,这个就是在我们发送响应时返回需要转换为 JSON 的属性数组的方法。
我们来修改它,让我们可以有更好的点子。
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->price,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
现在表示我们能够获得有 id, name, price, created_at
和 updated_at
这些字段的响应。
如果我们在 toArray 方法中去掉 price
字段,返回的 JSON 中就不会有 price
。很酷不是吗?
使用 Product
资源
我们刚刚更改了 toArray
方法,让我们继续在我们的控制器中使用 product
资源。
product
控制器是看起来是这样的:
<?php
namespace App\Http\Controllers;
use App\Product;
use App\Http\Resources\Product as ProductResource;
class ProductController extends Controller
{
public function show ($id)
{
return new ProductResource(Product::find($id));
}
}
为了转换 product
,我们仅仅在 product
资源类中传递了一个 product
。
让我们创建一个 show
方法的路由,看一看结果。
打开 api.php
文件,在中间件外部创建这个路由。
Route::get('/products/{id}', 'ProductController@show');
现在,手动的在你的 products
表里添加一个新的 product
,然后访问http://127.0.0.1:8000/api/pro...看看一个简单的 product
。
你应该得到这样的结果:
现在让我们来修改一点我们的资源,假如你不想公开你的 product
的 price
,你要做的就是简单的从你的 toArray
方法删除它。一旦你从 toArray
方法删除了 price
,你应该得到这样的结果,当然不包括 price
:
就这些吗?
当然不是!因为 toArray
方法仅仅是一个方法,它意味着你可以包含额外的信息。
假如我们想要包括一个「test」信息,简单的改变你的 toArray
方法。
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'test' => 'This is just a test',
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
这是结果:
然而,非常要重的是,你希望返回的数据类型总是正确的。在第一个截图上看看 price
,它返回的是一个 integer
,但是通过 (int) $this->price
,我们仍然要强制它是一个integer
。
现在,看看 create_at
和 updated_at
时间戳。如果你想要的是返回一个实际时间戳的字符串?那么你可以像这个例子中,强制类型转换为字符串:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'test' => 'This is just a test',
'created_at' => (string)$this->created_at,
'updated_at' => (string)$this->updated_at,
];
}
现在的结果是这个:
结束语
这仅仅是使用 Laravel API 资源的一个小例子。
如果我继续写下去,这篇文章永远也写不完。
所以,这篇文章就写到这吧,正如你所知道的,我们还有更多话题需要讨论,比如分页、资源集合、关联以及数据包裹等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。