Closed jtreminio closed 1 year ago
Hmm, Hab am not convinced. You still need to define two schemas, but now with custom syntax instead of using the mechanism provided by OAS.
To clarify, I know there was a similar question here: https://github.com/zircote/swagger-php/issues/977
However, I want to move a step further. The accepted answer to this question is to only add @OA\Property()
annotations to properties shared across all components.
Assuming all components that extend #/components/schemas/Pet
in this repo's example will use everything except id
, we can add @OA\Property()
to every property except $id
.
What I am proposing is adding @OA\Property()
to all class properties. This would allow us to avoid having some properties defined within the class itself, and others in annotations not directly attached to the class.
If we have a component where more than one field is not needed over several endpoints, the whole thing becomes much messier.
Hmm, Hab am not convinced. You still need to define two schemas, but now with custom syntax instead of using the mechanism provided by OAS.
I am suggesting having custom syntax only in swagger-php
but that evaluates to normal OAS definitions.
As this is a PHP-centric tool we can benefit from this by having all property definitions embedded in the class itself, but allowing the concrete component definitions to pick and choose what properties they want to use.
I see this as a major benefit of swagger-php
over writing the OAS definitions manually. It would be similar to how we can reference PHP constants in annotations, for example like in enums:
/**
* @var string
* @OA\Property(type="string",
* enum=\PetStoreApi\Model\Pet::TYPE_ENUM
* )
*/
public $type;
In my view the id/not-id case is special and has a perfectly good solution. If schemas are sufficiently different there should be separate models in your app IMHO. In that case those should require separate schema definitions as well.
In the extreme, your suggestion would allow to define a single schema with all possible properties and then just mix and match from there. I would prefer the OAS schema definitions mirror the application models and also benefit from their class hierachy.
Having said that implementing this might also not be so easy, in particular if you need to unravel allOf/anyOf/oneOf relations too.
If you are really keen you could probably implement that by having your PropertiesList
extend Attachable
and write a custom processor. I'd be very, very reluctant to merge that into swagger-php, though.
Perhaps I would find this feature very convenient.
I actually want to use the model, but There are cases where the model data used for the requestBody data is part but not all.
Well, I do not have the time to look into this but for a start using Attachable
and a custom processor this should be possible without having to touch the core librarry code.
There is something interesting from json schema that may be can be used:
https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.4
9.4. "readOnly" and "writeOnly"
The value of these keywords MUST be a boolean. When multiple occurrences of these keywords are applicable to a single sub-instance, the resulting behavior SHOULD be as for a true value if any occurrence specifies a true value, and SHOULD be as for a false value otherwise.
If "readOnly" has a value of boolean true, it indicates that the value of the instance is managed exclusively by the owning authority, and attempts by an application to modify the value of this property are expected to be ignored or rejected by that owning authority.
An instance document that is marked as "readOnly" for the entire document MAY be ignored if sent to the owning authority, or MAY result in an error, at the authority's discretion.
If "writeOnly" has a value of boolean true, it indicates that the value is never present when the instance is retrieved from the owning authority. It can be present when sent to the owning authority to update or create the document (or the resource it represents), but it will not be included in any updated or newly created version of the instance.
An instance document that is marked as "writeOnly" for the entire document MAY be returned as a blank document of some sort, or MAY produce an error upon retrieval, or have the retrieval request ignored, at the authority's discretion.
For example, "readOnly" would be used to mark a database-generated serial number as read-only, while "writeOnly" would be used to mark a password input field.
These keywords can be used to assist in user interface instance generation. In particular, an application MAY choose to use a widget that hides input values as they are typed for write-only fields.
Omitting these keywords has the same behavior as values of false.
Thanks, that sounds quite interesting - I really need to find some time to read more of the JSON specs...
This could be a good feature in this project: https://github.com/DerManoMann/openapi-extras
Closing due to inactivity.
Taking a look at the Pet component in the examples: https://github.com/zircote/swagger-php/blob/c4b6729e58022bdf53c886c3f45ce6054e3d0dbd/Examples/petstore-3.0/models/Pet.php
This is a single schema definition, and all the properties in the attached
Pet
class are assigned to this component.However, this breaks down a bit in endpoints that do not actually need (or would permit) all those properties, like
POST /pet
(addPet
). This endpoint would not use theid
property, as it would not exist nor would the API user know of the value beforehand.I realize this is a limitation of the OAS itself, but I am curious if adding functionality to
swagger-php
to exclude (or maybe include?) properties in schemas would be desirable.For example, the current code is:
My idea would work like this:
The default
Pet
component remains untouched, but we create a newAddPetBody
component with a new@OA\PropertiesList()
. This accepts a list of properties to include from the class and would create a new, separate component in the definitions file.The end result would be the same as what we can currently do like this:
I am curious as to what you think of this. This could either work using
allOf
, or it could just generate separate and distinct components to avoid theallOf
mess.If you think it is a feature worth pursuing, I would be more than happy to begin working on a PR.