docs icon indicating copy to clipboard operation
docs copied to clipboard

file upload example problem with integer input value

Open pinksnotdead opened this issue 4 years ago • 2 comments

All i've done was from this example https://api-platform.com/docs/core/file-upload/#uploading-to-an-existing-resource-with-its-fields

I've got problem with posting integer value. Response: "The type of the "size" attribute must be "int", "string" given."

In my MongoDB Document is a simple integer field and new file field:

// ...
#[ApiResource(
    collectionOperations: [
        'get',
        'post' => [
            'input_formats' => [
                'multipart' => ['multipart/form-data'],
            ],
            "openapi_context" => [
                "requestBody" => [
                    "content" => [
                        "multipart/form-data" => [
                            "schema" => [
                                "type" => "object",
                                "properties" => [
                                    "size" => [
                                        "type" => "integer",
                                        "format" => "int32"
                                    ],
                                    "file" => [
                                        "type" => "string",
                                        "format" => "binary"
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]

        ],
    ],
)]
// ...
    /**
     * @ODM\Field(type="integer")
     */
    public $size;

// ...

    public function getSize(): ?int
    {
        return $this->size;
    }

    public function setSize(int $size): void
    {
        $this->size = $size;
    }

// ...
curl -X 'POST' \
  'http://localhost/api/endpoint_name' \
  -H 'accept: application/ld+json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'size=123' \
  -F '[email protected];type=image/jpeg'

I think there is a problem with sending data via curl -F. Symfony or api-platform auto-cast data to string. Sending using Content-Type: application/ld+json works correctly, because swagger use object -d flag.

My workaround was to modify MultipartDecoder class from example by casting possible integer coming from request:

// src/Encoder/MultipartDecoder.php

// ...
        return array_map(static function (string $element) {
            // Multipart form values will be encoded in JSON.
            $decoded = json_decode($element, true);

            // this avoid converting int to string
            if (is_numeric($element)) {
                $element = (int)$element;
            }

            return \is_array($decoded) ? $decoded : $element;
        }, $request->request->all()) + $request->files->all();
// ...

so... am i right and docs should be updated or an error is somewhere else?

pinksnotdead avatar Oct 13 '21 09:10 pinksnotdead

the same error with MySQL, so it's related with serializer and exacly with this example

pinksnotdead avatar Mar 03 '22 18:03 pinksnotdead

Had the same problem. I think a better fix would be something like this :

return \is_array($decoded) | is_int($decoded) ? $decoded : $element;

I suspect booleans can also be an issue but I did not test it.

YannLe avatar Dec 10 '22 09:12 YannLe