dmavrin / graphql-laravel
Laravel的PHP GraphQL包装器
Requires
- php: >= 7.2
- ext-json: *
- illuminate/contracts: ^6.0|^7.0|^8.0
- illuminate/support: ^6.0|^7.0|^8.0
- webonyx/graphql-php: ^14.0
Requires (Dev)
- ext-pdo_sqlite: *
- friendsofphp/php-cs-fixer: ^2.15
- laravel/legacy-factories: ^1.0
- matt-allan/laravel-code-style: 0.5.1
- mockery/mockery: ^1.2
- nunomaduro/larastan: 0.6.4
- orchestra/testbench: 4.0.*|5.0.*|^6.0
- phpunit/phpunit: ~7.0|~8.0|^9
- dev-master
- 6.0.0-rc2
- 6.0.0-rc1
- 5.x-dev
- 5.1.5-rc1
- 5.1.4
- 5.1.3
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.0
- 5.0.0-rc2
- 5.0.0-rc1
- 4.0.0
- 4.0.0-rc1
- 3.1.0
- 3.0.0
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- v2.0.0-RC5
- v2.0.0-RC4
- v2.0.0-RC3
- v2.0.0-RC2
- v1.24.1
- v1.24.0
- v1.23.0
- v1.22.0
- v1.21.2
- v1.20.2
- v1.20.1
- v1.19.1
- v1.18.1
- v1.18.0
- v1.17.6
- v1.17.3
- v1.16.0
- v1.14.2
- v1.13.0
- v1.12.0
- v1.11.0
- v1.10.0
- v1.9.5
- v1.8.2
- v1.7.3
- v1.7.1
- v1.6.1
- v1.5.0
- v1.4.9
- v1.4
- dev-mfn-utils
- dev-mfn-detect-unused
This package is auto-updated.
Last update: 2024-09-23 22:46:44 UTC
README
使用Facebook GraphQL与Laravel 5.5+。它基于此处的PHP实现here。您可以在GraphQL Introduction上找到有关GraphQL的更多信息,该文章发布在React博客,或者您也可以阅读GraphQL specifications。这是一个正在进行中的项目。
此软件包与Eloquent模型或任何其他数据源兼容。
- 允许创建作为请求端点的查询和突变
- 可以为每个查询/突变定义自定义的中间件
- 查询返回具有自定义隐私设置的类型
- 可以通过使用
SelectFields类从数据库中动态检索查询字段。
它提供了以下功能和改进,这些功能和改进优于Folklore的原始包
- 按操作授权
- 按字段回调定义其可见性(例如,从未认证用户中隐藏)
- 在
resolve()中可用SelectFields抽象,允许进行高级预加载,从而解决n+1问题 - 支持分页
- 支持服务器端查询批处理
安装
依赖项
安装
- 使用Composer安装包
composer require rebing/graphql-laravel
Laravel 5.5+
1. Laravel 5.5+将自动发现该软件包,对于旧版本,请将以下服务提供程序添加到您的config/app.php文件中。
Rebing\GraphQL\GraphQLServiceProvider::class,
和别名
'GraphQL' => 'Rebing\GraphQL\Support\Facades\GraphQL',
在您的config/app.php文件中。
2. 发布配置文件
$ php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"
3. 检查配置文件
config/graphql.php
Lumen(实验性!)
1. 将以下服务提供程序添加到bootstrap/app.php文件中
$app->register(Rebing\GraphQL\GraphQLLumenServiceProvider::class);
2. 发布配置文件
$ php artisan graphql:publish
3. 将配置添加到bootstrap/app.php文件中 重要: 这需要在注册服务提供程序之前完成
$app->configure('graphql'); ... $app->register(Rebing\GraphQL\GraphQLLumenServiceProvider::class);
4. 检查配置文件
config/graphql.php
使用方法
高级使用
模式
需要模式来定义GraphQL端点。您可以定义多个模式并将不同的中间件分配给它们,除了全局中间件。例如
'schema' => 'default_schema', 'schemas' => [ 'default' => [ 'query' => [ 'example_query' => ExampleQuery::class, ], 'mutation' => [ 'example_mutation' => ExampleMutation::class, ], ], 'user' => [ 'query' => [ 'profile' => App\GraphQL\Query\ProfileQuery::class ], 'mutation' => [ ], 'middleware' => ['auth'], ], ],
创建查询
首先您需要创建一个类型。如果您指定了关系,则需要Eloquent模型。
注意:如果是一个非数据库字段或不是关系,则需要“selectable”键
<?php namespace App\GraphQL\Type; use App\User; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Type as GraphQLType; class UserType extends GraphQLType { protected $attributes = [ 'name' => 'User', 'description' => 'A user', 'model' => User::class, ]; public function fields() { return [ 'id' => [ 'type' => Type::nonNull(Type::string()), 'description' => 'The id of the user', 'alias' => 'user_id', // Use 'alias', if the database column is different from the type name ], 'email' => [ 'type' => Type::string(), 'description' => 'The email of user', ], // Uses the 'getIsMeAttribute' function on our custom User model 'isMe' => [ 'type' => Type::boolean(), 'description' => 'True, if the queried user is the current user', 'selectable' => false, // Does not try to query this from the database ] ]; } // If you want to resolve the field yourself, you can declare a method // with the following format resolve[FIELD_NAME]Field() protected function resolveEmailField($root, $args) { return strtolower($root->email); } }
将类型添加到config/graphql.php配置文件中
'types' => [ 'user' => App\GraphQL\Type\UserType::class ]
您还可以使用GraphQL外观在服务提供程序中添加类型。
GraphQL::addType(\App\GraphQL\Type\UserType::class, 'user');
然后您需要定义一个查询,该查询返回此类型(或列表)。您还可以指定在 resolve 方法中可以使用的参数。
<?php namespace App\GraphQL\Query; use App\User; use Rebing\GraphQL\Support\Facades\GraphQL; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Query; class UsersQuery extends Query { protected $attributes = [ 'name' => 'Users query' ]; public function type() { return Type::listOf(GraphQL::type('user')); } public function args() { return [ 'id' => ['name' => 'id', 'type' => Type::string()], 'email' => ['name' => 'email', 'type' => Type::string()] ]; } public function resolve($root, $args) { if (isset($args['id'])) { return User::where('id' , $args['id'])->get(); } if (isset($args['email'])) { return User::where('email', $args['email'])->get(); } return User::all(); } }
将查询添加到配置文件 config/graphql.php
'schemas' => [ 'default' => [ 'query' => [ 'users' => App\GraphQL\Query\UsersQuery::class ], // ... ] ]
就是这样。您应该能够通过向网址 /graphql(或您在配置中选择的任何网址)发出请求来查询 GraphQL。尝试以下 query 输入的 GET 请求
query FetchUsers {
users {
id
email
}
}
例如,如果您使用 homestead
http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}
创建突变
变异类似于任何其他查询。它接受参数(这些参数将用于执行变异)并返回特定类型的对象。
例如,更新用户密码的变异。首先您需要定义变异
<?php namespace App\GraphQL\Mutation; use App\User; use GraphQL; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Mutation; class UpdateUserPasswordMutation extends Mutation { protected $attributes = [ 'name' => 'UpdateUserPassword' ]; public function type() { return GraphQL::type('user'); } public function args() { return [ 'id' => ['name' => 'id', 'type' => Type::nonNull(Type::string())], 'password' => ['name' => 'password', 'type' => Type::nonNull(Type::string())] ]; } public function resolve($root, $args) { $user = User::find($args['id']); if(!$user) { return null; } $user->password = bcrypt($args['password']); $user->save(); return $user; } }
如 resolve() 方法中所示,您使用参数来更新您的模型并返回它。
然后您需要将变异添加到配置文件 config/graphql.php
'schemas' => [ 'default' => [ 'mutation' => [ 'updateUserPassword' => App\GraphQL\Mutation\UpdateUserPasswordMutation::class ], // ... ] ]
然后您应该能够在端点使用以下查询来执行变异
mutation users {
updateUserPassword(id: "1", password: "newpassword") {
id
email
}
}
如果您使用 homestead
http://homestead.app/graphql?query=mutation+users{updateUserPassword(id: "1", password: "newpassword"){id,email}}
给变异添加验证
可以向变异添加验证规则。它使用 Laravel 的 Validator 来对 $args 执行验证。
在创建变异时,您可以添加一个方法来定义应用的验证规则,方法如下
<?php namespace App\GraphQL\Mutation; use App\User; use GraphQL; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Mutation; class UpdateUserEmailMutation extends Mutation { protected $attributes = [ 'name' => 'UpdateUserEmail' ]; public function type() { return GraphQL::type('user'); } public function args() { return [ 'id' => ['name' => 'id', 'type' => Type::string()], 'email' => ['name' => 'email', 'type' => Type::string()] ]; } public function rules(array $args = []) { return [ 'id' => ['required'], 'email' => ['required', 'email'] ]; } public function resolve($root, $args) { $user = User::find($args['id']); if (!$user) { return null; } $user->email = $args['email']; $user->save(); return $user; } }
或者,您可以在每个参数上定义规则
class UpdateUserEmailMutation extends Mutation { //... public function args() { return [ 'id' => [ 'name' => 'id', 'type' => Type::string(), 'rules' => ['required'] ], 'email' => [ 'name' => 'email', 'type' => Type::string(), 'rules' => ['required', 'email'] ] ]; } //... }
当您执行变异时,它将返回发生的任何验证错误。由于 GraphQL 规范定义了错误的一定格式,因此验证错误被添加到错误对象中的额外 validation 属性。要找到验证错误,您应该检查具有 message 等于 'validation' 的错误,然后 validation 属性将包含 Laravel Validator 返回的正常错误消息
{
"data": {
"updateUserEmail": null
},
"errors": [
{
"message": "validation",
"locations": [
{
"line": 1,
"column": 20
}
],
"validation": {
"email": [
"The email is invalid."
]
}
}
]
}
返回的验证错误可以通过覆盖变异上的 validationErrorMessages 方法来自定义。该方法应该返回一个数组,其中包含与 Laravel 验证相同方式记录的自定义验证消息。例如,为了检查 email 参数是否与任何现有数据冲突,您可以执行以下操作
注意:键应该以
field_name.validator_type格式存在,这样您可以为每个验证类型返回特定错误。
public function validationErrorMessages ($args = []) { return [ 'name.required' => 'Please enter your full name', 'name.string' => 'Your name must be a valid string', 'email.required' => 'Please enter your email address', 'email.email' => 'Please enter a valid email address', 'email.exists' => 'Sorry, this email address is already in use', ]; }
文件上传
仅使用 UploadType 来上传新文件。这种上传文件的支持基于 https://github.com/jaydenseric/graphql-multipart-request-spec,因此您必须将它们作为多部分表单上传
警告:当您上传文件时,Laravel 将使用 FormRequest - 这意味着更改请求的中间件将没有任何效果。
<?php use GraphQL; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\UploadType; use Rebing\GraphQL\Support\Mutation; class UserProfilePhotoMutation extends Mutation { protected $attributes = [ 'name' => 'UpdateUserProfilePhoto' ]; public function type() { return GraphQL::type('user'); } public function args() { return [ 'profilePicture' => [ 'name' => 'profilePicture', 'type' => UploadType::getInstance(), 'rules' => ['required', 'image', 'max:1500'], ], ]; } public function resolve($root, $args) { $file = $args['profilePicture']; // Do something with file here... } }
注意:您可以使用 Altair 来测试您的文件上传实现,具体说明请参阅 此处。