Skip to content

Issue with documentation in part with VichUploaderBundle #2058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
D3xime opened this issue Nov 7, 2024 · 5 comments
Open

Issue with documentation in part with VichUploaderBundle #2058

D3xime opened this issue Nov 7, 2024 · 5 comments

Comments

@D3xime
Copy link

D3xime commented Nov 7, 2024

Hello everyone,
i have seen an issue in ApiPlatform documentation about integration with VichUploaderBundle. The issue is when i follow the documentation step by step i got an error saying multipart can't be denormalize. The issue seems to appear in 3.3 to 4.0. I think, some part of the documentation like the creation of a dedicated controller are missing.

<?php
// api/src/Entity/MediaObject.php

namespace App\Entity;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model;
use App\State\SaveMediaObject;
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;

#[Vich\Uploadable]
#[ORM\Entity]
#[ApiResource(
    normalizationContext: ['groups' => ['media_object:read']],
    types: ['https://schema.org/MediaObject'],
    outputFormats: ['jsonld' => ['application/ld+json']],
    operations: [
        new Get(),
        new GetCollection(),
        new Post(
            inputFormats: ['multipart' => ['multipart/form-data']],
            openapi: new Model\Operation(
                requestBody: new Model\RequestBody(
                    content: new \ArrayObject([
                        'multipart/form-data' => [
                            'schema' => [
                                'type' => 'object',
                                'properties' => [
                                    'file' => [
                                        'type' => 'string',
                                        'format' => 'binary'
                                    ]
                                ]
                            ]
                        ]
                    ])
                )
            )
        )
    ]
)]
class MediaObject
{
    #[ORM\Id, ORM\Column, ORM\GeneratedValue]
    private ?int $id = null;

    #[ApiProperty(types: ['https://schema.org/contentUrl'], writable: false)]
    #[Groups(['media_object:read'])]
    public ?string $contentUrl = null;

    #[Vich\UploadableField(mapping: 'media_object', fileNameProperty: 'filePath')]
    #[Assert\NotNull]
    public ?File $file = null;

    #[ApiProperty(writable: false)]
    #[ORM\Column(nullable: true)]
    public ?string $filePath = null;

    public function getId(): ?int
    {
        return $this->id;
    }
}

Above the entity shown in documentation of apiPlatform 4.0

Below the entity shown in document of apiPlatform 3.2

<?php
// api/src/Entity/MediaObject.php

namespace App\Entity;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model;
use App\Controller\CreateMediaObjectAction;
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;

#[Vich\Uploadable]
#[ORM\Entity]
#[ApiResource(
    normalizationContext: ['groups' => ['media_object:read']], 
    types: ['https://schema.org/MediaObject'],
    operations: [
        new Get(),
        new GetCollection(),
        new Post(
            controller: CreateMediaObjectAction::class, 
            deserialize: false, 
            validationContext: ['groups' => ['Default', 'media_object_create']], 
            openapi: new Model\Operation(
                requestBody: new Model\RequestBody(
                    content: new \ArrayObject([
                        'multipart/form-data' => [
                            'schema' => [
                                'type' => 'object', 
                                'properties' => [
                                    'file' => [
                                        'type' => 'string', 
                                        'format' => 'binary'
                                    ]
                                ]
                            ]
                        ]
                    ])
                )
            )
        )
    ]
)]
class MediaObject
{
    #[ORM\Id, ORM\Column, ORM\GeneratedValue]
    private ?int $id = null;

    #[ApiProperty(types: ['https://schema.org/contentUrl'])]
    #[Groups(['media_object:read'])]
    public ?string $contentUrl = null;

    #[Vich\UploadableField(mapping: 'media_object', fileNameProperty: 'filePath')]
    #[Assert\NotNull(groups: ['media_object_create'])]
    public ?File $file = null;

    #[ORM\Column(nullable: true)] 
    public ?string $filePath = null;

    public function getId(): ?int
    {
        return $this->id;
    }
}

https://api-platform.com/docs/core/file-upload/

Thanks for reading, if i missing something feel free to answer, i will be enthusiast to respond you.

-- Déxime

@vinceAmstoutz
Copy link
Contributor

vinceAmstoutz commented Nov 14, 2024

@D3xime You're welcome to contribute, check our CONTRIBUTING.md and submit your suggestions. Thanks!

@mbrodala
Copy link
Contributor

mbrodala commented Mar 7, 2025

This issue can be avoided by adding deserialize: false to your Post() operation. Also see #1512

@lucastrahlendorff
Copy link
Contributor

Had the same issue with the error message Serialization for the format "multipart" is not supported.. It only affected the swagger documentation. It was resolved by switching the defined formats in api_platform.yaml (so it's probably a issue in the doc generator?):

formats:
    jsonld: ['application/ld+json']
    multipart: ['multipart/form-data']

Moving multipart from the first to the second position under "formats" was all it needed.

This issue can be avoided by adding deserialize: false to your Post() operation. Also see #1512

Setting deserialize: false for the post operation was not needed in our scenario as it just disabled deserializing and prevented our endpoint to return anything else then 'null'.

@mbrodala
Copy link
Contributor

Moving multipart from the first to the second position under "formats" was all it needed.

That's the default as suggested in the docs. We need deserialize: false to prevent said error. Not sure why you don't get an error that a multipart/form-data response cannot be serialized.

@D3xime
Copy link
Author

D3xime commented Mar 11, 2025

If i set deserialize to false, it won't create the entity either. Thhier some missing information in the documentation which is needed to be patched.

D3xime added a commit to D3xime/docs that referenced this issue Apr 11, 2025
Hello everyone,

I am a new Developper who love using ApiPlatform but i encountered a bug when i tried to implement file handling in ApiPlatform. I reach out the documentation is misssing some data. 
The missing data was deserialize: false. 

This commit gives the following of this issues api-platform#2058.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants