bonfirecc / laravel-graphql
Laravel的PHP GraphQL包装器
Requires
- php: >=5.5.9
- illuminate/support: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*
- laravel/framework: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*
- webonyx/graphql-php: ~0.10.0
Requires (Dev)
- orchestra/testbench: 3.1.*|3.2.*|3.3.*|3.4.*|3.5.*
- phpunit/phpunit: ^5.5|~6.0|~7.0
README
核心代码来自Rabing laravel-graphql
使用Laravel 5的Facebook GraphQL。它基于PHP实现此处。您可以在GraphQL Introduction(在React博客上)了解更多关于GraphQL的信息,或者您也可以阅读GraphQL规范。这是一个持续开发的项目。
此包与Eloquent模型或任何其他数据源兼容。
- 允许创建作为请求端点的查询和突变
- 可以为每个查询/突变定义自定义的中间件
- 查询返回的类型可以具有自定义的隐私设置。
- 查询的字段将可以选择通过
SelectFields
类从数据库动态检索。
安装
依赖
安装
1- 在您的composer.json
中通过Composer要求此包。
{ "require": { "BonfireCC/graphql-laravel": "~1.0.2" } }
2- 运行Composer来安装或更新新要求。
$ composer install
或
$ composer update
3- 将服务提供者添加到您的app/config/app.php
文件中
BonfireCC\GraphQL\GraphQLServiceProvider::class,
4- 将外观添加到您的app/config/app.php
文件中
'GraphQL' => 'BonfireCC\GraphQL\Support\Facades\GraphQL',
5- 发布配置文件
$ php artisan vendor:publish --provider="BonfireCC\GraphQL\GraphQLServiceProvider"
6- 检查配置文件
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'
],
'mutation' => [
],
'middleware' => ['auth'],
],
],
创建查询
首先,您需要创建一个类型。如果指定关系,则需要Eloquent模型。
注意!如果它是非数据库字段或不是关系,则需要“selectable”键
namespace App\GraphQL\Type; use GraphQL\Type\Definition\Type; use BonfireCC\GraphQL\Support\Type as GraphQLType; class UserType extends GraphQLType { protected $attributes = [ 'name' => 'User', 'description' => 'A user', 'model' => UserModel::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' ]
您还可以使用GraphQL
外观将类型添加到服务提供者中,例如。
GraphQL::addType('App\GraphQL\Type\UserType', 'user');
然后,您需要定义一个返回此类型(或列表)的查询。您还可以指定在resolve方法中使用的参数。
namespace App\GraphQL\Query; use GraphQL; use GraphQL\Type\Definition\Type; use BonfireCC\GraphQL\Support\Query; use App\User; 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(); } else if(isset($args['email'])) { return User::where('email', $args['email'])->get(); } else { return User::all(); } } }
将查询添加到config/graphql.php
配置文件中
'schemas' => [ 'default' => [ 'query' => [ 'users' => 'App\GraphQL\Query\UsersQuery' ], // ... ] ]
就这样。您应该能够通过向URL /graphql
(或您在配置中选择的任何内容)发出请求来查询GraphQL。尝试以下query
输入的GET请求
query FetchUsers {
users {
id
email
}
}
例如,如果您使用homestead
http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}
创建突变
突变就像任何其他查询一样。它接受参数(将用于执行突变)并返回一定类型的对象。
例如,更新用户密码的突变。首先,您需要定义突变
namespace App\GraphQL\Mutation; use GraphQL; use GraphQL\Type\Definition\Type; use BonfireCC\GraphQL\Support\Mutation; use App\User; 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' ], // ... ] ]
然后你应该能够使用以下查询在端点上执行突变
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
执行验证。
在创建突变时,你可以添加一个方法来定义应用的验证规则,方法如下
namespace App\GraphQL\Mutation; use GraphQL; use GraphQL\Type\Definition\Type; use BonfireCC\GraphQL\Support\Mutation; use App\User; 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' => 'password', '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
属性添加到错误对象中。要查找验证错误,你应该检查具有等于'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 - 这意味着更改请求的中间件将没有任何效果...
use GraphQL; use GraphQL\Type\Definition\Type; use BonfireCC\GraphQL\Support\UploadType; use BonfireCC\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' => new UploadType($this->attributes['name']), 'rules' => ['required', 'image', 'max:1500'], ], ]; } public function resolve($root, $args) { $file = $args['profilePicture']; // Do something with file here... } }