在过去的2年时间里,我一直使用 Fractal 来进行 API 开发。
如果说一个我最希望 Laravel可以增加的功能的话,无疑是方便的数据转换,以便开发更好的 API 接口。
别误会, Fractal 很好用,然而我总是希望能只用框架进行开发。如果可以的话,我尽可能不使用类库!我不喜欢使用第三方类库使得开发复杂化。
在过去的一年里,我喜欢使用一些前端框架如 Vue 和 React 来进行开发。因此,我选择只使用 Laravel来建立 API 接口。 而当我需要建立 API 接口 的时候,Fractal是我首选的类库。 现在,情况发生了变化。
在 Laravel 5.5 中,我们有了 API 资源,对此,我真的是非常的兴奋。
在2小时前,Laravel 5.5 发布了,当时我正和朋友一起喝咖啡。当我在半小时前读到这条推的时候,脑子里的第一个想法就是用 API 资源来发布我的第一篇博客文章,我也确实这么做了。
Laravel 的 API 资源是基于 Fractal , 因此,我并没有花太多时间来了解如何使用它。 所以,让我们开始来了解它吧 ...
ibucoin 翻译于 2个月前
创建 Laravel 应用
用常用的命令行来创建 Laravel 应用
composer create-project laravel/laravel Laravel55Api
应用创建完成后,将 .env.example
重命名为 .env
并用以下命令生成 Laravel 密钥。
php artisan key:generate
启动服务
php artisan serve
很好,接下来是什么呢?
無限之秋 翻译于 2个月前
创建一个 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 一对一教学贴,所以我不会在连接数据库的问题上浪费你过多的时间。
無限之秋 翻译于 2个月前
接下来?
到目前为止,我们已经有模型,控制器,数据库迁移以及用以转换模型和模型集合为 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
。很酷不是吗?
無限之秋 翻译于 2个月前
使用 Product
资源
我们刚刚更改了 toArray
方法,让我们继续在我们的控制器中使用 product
资源。
product
控制器是看起来是这样的:
<?phpnamespace 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/products/1看看一个简单的 product
。
你应该得到这样的结果:
现在让我们来修改一点我们的资源,假如你不想公开你的 product
的 price
,你要做的就是简单的从你的 toArray
方法删除它。一旦你从 toArray
方法删除了 price
,你应该得到这样的结果,当然不包括 price
:
rayle 翻译于 2个月前
就这些吗?
当然不是!因为 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 资源的一个小例子。
如果我继续写下去,这篇文章永远也写不完。
所以,这篇文章就写到这吧,正如你所知道的,我们还有更多话题需要讨论,比如分页、资源集合、关联以及数据包裹等
原文地址:https://laravel-china.org/topics/7528/use-the-api-resource-function-of-laravel-to-build-your-api
翻译作者:LOST