PHP Laravel GraphQL 查询声明不兼容问题



我按照以下文章在本地机器上使用 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();
}
}

最新更新