Custom Queries / Mutations
CoreShop Headless abstracts away the complexity of GraphQL and provides a simple API for developers to use. However, there are cases where you might want to write your own queries. For example, you might want to fetch custom entities or extend the default queries.
Extending Queries
CoreShop Headless provides a simple way to extend the default queries. You can extend the default queries by creating a
new class that implements the CoreShop\Bundle\HeadlessBundle\Query\CommandQueryInterface
Interface. For example:
CoreShop Headless uses Symfony Command Bus to execute the queries. So we need several things to make this work:
- A
Command
that gets the input parameters from the query - A
CommandHandler
that handles the Command - A
CommandQuery
that instantiates the Command and returns the result - (Optional) if your query is a Mutation Query, add the
Interface
CoreShop\Bundle\HeadlessBundle\Query\CommandMutationQueryInterface
.
Command
<?php
declare(strict_types=1);
namespace App\CoreShop\Headless\Command;
use CoreShop\Bundle\HeadlessBundle\Command\CommandInterface;
class MyCustomCommand implements CommandInterface
{
public function __construct(
public readonly string myArgument,
) {
}
}
Command Handler
<?php
declare(strict_types=1);
namespace App\CoreShop\Headless\CommandHandler;
use CoreShop\Bundle\HeadlessBundle\Command\MyCustomCommand;
class MyCustomHandler
{
public function __invoke(MyCustomCommand $myCustomCommand): string
{
return 'Hello World ' . $myCustomCommand->myArgument;
}
}
The handler needs to be registered as a service and tagged with messenger.message_handler
and
bus: coreshop_headless.bus
:
services:
App\CoreShop\Headless\CommandHandler\MyCustomHandler:
tags:
- { name: messenger.message_handler, bus: coreshop_headless.bus }
Command Query
Lastly, we need to create the Command Query that creates the GraphQL Query, instantiates the Command and returns the result:
<?php
declare(strict_types=1);
namespace App\CoreShop\Headless\Query;
use CoreShop\Bundle\HeadlessBundle\Command\MyCustomCommand;
use CoreShop\Bundle\HeadlessBundle\Command\CommandInterface;
use CoreShop\Bundle\HeadlessBundle\InputType\ActiveOrderInputType;
use CoreShop\Bundle\HeadlessBundle\InputType\InputTypeFactoryInterface;
use CoreShop\Bundle\HeadlessBundle\Query\ClassRestrictedCommandQueryInterface;
use CoreShop\Bundle\HeadlessBundle\Query\CommandQueryInterface;
use CoreShop\Bundle\HeadlessBundle\Query\QueryHelper;
use GraphQL\Type\Definition\Type;
class MyCustomQuery implements CommandQueryInterface, ClassRestrictedCommandQueryInterface
{
public function getName(array $context, array $config): string
{
return 'MyCustomQuery';
}
public function getCommand(array $args, array $context, array $config): CommandInterface
{
return new MyCustomCommand($context['configuration']->getConfiguration()['general']['store']);
}
public function configureInputArguments(array $context, array $config): array
{
return [
'myArgument' => [
'type' => Type::string(),
],
];
}
public function configureResultFields(array $context, array $config): array
{
return ['myResult' => Type::string()];
}
public function prepareResult(mixed $result, array $context, array $config): array
{
return [
'myResult' => $result,
];
}
}
The Query needs to be registered as a service and tagged with coreshop.headless.command_query
:
services:
App\CoreShop\Headless\Query\MyCustomQuery:
tags:
- { name: coreshop.headless.command_query }
Usage
query {
MyCustomQuery(myArgument: ":) My Argument") {
myResult
}
}
Voila, you have successfully extended the default queries.