nelmio / NelmioApiDocBundle

Generates documentation for your REST API from annotations
MIT License
2.23k stars 836 forks source link

Required field in OpenAPI response #2235

Open AurelienPillevesse opened 8 months ago

AurelienPillevesse commented 8 months ago

In my Symfony application, I have a controller which returns an output. Fields in this output which are not nullable are required in the OpenAPI documentation expect my nullable field in the same class (attribute3). Strange thing is that they are all in the constructor. In my opinion, the required for attribute3 is missing.

Don't know if it's a bug. Here is the code.

This is the Output class in my API.

final readonly class MyOutput
{
    public function __construct(
        public string $attribute1,
        public string $attribute2,
        public ?string $attribute3,
    ) {
    }

This is the code in my controller :

#[OA\Get(
    operationId: 'getMyThing',
    description: 'Returns one thing.',
    summary: 'Get one thing.',
    tags: ['Things'],
    responses: [
        new OA\Response(
            response: Response::HTTP_OK,
            description: 'Thing Item',
            content: new OA\JsonContent(ref: new Model(type: MyOutput::class))
        ),
    ]
)]

In my OpenAPI documentation:

"MyOutput": {
  "required": [
      "attribute1",
      "attribute2",
  ],
  "properties": {
      "attribute1": {
          "type": "string"
      },
      "attribute2": {
          "type": "string"
      },
      "attribute3": {
          "type": "string",
          "nullable": true
      },
  },
  "type": "object"
}
DjordyKoert commented 8 months ago

I think we need a way to differentiate between requests & responses.

adpeyre commented 6 months ago

@DjordyKoert I don't understand.

In the response case, if my property is nullable, I would like to see it required in my schema. The expected value is string or null.

After, I use the generated json schema in a package for generating api. My logo property is nullable and should not be undefinable :

export interface Site {
  logo?: string | null;
}

Should be :

export interface Site {
  logo: string | null;
}