Skip to content

[Bug]: Nelmio API Doc cannot scan mixed MapRequestPayload and MapUploadedFile #2672

@natoliverepairsoft

Description

@natoliverepairsoft

Version

5.9.2

Description

Description

Nelmio API Doc cannot automatically scan and generate documentation when both MapRequestPayload and MapUploadedFile attributes are used together in the same controller method.

Root Cause

The framework doesn't support automatic introspection of mixed content types (multipart/form-data with file upload + JSON payload). When these two attributes are combined, the documentation generator fails to properly detect and document the endpoint parameters.

Current Workaround

The only workaround is to explicitly add the UploadedFile parameter manually in the controller method signature, even though this is not ideal for automatic API documentation generation.

Example

#[Route("/upload", name: "upload", methods: ["POST"])]
public function upload(
    #[MapRequestPayload] UploadBunnyDto $dto,
    #[MapUploadedFile([
        new Assert\NotBlank(message: 'file is required'),
        new Assert\File(maxSize: '200M')
    ])] UploadedFile $file,
    UploadBunnyUseCase $useCase
): Response
{
    // ...
}

Expected Behavior

Nelmio API Doc should automatically detect and document endpoints that use both MapRequestPayload and MapUploadedFile attributes without requiring manual intervention.

Actual Behavior

The documentation is not generated automatically, and developers must manually specify the parameters as a workaround.

JSON OpenApi

JSON OpenApi
{
    "openapi": "3.0.0",
    "info": {
        "title": "API GED v2",
        "description": "Documentation de l'API GED version 2",
        "version": "2.0.0"
    },
    "paths": {
        "/v2/bunny/upload": {
            "post": {
                "summary": "T\u00e9l\u00e9verser un ficher vers Bunny",
                "operationId": "post_v2_bunny_upload",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "file": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            }
        },
        "/v2/bunny/delete": {
            "delete": {
                "summary": "Supprimer un fichier de Bunny",
                "operationId": "delete_v2_bunny_delete",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DeleteBunnyDto"
                            }
                        }
                    }
                },
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "UploadBunnyDto": {
                "required": [
                    "path",
                    "checksum"
                ],
                "properties": {
                    "path": {
                        "type": "string",
                        "minLength": 1,
                        "pattern": "/(?:[^/\\s]+(?:[ /])?)*, (?!.*TRASH).+"
                    },
                    "checksum": {
                        "type": "string",
                        "maxLength": 64,
                        "minLength": 64,
                        "pattern": "[a-fA-F0-9]{64}"
                    }
                },
                "type": "object"
            },
            "DeleteBunnyDto": {
                "required": [
                    "path",
                    "fileName"
                ],
                "properties": {
                    "path": {
                        "type": "string",
                        "minLength": 1,
                        "pattern": "/(?:[^/\\s]+(?:[ /])?)*/, (?!.*TRASH).+"
                    },
                    "fileName": {
                        "type": "string",
                        "minLength": 1
                    }
                },
                "type": "object"
            }
        },
        "securitySchemes": {
            "X-Security-Token": {
                "type": "apiKey",
                "name": "X-Security-Token",
                "in": "header"
            }
        }
    },
    "security": [
        {
            "X-Security-Token": []
        }
    ]
}

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions