bonfirecc/laravel-graphql

Laravel的PHP GraphQL包装器

安装: 20

依赖: 0

建议者: 0

安全: 0

星标: 0

关注者: 5

分支: 0

开放问题: 0

类型:项目

v1.0.3 2018-10-16 14:32 UTC

This package is auto-updated.

Last update: 2024-09-17 10:54:37 UTC


README

Latest Stable Version License

核心代码来自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...
		}

	}

高级用法