Skip to content
Open
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
8 changes: 7 additions & 1 deletion Annotation/ApiMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
* @Target({"CLASS"})
* @Attributes(
* @Attribute("path", type="string"),
* @Attribute("type", type="string")
* @Attribute("type", type="string"),
* @Attribute("return", type="string"),
* )
*/
class ApiMessage
Expand All @@ -27,6 +28,11 @@ class ApiMessage
*/
public $type;

/**
* @var string
*/
public $return;

/**
* @throws InvalidArgumentException
*/
Expand Down
13 changes: 9 additions & 4 deletions Factory/AnnotationResourceMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function create(string $resourceClass): ResourceMetadata
return $this->handleNotFound($parentResourceMetadata, $resourceClass);
}

return $this->createMetadata($resourceAnnotation);
return $this->createMetadata($resourceClass, $resourceAnnotation);
}

/**
Expand All @@ -66,22 +66,27 @@ private function handleNotFound(ResourceMetadata $parentPropertyMetadata = null,
throw new ResourceClassNotFoundException(sprintf('Resource "%s" not found.', $resourceClass));
}

private function createMetadata(ApiMessage $annotation): ResourceMetadata
private function createMetadata(string $messageClass, ApiMessage $annotation): ResourceMetadata
{
$method = $annotation->type === 'command' ? 'post' : 'get';
$collectionOperations = [
$method => ['method' => $method, 'controller' => 'api_platform_messenger.action.dispatch', 'defaults' => ['_api_platform_messenger_type' => $annotation->type]]
];

$graphqlOperation = $annotation->type === 'command' ? 'update' : 'query';
return new ResourceMetadata(
str_replace('/', '', $annotation->path),
null,
$annotation->path,
[],
$collectionOperations,
array_merge(['_api_platform_messenger' => true], $annotation->attributes),
array_merge(['_api_platform_messenger' => $messageClass], $annotation->attributes),
[],
null
[
$graphqlOperation => [
'return' => $annotation->return,
],
]
);
}
}
59 changes: 59 additions & 0 deletions GraphQl/MessageResolverFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Sam\ApiPlatform\Messenger\GraphQl;

use ApiPlatform\Core\GraphQl\Resolver\Factory\ResolverFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer;
use GraphQL\Type\Definition\ResolveInfo;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class MessageResolverFactory implements ResolverFactoryInterface
{
private $decoratedResolver;
private $resourceMetadataFactory;
private $messageBus;
private $denormalizer;
private $normalizer;

public function __construct(
ResolverFactoryInterface $decoratedResolver,
ResourceMetadataFactoryInterface $resourceMetadataFactory,
DenormalizerInterface $denormalizer,
NormalizerInterface $normalizer,
MessageBusInterface $messageBus
)
{
$this->decoratedResolver = $decoratedResolver;
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->denormalizer = $denormalizer;
$this->normalizer = $normalizer;
$this->messageBus = $messageBus;
}

public function __invoke(string $resourceClass = null, string $rootClass = null, string $operationName = null, ResourceMetadata $metadata = null): callable
{
if (null === $messageClass = $metadata->getAttribute('_api_platform_messenger')) {
return $this->decoratedResolver->__invoke($resourceClass, $rootClass, $operationName, $metadata);
}

return function ($root, $args, $context, ResolveInfo $info) use ($messageClass, $operationName, $metadata) {
$message = $this->denormalizer->denormalize(
$args['input'] ?? [],
$messageClass
);

$normalizationContext = $metadata->getGraphqlAttribute($operationName ?? '', 'normalization_context', [], true);
$normalizationContext['attributes'] = $info->getFieldSelection(PHP_INT_MAX);

return $this->normalizer->normalize(
$this->messageBus->dispatch($message),
ItemNormalizer::FORMAT,
$normalizationContext
);
};
}
}
21 changes: 21 additions & 0 deletions Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,26 @@
<argument type="service" id="api_platform_messenger.metadata.allow_resource_without_property.inner" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
</service>

<!-- GraphQL -->
<service id="api_platform_messenger.graphql.resolver.collection"
class="Sam\ApiPlatform\Messenger\GraphQl\MessageResolverFactory"
decorates="api_platform.graphql.resolver.factory.collection">
<argument type="service" id="api_platform_messenger.graphql.resolver.collection.inner" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
<argument type="service" id="serializer" />
<argument type="service" id="serializer" />
<argument type="service" id="message_bus" />
</service>

<service id="api_platform_messenger.graphql.resolver.item_mutation"
class="Sam\ApiPlatform\Messenger\GraphQl\MessageResolverFactory"
decorates="api_platform.graphql.resolver.factory.item_mutation">
<argument type="service" id="api_platform_messenger.graphql.resolver.item_mutation.inner" />
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
<argument type="service" id="serializer" />
<argument type="service" id="serializer" />
<argument type="service" id="message_bus" />
</service>
</services>
</container>
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}
},
"require": {
"api-platform/core": "^2.1",
"api-platform/core": ">=2.1",
"symfony/framework-bundle": "^3.3 || ^4.0"
}
}