ufree/laravel-graphql

Facebook GraphQL for Laravel

安装: 27

依赖者: 0

建议者: 0

安全: 0

星星: 0

关注者: 1

分支: 233

类型:项目

3.0.1 2019-03-03 18:15 UTC

README

本版本已针对性能进行优化,并且我紧跟 webonyx 库的最新版本。本版本在注册模式时使用 TypeRegistry 类来延迟加载类型,从而提高了拥有500+类型注册的应用程序的性能超过50%。我还停止了未使用的 TypeAdded 事件触发,这也大大提高了性能。

TypeRegistry 的使用使库的复杂性有所增加 - 您现在必须在 graphql.php 配置文件中发布自定义标量目录和命名空间路径。当创建自定义标量时,您的 type 函数必须按以下方式配置

static public function type() {
        if(is_null(self::$_instance))
        {
            self::$_instance = new self();
        }
        return GraphQL::type(self::$_instance->name);
    }

在引用 GraphQL 的任何地方,您都应始终使用 GraphQL::type 而不是实例化类来调用它,因为这会将您连接到 TypeRegistry 类。如果您不这样做,您将收到模式错误。

Laravel GraphQL

使用 Laravel 5 或 Lumen 与 Facebook GraphQL。它基于此处的 PHP 实现 here。您可以在 GraphQL Introduction 上找到有关 GraphQL 的更多信息,该文章发布在 React 博客上,或者您可以阅读 GraphQL specifications。这是一个正在进行中的项目。

此包与 Eloquent 模型(或任何其他数据源)兼容。请参阅下面的示例。

Latest Stable Version Build Status Total Downloads

要使用 laravel-graphql 与 Relay,请查看 feature/relay 分支。

安装

已发布版本 1.0。如果您从旧版本升级,您可以查看 升级到 1.0

依赖项

1- 在您的 composer.json 中通过 Composer 需求此包。

{
  "require": {
    "sonarsoftware/graphql": "~2.0.0"
  }
}

2- 运行 Composer 来安装或更新新需求。

$ composer install

$ composer update

Laravel >= 5.5.x

1- 发布配置文件

$ php artisan vendor:publish --provider="Folklore\GraphQL\ServiceProvider"

2- 检查配置文件

config/graphql.php

使用方法

高级使用

模式

从版本 1.0 开始,您可以定义多个模式。如果您想要一个公共端点和另一个需要认证的端点,这可能会很有用。

您可以在配置中定义多个模式

'schema' => 'default',

'schemas' => [
    'default' => [
        'query' => [
            //'users' => 'App\GraphQL\Query\UsersQuery'
        ],
        'mutation' => [
            //'updateUserEmail' => 'App\GraphQL\Query\UpdateUserEmailMutation'
        ]
    ],
    'secret' => [
        'query' => [
            //'users' => 'App\GraphQL\Query\UsersQuery'
        ],
        'mutation' => [
            //'updateUserEmail' => 'App\GraphQL\Query\UpdateUserEmailMutation'
        ]
    ]
]

或者您可以使用外观添加模式

GraphQL::addSchema('secret', [
    'query' => [
        'users' => 'App\GraphQL\Query\UsersQuery'
    ],
    'mutation' => [
        'updateUserEmail' => 'App\GraphQL\Query\UpdateUserEmailMutation'
    ]
]);

然后,您可以使用外观构建模式

// Will return the default schema defined by 'schema' in the config
$schema = GraphQL::schema();

// Will return the 'secret' schema
$schema = GraphQL::schema('secret');

// Will build a new schema
$schema = GraphQL::schema([
    'query' => [
        //'users' => 'App\GraphQL\Query\UsersQuery'
    ],
    'mutation' => [
        //'updateUserEmail' => 'App\GraphQL\Query\UpdateUserEmailMutation'
    ]
]);

或者您可以请求特定模式的端点

// Default schema
http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}

// Secret schema
http://homestead.app/graphql/secret?query=query+FetchUsers{users{id,email}}

创建查询

首先您需要创建一个类型。

namespace App\GraphQL\Type;

use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;

class UserType extends GraphQLType
{
    protected $attributes = [
        'name' => 'User',
        'description' => 'A user'
    ];

    /*
    * Uncomment following line to make the type input object.
    * https://graphql.net.cn/learn/schema/#input-types
    */
    // protected $inputObject = true;

    public function fields()
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::string()),
                'description' => 'The id of the user'
            ],
            'email' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ]
        ];
    }

    // 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::addType('App\GraphQL\Type\UserType', 'User');

然后您需要定义一个返回此类型(或列表)的查询。您还可以指定在 resolve 方法中使用的参数。

namespace App\GraphQL\Query;

use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
use App\User;

class UsersQuery extends Query
{
    protected $attributes = [
        'name' => 'users'
    ];

    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();
        }
    }
}

如果查询的任何部分有默认值,您可以在args()函数中定义它,通过将defaultValue作为数组键包含在其中一个参数中,并将值设置为默认值。例如,如果您在查询中有一个可选参数include_deleted_users,并且默认值应该是false,那么您可以像下面这样编辑args()函数

public function args()
{
    return [
        'id' => [
            'name' => 'id',
            'type' => Type::string()
        ],
        'email' => [
            'name' => 'email',
            'type' => Type::string()
        ],
        'include_deleted_users' => [
            'name' => 'include_deleted_users',
            'type' => Type::boolean(),
            'defaultValue' => false
        ]
    ];
}

您还可以通过添加description数组键来为查询字段添加描述 - 这将在模式中显示,并被GraphiQL等工具拾取。

将查询添加到config/graphql.php配置文件中

'schemas' => [
    'default' => [
        'query' => [
            'users' => 'App\GraphQL\Query\UsersQuery'
        ],
        // ...
    ]
]

就是这样。您应该能够通过向/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 Folklore\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配置文件中

'schema' => [
    '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的Validatorargs执行验证。

在创建变异时,您可以添加一个方法来定义适用的验证规则,如下所示

namespace App\GraphQL\Mutation;

use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\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' => 'email', 'type' => Type::string()]
        ];
    }

    public function rules()
    {
        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'message的错误,然后validation属性将包含由Laravel Validator返回的正常错误消息。

{
  "data": {
    "updateUserEmail": null
  },
  "errors": [
    {
      "message": "validation",
      "locations": [
        {
          "line": 1,
          "column": 20
        }
      ],
      "validation": {
        "email": [
          "The email is invalid."
        ]
      }
    }
  ]
}