Skip to content
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

Parent attributes have missing named parameters #1036

Closed
akalineskou opened this issue Dec 21, 2021 · 4 comments
Closed

Parent attributes have missing named parameters #1036

akalineskou opened this issue Dec 21, 2021 · 4 comments

Comments

@akalineskou
Copy link
Contributor

akalineskou commented Dec 21, 2021

Annotations worked better than attributes in this regard, the extended properties were autocompleted and worked (they were public properties).

Since attributes are more strict, they dont inherit the extended class properties (it's in the constructor, so it doesnt work in the same way)

An example would be Property extends Schema

Right now Property has these named arguments

        string $property = Generator::UNDEFINED,
        string $description = Generator::UNDEFINED,
        string $title = Generator::UNDEFINED,
        string $type = Generator::UNDEFINED,
        string $format = Generator::UNDEFINED,
        string $ref = Generator::UNDEFINED,
        ?array $allOf = null,
        ?array $anyOf = null,
        ?array $oneOf = null,
        ?bool $nullable = null,
        ?Items $items = null,
        ?bool $deprecated = null,
        $example = Generator::UNDEFINED,
        $examples = Generator::UNDEFINED,
        ?array $x = null,
        ?array $attachables = null

And Schema has these

        string $schema = Generator::UNDEFINED,
        string $description = Generator::UNDEFINED,
        string $title = Generator::UNDEFINED,
        string $type = Generator::UNDEFINED,
        string $format = Generator::UNDEFINED,
        string $ref = Generator::UNDEFINED,
        ?Items $items = null,
        ?array $enum = null,
        ?bool $deprecated = null,
        ?ExternalDocumentation $externalDocs = null,
        ?array $x = null,
        ?array $attachables = null

As you can see enum is not present in the Property constructor, so you have to use the properties array #[OA\Property(properties: ['enum' => 'foo'])] which kind of defeats the purpose, since we dont have autocomplete anymore

But Schema has more properties which are not added in its constructor (and some in the Property constructor)

        'title' => 'string',
        'description' => 'string',
        'required' => '[string]',
        'format' => 'string',
        'collectionFormat' => ['csv', 'ssv', 'tsv', 'pipes', 'multi'],
        'maximum' => 'number',
        'exclusiveMaximum' => 'boolean',
        'minimum' => 'number',
        'exclusiveMinimum' => 'boolean',
        'maxLength' => 'integer',
        'minLength' => 'integer',
        'pattern' => 'string',
        'maxItems' => 'integer',
        'minItems' => 'integer',
        'uniqueItems' => 'boolean',
        'multipleOf' => 'integer',
        'allOf' => '[' . Schema::class . ']',
        'oneOf' => '[' . Schema::class . ']',
        'anyOf' => '[' . Schema::class . ']',

maximum, minimum, minItems to name a few.

The only way I see that can be working with autocomplete, is every class has all its named attributes, and the class that extends that one should have all the parents named arguments + the ones that it declares (that is a lot of copy and paste for each class that extends Schema for example, if it declares new properties, a simple extend would not require it)

 

Another thing to consider, would be to allow $ref to pass non strings (in the named parameters)
With annotations we were able to pass a NelmioApiDocBundle @Model to the ref

     *         @OA\Property(
     *             property="data",
     *             type="object",
     *             ref=@Model(type=EntityClassHere::class),
     *         ),

Right now for attributes we have to trick it in using the properties with the ref index

    #[OA\Property(
            property: 'data',
            type: 'object',
            properties: [
                'ref' => new Model(type: EntityClassHere::class),
            ],
    )]

Where it could be

    #[OA\Property(
            property: 'data',
            type: 'object',
            ref: new Model(type: EntityClassHere::class),
    )]

Which again loses the autocomplete which the annotations had

 

Another another thing, would be to allow to pass objects in the properties array without an index
Before

new OA\JsonContent(
    type: 'object',
    required: ['data'], // missing named attribute
    properties: ['value' => new OA\Property(
        property: 'data',
        type: 'array',
        items: new OA\Items(ref: new Model(type: EntityClassHere::class)),
    )],
),

After

new OA\JsonContent(
    type: 'object',
    required: ['data'],
    properties: [new OA\Property(
        property: 'data',
        type: 'array',
        items: new OA\Items(ref: new Model(type: Article::class, groups: ['article_list'])),
    )],
),

For this to work, a small is_string($property) check is needed in the AbstractAnnotation::__construct
The JsonContent actually expects the properties to be of time Property as per the nested Property::class => ['properties', 'property'], also the property named argument is missing

 

Thoughts?
I'm not bashing on the library, its a great one which could be even greater.
I'm happy to work on these changes, but want to see if you're ok with going in this direction before I do it.

@DerManoMann
Copy link
Collaborator

DerManoMann commented Dec 21, 2021

I'll need to go through this list in more details but it is quite possible that there are named parameters missing. I didn't take a very structured approach adding them... Happy to add missing ones.

Another thing to consider, would be to allow $ref to pass non strings

Yes, that should be ok.

Another another thing, would be to allow to pass objects in the properties array without an index

This is new to me. Certainly will look into that.
Not sure but it might work by having JsonContent and Property attributes at the same level - the code does support auto-merging when there is no ambiguity (I hope).

Documentation definitely needs some more love too :)

Help / PRs are definitely welcome.

@DerManoMann
Copy link
Collaborator

Have a look at #1037 - there are still some pure JSON schema related properties missing, but at least it will be easy to add those if needed in all the right places.

$ref is now string|object|null - does that work?

I've also updated some of the tests adding a couple of your example attributes :)

@akalineskou
Copy link
Contributor Author

Had some time to try it today, had an issue with the missing ref for the Response, but I see that was fixed (pending release), other than that it seems OK, kudos!

An issue I have, is I cant update because NelmioApiDocBundle is not compatible with the changes implemented to the annotations -> attributes.

@DerManoMann
Copy link
Collaborator

There is work being done to support V4 I think: nelmio/NelmioApiDocBundle#1916

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants