我按照以下文章在本地机器上使用 graphql 设置 laravel:
https://auth0.com/blog/developing-and-securing-graphql-apis-with-laravel
我一步一步地遵循完整的文章,没有任何问题。但是当我使用
php artisan serve
并localhost:8000/graphql
命中端点,出现以下错误。
[2019 年 8 月 31 日星期六 23:09:20] PHP 致命错误:App\GraphQL\Query\WineQuery::type(( 的声明必须与 Rebing\GraphQL\Support\Field::type((: GraphQL\Type\Definition\Type 在/Users/sushilsingh/Projects/winestore/app/GraphQL/Queries/WineQuery.php 第 9 行
这是我的WineQuery.php
<?php
namespace AppGraphQLQueries;
use AppWine;
use GraphQLTypeDefinitionType;
use RebingGraphQLSupportQuery;
class WineQuery extends Query
{
protected $attributes = [
'name' => 'wine',
];
public function type()
{
return GraphQL::type('Wine');
}
public function args()
{
return [
'id' => [
'name' => 'id',
'type' => Type::int(),
'rules' => ['required']
],
];
}
public function resolve($root, $args)
{
return Wine::findOrFail($args['id']);
}
}
这是graphql.php
<?php
declare(strict_types=1);
use exampleTypeExampleType;
use exampleQueryExampleQuery;
use exampleMutationExampleMutation;
use exampleTypeExampleRelationType;
return [
// The prefix for routes
'prefix' => 'graphql',
// The routes to make GraphQL request. Either a string that will apply
// to both query and mutation or an array containing the key 'query' and/or
// 'mutation' with the according Route
//
// Example:
//
// Same route for both query and mutation
//
// 'routes' => 'path/to/query/{graphql_schema?}',
//
// or define each route
//
// 'routes' => [
// 'query' => 'query/{graphql_schema?}',
// 'mutation' => 'mutation/{graphql_schema?}',
// ]
//
'routes' => '{graphql_schema?}',
// The controller to use in GraphQL request. Either a string that will apply
// to both query and mutation or an array containing the key 'query' and/or
// 'mutation' with the according Controller and method
//
// Example:
//
// 'controllers' => [
// 'query' => 'RebingGraphQLGraphQLController@query',
// 'mutation' => 'RebingGraphQLGraphQLController@mutation'
// ]
//
'controllers' => RebingGraphQLGraphQLController::class.'@query',
// Any middleware for the graphql route group
'middleware' => [],
// Additional route group attributes
//
// Example:
//
// 'route_group_attributes' => ['guard' => 'api']
//
'route_group_attributes' => [],
// The name of the default schema used when no argument is provided
// to GraphQL::schema() or when the route is used without the graphql_schema
// parameter.
'default_schema' => 'default',
// The schemas for query and/or mutation. It expects an array of schemas to provide
// both the 'query' fields and the 'mutation' fields.
//
// You can also provide a middleware that will only apply to the given schema
//
// Example:
//
// 'schema' => 'default',
//
// 'schemas' => [
// 'default' => [
// 'query' => [
// 'users' => 'AppGraphQLQueryUsersQuery'
// ],
// 'mutation' => [
//
// ]
// ],
// 'user' => [
// 'query' => [
// 'profile' => 'AppGraphQLQueryProfileQuery'
// ],
// 'mutation' => [
//
// ],
// 'middleware' => ['auth'],
// ],
// 'user/me' => [
// 'query' => [
// 'profile' => 'AppGraphQLQueryMyProfileQuery'
// ],
// 'mutation' => [
//
// ],
// 'middleware' => ['auth'],
// ],
// ]
//
// 'schemas' => [
// 'default' => [
// 'query' => [
// // 'example_query' => ExampleQuery::class,
// ],
// 'mutation' => [
// // 'example_mutation' => ExampleMutation::class,
// ],
// 'middleware' => [],
// 'method' => ['get', 'post'],
// ],
// ],
'schemas' => [
'default' => [
'query' => [
'wine' => AppGraphQLQueriesWineQuery::class,
'wines' => AppGraphQLQueriesWinesQuery::class,
]
],
],
// The types available in the application. You can then access it from the
// facade like this: GraphQL::type('user')
//
// Example:
//
// 'types' => [
// 'user' => 'AppGraphQLTypeUserType'
// ]
//
'types' => [
// 'example' => ExampleType::class,
// 'relation_example' => ExampleRelationType::class,
// RebingGraphQLSupportUploadType::class,
'Wine' => AppGraphQLTypesWineType::class,
],
// The types will be loaded on demand. Default is to load all types on each request
// Can increase performance on schemes with many types
// Presupposes the config type key to match the type class name property
'lazyload_types' => false,
// This callable will be passed the Error object for each errors GraphQL catch.
// The method should return an array representing the error.
// Typically:
// [
// 'message' => '',
// 'locations' => []
// ]
'error_formatter' => ['RebingGraphQLGraphQL', 'formatError'],
/*
* Custom Error Handling
*
* Expected handler signature is: function (array $errors, callable $formatter): array
*
* The default handler will pass exceptions to laravel Error Handling mechanism
*/
'errors_handler' => ['RebingGraphQLGraphQL', 'handleErrors'],
// You can set the key, which will be used to retrieve the dynamic variables
'params_key' => 'variables',
/*
* Options to limit the query complexity and depth. See the doc
* @ https://github.com/webonyx/graphql-php#security
* for details. Disabled by default.
*/
'security' => [
'query_max_complexity' => null,
'query_max_depth' => null,
'disable_introspection' => false,
],
/*
* You can define your own pagination type.
* Reference RebingGraphQLSupportPaginationType::class
*/
'pagination_type' => RebingGraphQLSupportPaginationType::class,
/*
* Config for GraphiQL (see (https://github.com/graphql/graphiql).
*/
'graphiql' => [
'prefix' => '/graphiql',
'controller' => RebingGraphQLGraphQLController::class.'@graphiql',
'middleware' => [],
'view' => 'graphql::graphiql',
'display' => env('ENABLE_GRAPHIQL', true),
],
/*
* Overrides the default field resolver
* See http://webonyx.github.io/graphql-php/data-fetching/#default-field-resolver
*
* Example:
*
* ```php
* 'defaultFieldResolver' => function ($root, $args, $context, $info) {
* },
* ```
* or
* ```php
* 'defaultFieldResolver' => [SomeKlass::class, 'someMethod'],
* ```
*/
'defaultFieldResolver' => null,
/*
* Any headers that will be added to the response returned by the default controller
*/
'headers' => [],
/*
* Any JSON encoding options when returning a response from the default controller
* See http://php.net/manual/function.json-encode.php for the full list of options
*/
'json_encoding_options' => 0,
];
您错过了一些导入和返回类型,请检查更新的代码:
app/GraphQL/Types/WineType.php
<?php
namespace AppGraphQLTypes;
use AppWine;
use GraphQLTypeDefinitionType;
use RebingGraphQLSupportType as GraphQLType;
class WineType extends GraphQLType
{
protected $attributes = [
'name' => 'Wine',
'description' => 'Details about a wine',
'model' => Wine::class
];
public function fields(): array
{
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => 'Id of the wine',
],
'name' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The name of the wine',
],
'description' => [
'type' => Type::nonNull(Type::string()),
'description' => 'Short description of the wine',
],
'color' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The color of the wine',
],
'grape_variety' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The grape variety of the wine',
],
'country' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The country of origin of the wine',
]
];
}
}
app/GraphQL/Query/WineQuery.php
<?php
namespace AppGraphQLQueries;
use AppWine;
use GraphQLTypeDefinitionType;
use RebingGraphQLSupportFacadesGraphQL;
use RebingGraphQLSupportQuery;
class WineQuery extends Query
{
protected $attributes = [
'name' => 'wine',
];
public function type(): Type
{
return GraphQL::type('Wine');
}
public function args():array
{
return [
'id' => [
'name' => 'id',
'type' => Type::int(),
'rules' => ['required']
],
];
}
public function resolve($root, $args)
{
return Wine::findOrFail($args['id']);
}
}
app/GraphQL/Query/WinesQuery.php
<?php
namespace AppGraphQLQueries;
use AppWine;
use GraphQLTypeDefinitionType;
use RebingGraphQLSupportFacadesGraphQL;
use RebingGraphQLSupportQuery;
class WinesQuery extends Query
{
protected $attributes = [
'name' => 'wines',
];
public function type(): Type
{
return Type::listOf(GraphQL::type('Wine'));
}
public function resolve($root, $args)
{
return Wine::all();
}
}