tomblakemore / laravel-jsonapi-http
支持JSON:API规范的Laravel项目的包
Requires
- php: >=5.4.0
Requires (Dev)
- phpunit/phpunit: 5.2.*
This package is not auto-updated.
Last update: 2024-09-28 20:35:41 UTC
README
描述
一个支持JSON:API规范的Laravel项目的包。
包支持的特性
- 关系
- 包含
- 过滤
- 分页
- 排序
有关JSON:API规范的完整详细信息,请参阅https://jsonapi.fullstack.org.cn/format。
使用Composer安装
使用 Composer 安装此包。如果您尚未安装Composer,请按照文档进行安装。
在您的应用程序文件夹内运行
composer require tomblakemore/laravel-jsonapi-http
设置
将服务提供者添加到 config/app.php 文件。
'providers' => [
...
JsonApiHttp\RequestServiceProvider::class
],
将以下中间件组添加到 app\Http\Kernel.php 类。
protected $middlewareGroups = [
...
'jsonapi' => [
\JsonApiHttp\Middleware\SetRequest::class,
\JsonApiHttp\Middleware\CheckAcceptHeaders::class,
\JsonApiHttp\Middleware\CheckForContentTypeHeader::class,
\JsonApiHttp\Middleware\VerifyContentTypeHeader::class,
\JsonApiHttp\Middleware\VerifyContent::class,
\JsonApiHttp\Middleware\SetResponseHeaders::class
],
'relationships' => [
\JsonApiHttp\Middleware\VerifyRelationship::class,
\JsonApiHttp\Middleware\AddRelationshipToModel::class,
\JsonApiHttp\Middleware\RemoveRelationshipFromModel::class
],
'resources' => [
\JsonApiHttp\Middleware\VerifyResource::class,
\JsonApiHttp\Middleware\AddResourceAttributesToModel::class,
\JsonApiHttp\Middleware\AddResourceRelationshipsToModel::class,
\JsonApiHttp\Middleware\RemoveResourceRelationshipsFromModel::class
]
];
基本用法
以下是一个简单的模型和控制器示例,用于显示人员列表和获取特定人员。
创建 people 表。
php artisan make:migration create_people_table --create=people
将以下内容添加到迁移文件。
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('people', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
创建 Person 模型并填写属性 $type。类型是JSON:API资源类型,应该是模型名称的复数形式,因此在这种情况下是 people。
<?php
namespace App;
use JsonApiHttp\AbstractModel;
class Person extends AbstractModel
{
/**
* The resource type.
*
* @var string
*/
protected $type = 'people';
}
一个控制器,包含两个操作来获取人员和人员。
<?php
namespace App\Http\Controllers;
use App\Person;
use JsonApiHttp\Controller;
use JsonApiHttp\Request;
class PersonController extends Controller
{
/**
* The resource type.
*
* @var string
*/
protected $type = 'people';
/**
* Display a list of people.
*
* @param \JsonApiHttp\Request $request
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$query = Person::query();
$request->filter($query)->sort($query);
$people = $request->paginate($query, Person::perPage());
$people->appends($request->query());
$resources = $this->resources($request, $people);
return response($resources);
}
/**
* Display a person.
*
* @param \JsonApiHttp\Request $request
* @param \App\Person $person
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Person $person)
{
$resource = $this->resource($request, $person);
return response($resource);
}
}
两个路由将请求定向到两个控制器操作。
Route::group(['middleware' => ['jsonapi', 'resources']], function () {
Route::get('/people', 'PersonController@index')->name('people.index');
Route::get('/people/{person}', 'PersonController@show')->name('people.show');
});
资源现在可以在以下端点上访问
GET /peopleGET /people/:id
关系
可以使用JSON:API关系端点来表示对象。我们将创建一个简单的 Patient > Doctor 关系作为示例。
创建 doctors 表。
php artisan make:migration create_doctors_table --create=doctors
将以下内容添加到迁移文件。
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('doctors', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
创建 Doctor 模型并创建 patients 关系。
<?php
namespace App;
use JsonApiHttp\AbstractModel;
class Doctor extends AbstractModel
{
/**
* The resource type.
*
* @var string
*/
protected $type = 'doctors';
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function patients()
{
return $this->hasMany(Patient::class);
}
/**
* Return any the relations to display in the JSON:API output.
*
* @return array
*/
public function relations()
{
return ['patients'];
}
}
创建一个用于关系的控制器。
<?php
namespace App\Http\Controllers;
use App\Doctor;
use JsonApiHttp\RelationshipsController;
use JsonApiHttp\Request;
class DoctorRelationshipsController extends RelationshipsController
{
/**
* The resource type.
*
* @var string
*/
protected $type = 'doctors';
/**
* Display a relation or collection of relations.
*
* @param \JsonApiHttp\Request $request
* @param \App\Doctor $doctor
* @param string $relation
* @return \Illuminate\Http\Response
*/
public function index(Request $request, Doctor $doctor, $relation)
{
$relations = $this->relations($request, $doctor, $relation);
return response($relations);
}
/**
* Display a relationship.
*
* @param \JsonApiHttp\Request $request
* @param \App\Doctor $doctor
* @param string $relation
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Doctor $doctor, $relation)
{
$relationship = $this->relationship($request, $doctor, $relation);
return response($relationship);
}
}
创建 patients 表。
php artisan make:migration create_patients_table --create=patients
将以下内容添加到迁移文件。
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('patients', function (Blueprint $table) {
$table->increments('id');
$table->integer('doctor_id')->unsigned()->index();
$table->foreign('doctor_id')->references('id')->on('doctors');
$table->string('name');
$table->timestamps();
});
}
创建 Patient 模型并创建 doctor 关系。
<?php
namespace App;
use JsonApiHttp\AbstractModel;
class Patient extends AbstractModel
{
/**
* The resource type.
*
* @var string
*/
protected $type = 'patients';
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function doctor()
{
return $this->belongsTo(Doctor::class);
}
/**
* Return any the relations to display in the JSON:API output.
*
* @return array
*/
public function relations()
{
return ['doctor'];
}
}
创建一个用于关系的控制器。
<?php
namespace App\Http\Controllers;
use App\Patient;
use JsonApiHttp\RelationshipsController;
use JsonApiHttp\Request;
class PatientRelationshipsController extends RelationshipsController
{
/**
* The resource type.
*
* @var string
*/
protected $type = 'patients';
/**
* Display a relation or collection of relations.
*
* @param \JsonApiHttp\Request $request
* @param \App\Patient $patient
* @param string $relation
* @return \Illuminate\Http\Response
*/
public function index(Request $request, Patient $patient, $relation)
{
$relations = $this->relations($request, $patient, $relation);
return response($relations);
}
/**
* Display a relationship.
*
* @param \JsonApiHttp\Request $request
* @param \App\Patient $patient
* @param string $relation
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Patient $patient, $relation)
{
$relationship = $this->relationship($request, $patient, $relation);
return response($relationship);
}
}
创建将请求定向到两个关系控制器的路由。
Route::group(['middleware' => ['jsonapi', 'relationships']], function () {
Route::get(
'doctors/{doctor}/{relation}',
'DoctorRelationshipsController@index'
)
->where('relation', 'patients')
->name('doctors.relations.index');
Route::get(
'doctors/{doctor}/relationships/{relation}',
'DoctorRelationshipsController@show'
)
->where('relation', 'patients')
->name('doctors.relations.show');
Route::get(
'patients/{patient}/{relation}',
'PatientRelationshipsController@index'
)
->where('relation', 'doctor')
->name('patients.relations.index');
Route::get(
'patients/{patient}/relationships/{relation}',
'PatientRelationshipsController@show'
)
->where('relation', 'doctor')
->name('patients.relations.show');
});
关系现在可以在以下端点上访问
GET /doctors/:id/patientsGET /doctors/:id/relationships/patientsGET /patients/:id/doctorGET /patients/:id/relationships/doctor
包含
要获取单个请求中的相关对象,请使用 ?include 查询参数。
GET /patients/1?include=doctor
您还可以使用点表示法来返回关系的嵌套关系。
GET /patients/1?include=doctor.patients
过滤
要过滤结果集,请将 filter 参数传递到查询字符串中。
值可以是逗号分隔的值(AND)和/或管道分隔的值(OR)的组合。
可以使用括号实现AND和OR操作的嵌套。
要查询的属性和属性/值对由冒号字符连接。
支持的运算符包括 ! (不等于),< <= => > <> (小于和大于运算符,包括一个替代的不等于运算符),^ !^ (以/不以开头),$ !$ (以/不以结尾),^$ !^$ (包含/不包含)。
要按单个属性(精确值)进行过滤。
GET /patients?filter=name:tom
要按单个属性的多个值进行过滤。
GET /patients?filter=name:(tom|ben)
关系可以查询,值是一个或多个相关资源的ID。支持属于和拥有多个类型的关系。
GET /patients?filter=doctor:1
分页
使用 page 和 perPage 查询参数来控制结果集的分页。
GET /patients?page=1&perPage=10
排序
使用 sort 查询参数来排序结果集。值应该是模型的一个属性。使用 - 符号前缀进行降序排序。可以指定多个属性,用逗号分隔。
GET /patients?sort=-name
测试
这些功能很快就会添加!