Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions Controller/GraphController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,44 @@

class GraphController extends Controller
{
public function endpointAction(Request $request)
public function endpointAction(Request $request, $schemaName = null)
{
$payload = $this->processNormalQuery($request);
$payload = $this->processNormalQuery($request, $schemaName);

return new JsonResponse($payload, 200);
}

public function batchEndpointAction(Request $request)
public function batchEndpointAction(Request $request, $schemaName = null)
{
$payloads = $this->processBatchQuery($request);
$payloads = $this->processBatchQuery($request, $schemaName);

return new JsonResponse($payloads, 200);
}

private function processBatchQuery(Request $request)
private function processBatchQuery(Request $request, $schemaName = null)
{
$queries = $this->get('overblog_graphql.request_batch_parser')->parse($request);
$payloads = [];

foreach ($queries as $query) {
$payloadResult = $this->get('overblog_graphql.request_executor')->execute([
'query' => $query['query'],
'variables' => $query['variables'],
]);
$payloadResult = $this->get('overblog_graphql.request_executor')->execute(
[
'query' => $query['query'],
'variables' => $query['variables'],
],
[],
$schemaName
);
$payloads[] = ['id' => $query['id'], 'payload' => $payloadResult->toArray()];
}

return $payloads;
}

private function processNormalQuery(Request $request)
private function processNormalQuery(Request $request, $schemaName = null)
{
$params = $this->get('overblog_graphql.request_parser')->parse($request);
$data = $this->get('overblog_graphql.request_executor')->execute($params)->toArray();
$data = $this->get('overblog_graphql.request_executor')->execute($params, [], $schemaName)->toArray();

return $data;
}
Expand Down
10 changes: 8 additions & 2 deletions Controller/GraphiQLController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@

class GraphiQLController extends Controller
{
public function indexAction()
public function indexAction($schemaName = null)
{
if (null === $schemaName) {
$endpoint = $this->generateUrl('overblog_graphql_endpoint');
} else {
$endpoint = $this->generateUrl('overblog_graphql_multiple_endpoint', ['schemaName' => $schemaName]);
}

return $this->render(
$this->getParameter('overblog_graphql.graphiql_template'),
[
'endpoint' => $this->generateUrl('overblog_graphql_endpoint'),
'endpoint' => $endpoint,
'versions' => [
'graphiql' => $this->getParameter('overblog_graphql.versions.graphiql'),
'react' => $this->getParameter('overblog_graphql.versions.react'),
Expand Down
29 changes: 22 additions & 7 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,26 @@ public function getConfigTreeBuilder()
->scalarNode('internal_error_message')->defaultNull()->end()
->booleanNode('config_validation')->defaultValue($this->debug)->end()
->arrayNode('schema')
->addDefaultsIfNotSet()
->children()
->scalarNode('query')->defaultNull()->end()
->scalarNode('mutation')->defaultNull()->end()
->scalarNode('subscription')->defaultNull()->end()
->beforeNormalization()
->ifTrue(function ($v) {
$needNormalization = isset($v['query']) && is_string($v['query']) ||
isset($v['mutation']) && is_string($v['mutation']) ||
isset($v['subscription']) && is_string($v['subscription']);

return $needNormalization;
})
->then(function ($v) {
return ['default' => $v];
})
->end()
->useAttributeAsKey('name')
->prototype('array')
->addDefaultsIfNotSet()
->children()
->scalarNode('query')->defaultNull()->end()
->scalarNode('mutation')->defaultNull()->end()
->scalarNode('subscription')->defaultNull()->end()
->end()
->end()
->end()
->arrayNode('mappings')
Expand Down Expand Up @@ -142,8 +157,8 @@ public function getConfigTreeBuilder()
->arrayNode('versions')
->addDefaultsIfNotSet()
->children()
->scalarNode('graphiql')->defaultValue('0.7.1')->end()
->scalarNode('react')->defaultValue('15.0.2')->end()
->scalarNode('graphiql')->defaultValue('0.7.8')->end()
->scalarNode('react')->defaultValue('15.3.2')->end()
->end()
->end()
->end();
Expand Down
23 changes: 15 additions & 8 deletions DependencyInjection/OverblogGraphQLExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
use Overblog\GraphQLBundle\Config\TypeWithOutputFieldsDefinition;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class OverblogGraphQLExtension extends Extension implements PrependExtensionInterface
Expand Down Expand Up @@ -120,13 +122,18 @@ private function setSchemaBuilderArguments(array $config, ContainerBuilder $cont
private function setSchemaArguments(array $config, ContainerBuilder $container)
{
if (isset($config['definitions']['schema'])) {
$container
->getDefinition($this->getAlias().'.schema')
->replaceArgument(0, $config['definitions']['schema']['query'])
->replaceArgument(1, $config['definitions']['schema']['mutation'])
->replaceArgument(2, $config['definitions']['schema']['subscription'])
->setPublic(true)
;
$executorDefinition = $container->getDefinition($this->getAlias().'.request_executor');

foreach ($config['definitions']['schema'] as $schemaName => $schemaConfig) {
$schemaID = sprintf('%s.schema_%s', $this->getAlias(), $schemaName);
$definition = new Definition('GraphQL\Schema');
$definition->setFactory([new Reference('overblog_graphql.schema_builder'), 'create']);
$definition->setArguments([$schemaConfig['query'], $schemaConfig['mutation'], $schemaConfig['subscription']]);
$definition->setPublic(false);
$container->setDefinition($schemaID, $definition);

$executorDefinition->addMethodCall('addSchema', [$schemaName, new Reference($schemaID)]);
}
}
}

Expand All @@ -153,7 +160,7 @@ public function getConfiguration(array $config, ContainerBuilder $container)
/**
* Returns a list of custom exceptions mapped to error/warning classes.
*
* @param array $config
* @param array $exceptionConfig
* @return array Custom exception map, [exception => UserError/UserWarning].
*/
private function buildExceptionMap(array $exceptionConfig)
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,38 @@ Batching
Batching can help decrease io between server and client.
The default route of batching is `/batch`.

Multiple schema endpoint
------------------------

```yaml
#app/config/config.yml

overblog_graphql:
definitions:
schema:
foo:
query: fooQuery
bar:
query: barQuery
mutation: barMutation
```

**foo** schema endpoint can be access:

type | Path
-----| -----
simple request | `/graphql/foo`
batch request | `/graphql/foo/batch`
graphiQL | `/graphiql/foo`

**bar** schema endpoint can be access:

type | Path
-----| -----
simple request | `/graphql/bar`
batch request | `/graphql/bar/batch`
graphiQL | `/graphiql/bar`

Contribute
----------

Expand Down
45 changes: 40 additions & 5 deletions Request/Executor.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@
use Overblog\GraphQLBundle\Event\Events;
use Overblog\GraphQLBundle\Event\ExecutorContextEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class Executor
{
private $schema;
/**
* @var Schema[]
*/
private $schemas;

/**
* @var EventDispatcherInterface|null
Expand All @@ -36,14 +40,20 @@ class Executor
/** @var ErrorHandler|null */
private $errorHandler;

public function __construct(Schema $schema, EventDispatcherInterface $dispatcher = null, $throwException = false, ErrorHandler $errorHandler = null)
public function __construct(EventDispatcherInterface $dispatcher = null, $throwException = false, ErrorHandler $errorHandler = null)
{
$this->schema = $schema;
$this->dispatcher = $dispatcher;
$this->throwException = (bool) $throwException;
$this->errorHandler = $errorHandler;
}

public function addSchema($name, Schema $schema)
{
$this->schemas[$name] = $schema;

return $this;
}

public function setMaxQueryDepth($maxQueryDepth)
{
/** @var QueryDepth $queryDepth */
Expand All @@ -70,16 +80,18 @@ public function setThrowException($throwException)
return $this;
}

public function execute(array $data, array $context = [])
public function execute(array $data, array $context = [], $schemaName = null)
{
if (null !== $this->dispatcher) {
$event = new ExecutorContextEvent($context);
$this->dispatcher->dispatch(Events::EXECUTOR_CONTEXT, $event);
$context = $event->getExecutorContext();
}

$schema = $this->getSchema($schemaName);

$executionResult = GraphQL::executeAndReturnResult(
$this->schema,
$schema,
isset($data[ParserInterface::PARAM_QUERY]) ? $data[ParserInterface::PARAM_QUERY] : null,
$context,
$context,
Expand All @@ -93,4 +105,27 @@ public function execute(array $data, array $context = [])

return $executionResult;
}

/**
* @param string|null $name
*
* @return Schema
*/
public function getSchema($name = null)
{
if (empty($this->schemas)) {
throw new \RuntimeException('At least one schema should be declare.');
}

if (null === $name) {
$schema = array_values($this->schemas)[0];
} else {
if (!isset($this->schemas[$name])) {
throw new NotFoundHttpException(sprintf('Could not found "%s" schema.', $name));
}
$schema = $this->schemas[$name];
}

return $schema;
}
}
5 changes: 5 additions & 0 deletions Resources/config/routing/graphiql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ overblog_graphql_graphiql:
path: /graphiql
defaults:
_controller: OverblogGraphQLBundle:GraphiQL:index

overblog_graphql_graphiql_multiple:
path: /graphiql/{schemaName}
defaults:
_controller: OverblogGraphQLBundle:GraphiQL:index
12 changes: 12 additions & 0 deletions Resources/config/routing/graphql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ overblog_graphql_batch_endpoint:
defaults:
_controller: OverblogGraphQLBundle:Graph:batchEndpoint
_format: "json"

overblog_graphql_multiple_endpoint:
path: /graphql/{schemaName}
defaults:
_controller: OverblogGraphQLBundle:Graph:endpoint
_format: "json"

overblog_graphql_batch_multiple_endpoint:
path: /graphql/{schemaName}/batch
defaults:
_controller: OverblogGraphQLBundle:Graph:batchEndpoint
_format: "json"
10 changes: 0 additions & 10 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ services:
overblog_graphql.request_executor:
class: Overblog\GraphQLBundle\Request\Executor
arguments:
- "@overblog_graphql.schema"
- "@event_dispatcher"
- "%kernel.debug%"
- "@overblog_graphql.error_handler"
Expand All @@ -28,15 +27,6 @@ services:
overblog_graphql.request_batch_parser:
class: Overblog\GraphQLBundle\Request\BatchParser

overblog_graphql.schema:
class: GraphQL\Schema
public: false
factory: ["@overblog_graphql.schema_builder", create]
arguments:
- ~
- ~
- ~

overblog_graphql.schema_builder:
class: Overblog\GraphQLBundle\Definition\Builder\SchemaBuilder
public: false
Expand Down
Loading