Description
Hi,
I'm not sure if it's feasible, but it would be helpful to make fields required but only in certain scenario's.
For example:
- Field A is optional, but required if field B is also present (or multiple other fields are present). This translates to dependentRequired in JSON schema, so can also easily be included in the auto-generated OpenAPI docs. This name might also be a good candidate for the method on the fields to set it, e.g.
Str::make('a')->depentRequired(['b', 'c'])
to mark it as required only if fields b and c are also present. - Field A is required, except when field B is present (and vice-versa). This is harder to translate to JSON schema / OpenAPI sadly. Theoretically it should be done like this, but it will probably make the schema generation a lot harder:
{
"type": "object",
"properties": {
"a": {"type": "string"},
"b": {"type": "string"},
"...": { ... }
},
"oneOf": [
{"required": ["a"]},
{"required": ["b"]}
],
"required": [ ... any other, unrelated required fields ... ]
}
It's maybe feasible for 1 pair of fields like this, but it will become more complex if there are multiple. Then you'd need something like this I think:
{
"type": "object",
"properties": {
"a": {"type": "string"},
"b": {"type": "string"},
"c": {"type": "string"},
"d": {"type": "string"},
"...": { ... }
},
"allOf": [
{
"oneOf": [
{"required": ["a"]},
{"required": ["b"]}
]
},
{
"oneOf": [
{"required": ["c"]},
{"required": ["d"]}
]
}
],
"required": [ ... any other, unrelated required fields ... ]
}
(You could of course always generate it like this with an allOf
wrapper, even for 1 oneOf
pair.)
It's this latter functionality that I'm mostly interested in at this point, but sadly it's also the less obvious one to implement. Maybe I can also work around it for our use case by using a custom action/endpoint like you mentioned in #36
More concretely, our use case is that we want to allow a resource to be created from a template. So we'd have templates with an id each, and allow users/clients to create a new resource (of a specific type called "actions") with a template id. If they instead want to create the resource from scratch, they have to provide one or more required fields.
For example, either:
POST /api/actions
Content-type: "application/vnd.api+json"
{
"data": {
"relationships": {
"template": { // Required (on create) if no attributes.name given
"type": "actions-templates",
"id": "..."
}
}
}
}
OR
POST /api/actions
Content-type: "application/vnd.api+json"
{
"data": {
"attributes": {
"name": "..." // Required (on create) if no relationships.template given
}
}
}
Maybe you also come up with a different solution for this?
The dependentRequired()
on the other hand is not something that we need right now, but seems something that is easy enough to implement and that could be useful in the future.