Skip to content

Commit

Permalink
* add license, tests and documentation
Browse files Browse the repository at this point in the history
bwaidelich committed Apr 27, 2016
1 parent b93ad99 commit d0bf1de
Showing 12 changed files with 370 additions and 780 deletions.
13 changes: 12 additions & 1 deletion Classes/AccessibleObject.php
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ public function offsetGet($propertyName)
return (boolean)call_user_func([$this->object, $propertyName]);
}
$result = ObjectAccess::getProperty($this->object, $propertyName);
if ($result instanceof \Iterator) {
if (is_array($result) || $result instanceof \Iterator) {
return new IterableAccessibleObject($result);
}
if ($result instanceof \DateTimeInterface) {
@@ -112,4 +112,15 @@ public function offsetUnset($offset)
throw new \RuntimeException('The AccessibleObject wrapper does not allow for mutation!', 1460895625);
}

/**
* This is required in order to implicitly cast wrapped string types for example
*
* @return string
*/
function __toString()
{
return (string)$this->object;
}


}
11 changes: 6 additions & 5 deletions Classes/Controller/StandardController.php
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ class StandardController extends ActionController
protected $supportedMediaTypes = ['application/json', 'text/html'];

/**
* @param string $endpoint
* @param string $endpoint The GraphQL endpoint, to allow for providing multiple APIs (this value is set from the routing usually)
* @return void
*/
public function indexAction($endpoint)
@@ -35,10 +35,10 @@ public function indexAction($endpoint)
}

/**
* @param string $endpoint
* @param string $query
* @param string $variables
* @param string $operationName
* @param string $endpoint The GraphQL endpoint, to allow for providing multiple APIs (this value is set from the routing usually)
* @param string $query The GraphQL query string (see GraphQL::execute())
* @param string $variables JSON-encoded list of variables (if any, see GraphQL::execute())
* @param string $operationName The operation to execute (if multiple, see GraphQL::execute())
* @return string
* @Flow\SkipCsrfProtection
*/
@@ -47,6 +47,7 @@ public function queryAction($endpoint, $query, $variables = null, $operationName
$this->verifySettings($endpoint);
$decodedVariables = json_decode($variables, true);
try {

$querySchema = $this->typeResolver->get($this->settings['endpoints'][$endpoint]['querySchema']);
$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;
14 changes: 13 additions & 1 deletion Classes/IterableAccessibleObject.php
Original file line number Diff line number Diff line change
@@ -58,12 +58,24 @@ public function __construct($object)
}
}

/**
* @return \Iterator
*/
public function getIterator()
{
return $this->innerIterator;
}

/**
* @return AccessibleObject
*/
public function current()
{
return new AccessibleObject($this->innerIterator->current());
$currentElement = $this->innerIterator->current();
if (is_object($currentElement)) {
return new AccessibleObject($currentElement);
}
return $currentElement;
}

/**
695 changes: 21 additions & 674 deletions LICENSE

Large diffs are not rendered by default.

133 changes: 124 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,110 @@
# Wwwision.GraphQL

This package allows you to easily provide GraphQL endpoints with Neos and Flow.
Easily create GraphQL APIs with Neos and Flow.

## Background

This package is a small collection of tools that'll make it easier to provide [GraphQL](http://graphql.org/) endpoints
with Neos and Flow.
It is a wrapper for the [PHP port of webonyx](https://github.com/webonyx/graphql-php) that comes with following additions:

ExampleRootQuery.php
* A `TypeResolver` that allows for easy interdependency between complex GraphQL type definitions
* The `AccessibleObject` and `IterableAccessibleObject` wrappers that make it possible to expose arbitrary objects to
the GraphQL API
* A `StandardController` that renders the [GraphiQL IDE](https://github.com/graphql/graphiql) and acts as dispatcher
for API calls

## Installation

```
composer require wwwision/graphql
```

(Refer to the [composer documentation](https://getcomposer.org/doc/) for more details)

## Simple tutorial

Create a simple Root Query definition within any Flow package:

`ExampleRootQuery.php`:

<?php
namespace Your\Package;

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use Wwwision\GraphQL\TypeResolver;

class ExampleRootQuery extends ObjectType
{
/**
* @param TypeResolver $typeResolver
*/
public function __construct(TypeResolver $typeResolver)
{
return parent::__construct([
'name' => 'ExampleRootQuery',
'fields' => [
'ping' => [
'type' => Type::string(),
'resolve' => function () {
return 'pong';
},
],
],
]);
}
}

Now register this endpoint like so:

`Settings.yaml`:

Wwwision:
GraphQL:
endpoints:
'test':
'querySchema': 'Your\Package\ExampleRootQuery'

And, lastly, activate the corresponding routes:

`Settings.yaml`:

TYPO3:
Flow:
mvc:
routes:
'Wwwision.GraphQL':
variables:
'endpoint': 'test'

This will make the endpoint "test" available under `/test`.

Note: If you already have more specific routes in place, or want to provide multiple GraphQL endpoints you can as well
activate routes in your global `Routes.yaml` file:

-
name: 'GraphQL API'
uriPattern: '<GraphQLSubroutes>'
subRoutes:
'GraphQLSubroutes':
package: 'Wwwision.GraphQL'
variables:
'endpoint': 'test'

Congratulations, your first GraphQL API is done and you should be able to invoke the GraphiQL IDE by browsing to `/test`:

![](graphiql.png)


## More advanced tutorial

Again, start with the Root Query definition

`ExampleRootQuery.php`:

<?php
namespace Wwwision\Test;
namespace Your\Package;

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
@@ -35,23 +131,42 @@ ExampleRootQuery.php
}
}

Now register this endpoint like so:

Settings.yaml
`Settings.yaml`:

Wwwision:
GraphQL:
endpoints:
'neos':
'querySchema': 'Your\Package\TheRootQueryType'
'mutationSchema': 'Your\Package\TheRootMutationType'
'test':
'querySchema': 'Your\Package\ExampleRootQuery'

Settings.yaml
And, lastly, activate the corresponding routes:

`Settings.yaml`:

TYPO3:
Flow:
mvc:
routes:
'Wwwision.GraphQL':
variables:
'endpoint': 'neos'
'endpoint': 'test'

This will make the endpoint "test" available under `/test`.

Note: If you already have more specific routes in place, or want to provide multiple GraphQL endpoints you can as well
activate routes in your global `Routes.yaml` file:

-
name: 'GraphQL API'
uriPattern: '<GraphQLSubroutes>'
subRoutes:
'GraphQLSubroutes':
package: 'Wwwision.GraphQL'
variables:
'endpoint': 'test'

Congratulations, your first GraphQL API is done and you should be able to invoke the GraphiQL IDE by browsing to `/test`:

![](graphiql_01.png)
Loading

0 comments on commit d0bf1de

Please sign in to comment.