-
-
Notifications
You must be signed in to change notification settings - Fork 940
Closed
Description
Hi all,
Because GraphiQL and GraphQL Playground does not support file uploading, I use Altair to test my queries.
I do exactly what's the doc said:
Handling File Upload
handling-file-upload with graphql
I get this error, I do not know if it's the custom event sucriber the problem:
{
"errors": [
{
"debugMessage": "GraphQL query is not valid.",
"message": "GraphQL query is not valid.",
"extensions": {
"category": "user",
"status": 400
},
"trace": [
{
"file": "E:\\increzia\\server\\vendor\\symfony\\http-kernel\\HttpKernel.php",
"line": 157,
"call": "ApiPlatform\\Core\\GraphQl\\Action\\EntrypointAction::__invoke(instance of Symfony\\Component\\HttpFoundation\\Request)"
},
{
"file": "E:\\increzia\\server\\vendor\\symfony\\http-kernel\\HttpKernel.php",
"line": 79,
"call": "Symfony\\Component\\HttpKernel\\HttpKernel::handleRaw(instance of Symfony\\Component\\HttpFoundation\\Request, 1)"
},
{
"file": "E:\\increzia\\server\\vendor\\symfony\\http-kernel\\Kernel.php",
"line": 195,
"call": "Symfony\\Component\\HttpKernel\\HttpKernel::handle(instance of Symfony\\Component\\HttpFoundation\\Request, 1, true)"
},
{
"file": "E:\\increzia\\server\\public\\index.php",
"line": 20,
"call": "Symfony\\Component\\HttpKernel\\Kernel::handle(instance of Symfony\\Component\\HttpFoundation\\Request)"
}
]
}
]
}
my query:
mutation UploadMediaObject($file: Upload!) {
uploadMediaObject(input: {file: $file}) {
mediaObject {
id
contentUrl
}
}
my custom event suscriber
<?php
// api/src/EventSubscriber/ResolveMediaObjectContentUrlSubscriber.php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use App\Entity\MediaObject;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Vich\UploaderBundle\Storage\StorageInterface;
final class ResolveMediaObjectContentUrlSubscriber implements EventSubscriberInterface
{
private $storage;
public function __construct(StorageInterface $storage)
{
$this->storage = $storage;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['onPreSerialize', EventPriorities::PRE_SERIALIZE],
];
}
public function onPreSerialize(ViewEvent $event): void
{
$controllerResult = $event->getControllerResult();
$request = $event->getRequest();
if ($controllerResult instanceof Response || !$request->attributes->getBoolean('_api_persist', true)) {
return;
}
if (!($attributes = RequestAttributesExtractor::extractAttributes($request)) || !\is_a($attributes['resource_class'], MediaObject::class, true)) {
return;
}
$mediaObjects = $controllerResult;
if (!is_iterable($mediaObjects)) {
$mediaObjects = [$mediaObjects];
}
foreach ($mediaObjects as $mediaObject) {
if (!$mediaObject instanceof MediaObject) {
continue;
}
$mediaObject->contentUrl = $this->storage->resolveUri($mediaObject, 'file');
}
}
}
Entity:
<?php
// api/src/Entity/MediaObject.php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Resolver\CreateMediaObjectResolver;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity
* @ApiResource(
* iri="http://schema.org/MediaObject",
* normalizationContext={
* "groups"={"media_object_read"}
* },
* denormalizationContext={"groups"={"write"}},
*
* graphql={
* "upload"={
* "mutation"=CreateMediaObjectResolver::class,
* "deserialize"=false,
* "args"={
* "file"={"type"="Upload!", "description"="The file to upload"}
* }
* },
* "udate",
* "delete"
* },
* )
* @Vich\Uploadable
*/
class MediaObject
{
/**
* @var int|null
*
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
* @ORM\Id
*/
protected $id;
/**
* @var string|null
*
* @ApiProperty(iri="http://schema.org/contentUrl")
* @Groups({"media_object_read"})
*/
public $contentUrl;
/**
* @var File|null
*
* @Assert\NotNull(groups={"media_object_create"})
* @Vich\UploadableField(mapping="media_object", fileNameProperty="filePath")
*/
public $file;
/**
* @var string|null
*
* @ORM\Column(nullable=true)
*
* @Groups("write")
*
*/
public $filePath;
public function getId(): ?int
{
return $this->id;
}
public function getFilePath(): ?string
{
return $this->filePath;
}
public function setFilePath(?string $filePath): self
{
$this->filePath = $filePath;
return $this;
}
}
Resolver
<?php
// api/src/Resolver/CreateMediaObjectResolver.php
namespace App\Resolver;
use ApiPlatform\Core\GraphQl\Resolver\MutationResolverInterface;
use App\Entity\MediaObject;
final class CreateMediaObjectResolver implements MutationResolverInterface
{
/**
* @param null $item
*/
public function __invoke($item, array $context): MediaObject
{
$uploadedFile = $context['args']['input']['file'];
$mediaObject = new MediaObject();
$mediaObject->file = $uploadedFile;
return $mediaObject;
}
}
Metadata
Metadata
Assignees
Labels
No labels