Skip to content

Commit

Permalink
FEATURE: GraphQLContext with access to current HTTP Request
Browse files Browse the repository at this point in the history
Adds a custom `GraphQLContext` that is available in all resolvers
and allows access to the current HTTP Request.

Example::

    'resolve' => function ($value, array $args, GraphQLContext $context) {
        $baseUri = $context->getHttpRequest()->getBaseUri();
    },
  • Loading branch information
bwaidelich committed May 30, 2017
1 parent b4d3b5a commit 5dbbcfc
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 1 deletion.
4 changes: 3 additions & 1 deletion Classes/Controller/StandardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use GraphQL\Schema;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Controller\ActionController;
use Wwwision\GraphQL\GraphQLContext;
use Wwwision\GraphQL\TypeResolver;
use Wwwision\GraphQL\View\GraphQlView;

Expand Down Expand Up @@ -59,7 +60,8 @@ public function queryAction($endpoint, $query, $variables = null, $operationName
$mutationSchema = isset($this->settings['endpoints'][$endpoint]['mutationSchema']) ? $this->typeResolver->get($this->settings['endpoints'][$endpoint]['mutationSchema']) : null;
$subscriptionSchema = isset($this->settings['endpoints'][$endpoint]['subscriptionSchema']) ? $this->typeResolver->get($this->settings['endpoints'][$endpoint]['subscriptionSchema']) : null;
$schema = new Schema($querySchema, $mutationSchema, $subscriptionSchema);
$result = GraphQL::executeAndReturnResult($schema, $query, null, null, $variables, $operationName);
$context = new GraphQLContext($this->request->getHttpRequest());
$result = GraphQL::executeAndReturnResult($schema, $query, null, $context, $variables, $operationName);
$this->view->assign('result', $result);
}

Expand Down
32 changes: 32 additions & 0 deletions Classes/GraphQLContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
namespace Wwwision\GraphQL;

use Neos\Flow\Http\Request as HttpRequest;

/**
* A custom context that will be accessible to all resolvers
*/
final class GraphQLContext
{
/**
* @var HttpRequest
*/
private $httpRequest;

/**
* @param HttpRequest $httpRequest
*/
public function __construct(HttpRequest $httpRequest)
{
$this->httpRequest = $httpRequest;
}

/**
* @return HttpRequest
*/
public function getHttpRequest()
{
return $this->httpRequest;
}

}
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ It is a wrapper for the [PHP port of webonyx](https://github.com/webonyx/graphql
* A `StandardController` that renders the [GraphiQL IDE](https://github.com/graphql/graphiql) and acts as dispatcher
for API calls
* A HTTP Component that responds to `OPTIONS` requests correctly (required for CORS preflight requests for example)
* A custom `GraphQLContext` that is available in all resolvers and allows access to the current HTTP Request

## Installation

Expand Down Expand Up @@ -106,3 +107,25 @@ activate routes in your global `Routes.yaml` file:
![](graphiql.png)

For a more advanced example, have a look at the [Neos Content Repository implementation](https://github.com/bwaidelich/Wwwision.Neos.GraphQL)

## Custom context

Resolvers should be as simple and self-contained as possible. But sometimes it's useful to have access to the current
HTTP request. For example in order to do explicit authentication or to render URLs.
With v2.1+ there's a new `GraphQLContext` accessible to all resolvers that allows to access the current HTTP request:

```php
<?php
// ...
use Wwwision\GraphQL\GraphQLContext;
// ...
'resolve' => function ($value, array $args, GraphQLContext $context) {
$baseUri = $context->getHttpRequest()->getBaseUri();
// ...
},
```

`$value` is the object containing the field. Its value is `null` on the root mutation/query.
`$args` is the array of arguments specified for that field. It's an empty array if no arguments have been specified.
`$context` is an instance of the `GraphQLContext` with a getter for the current HTTP request.
34 changes: 34 additions & 0 deletions Tests/Unit/GraphQLContextTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
namespace Wwwision\GraphQL\Tests\Unit;

use Neos\Flow\Http\Request;
use Neos\Flow\Tests\UnitTestCase;
use Wwwision\GraphQL\GraphQLContext;

class GraphQLContextTest extends UnitTestCase
{

/**
* @var GraphQLContext
*/
private $graphQLContext;

/**
* @var Request|\PHPUnit_Framework_MockObject_MockObject
*/
private $mockHttpRequest;

public function setUp()
{
$this->mockHttpRequest = $this->getMockBuilder(Request::class)->disableOriginalConstructor()->getMock();
$this->graphQLContext = new GraphQLContext($this->mockHttpRequest);
}

/**
* @test
*/
public function getHttpRequestReturnsTheSpecifiedRequestInstance()
{
$this->assertSame($this->mockHttpRequest, $this->graphQLContext->getHttpRequest());
}
}

0 comments on commit 5dbbcfc

Please sign in to comment.