Closed benjamingb closed 7 years ago
None that I am aware of
As of version 0.10.0 there is a PSR-7 compatible standard server. It should be possible to use it as is with Zend Expressive.
FYI, this is the integration I came up with. It could be cleaner, but at least it is simple. The middleware itself looks like:
<?php
declare(strict_types=1);
namespace Application\Action;
use Application\Api\Schema;
use GraphQL\Doctrine\DefaultFieldResolver;
use GraphQL\GraphQL;
use GraphQL\Server\StandardServer;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse;
class GraphQLAction implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
{
GraphQL::setDefaultFieldResolver(new DefaultFieldResolver());
$schema = new Schema();
$server = new StandardServer([
'schema' => $schema,
'queryBatching' => true,
'debug' => true,
]);
$parsedBody = json_decode($request->getBody()->getContents(), true);
$request = $request->withParsedBody($parsedBody);
$response = $server->executePsrRequest($request);
return new JsonResponse($response);
}
}
Configure it in config/autoload/dependencies.global.php
:
return [
'dependencies' => [
'invokables' => [
GraphQLAction::class => GraphQLAction::class,
],
],
];
And declare a route in config/routes.php
:
$app->post('/graphql', Application\Action\GraphQLAction::class, 'graphql');
@PowerKiKi You don't need following lines:
$parsedBody = json_decode($request->getBody()->getContents(), true);
$request = $request->withParsedBody($parsedBody);
They seem redundant as the server should already do it (if Content-Type
header in the request is application/json
).
Following should work as is (if something doesn't work, then it is probably a bug):
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
{
$schema = new Schema();
$server = new StandardServer([
'schema' => $schema,
'queryBatching' => true,
'debug' => true,
'fieldResolver' => new DefaultFieldResolver()
]);
$response = $server->executePsrRequest($request);
return new JsonResponse($response);
}
Also, there is complementary project https://github.com/phps-cans/psr7-middleware-graphql
Thanks for mentioning psr7-middleware-graphql, I wasn't aware of it.
The parsing of JSON is necessary in my case, otherwise parsedBody is empty and the server will fail to decode json from non-parsed body. I was surprised by this behavior as I was expecting it would work out of the box as you described. Would you want me to open an issue for that ?
If parsedBody is empty, then it is a bug. Will appreciate if you open an issue for it. But are you sure Content-Type
header is set properly to application/json
in your case?
Do you know of an example that works with Zend Expressive? He tried, but it works