Closed fisehara closed 1 year ago
Hi Harald,
Happy New Year!
PATCH and DELETE requests to filtered collections of entities aren't yet supported by the generator because I don't know of any OData services that support this advanced feature.
It could be added for services that advertise this feature via the FilterSegmentSupported
property of UpdateRestrictions
and DeleteRestrictions
annotations.
I'll keep this issue open as a reminder.
If you know of services providing this feature, please tell me.
Thanks in advance Ralf
Hi Ralf,
thanks for the fast and precise answer! We are developing and using @balena/pinejs to auto-generate our OData API at balena.io. PineJs implements DELETE and Patch on filtered collections generically for every collection as it generates the end-points for each resource in the same way.
Thus, every instance of our open source published IoT fleet management tool https://github.com/balena-io/open-balena and our balenaCloud API ( https://api.balena-cloud.com/ ) are supporting DELETE and PATCH on filtered collections.
The overall idea to use odata-openapi translator is to have it build into PineJS so that documentation renders, SDK generators and other tools can either use the OData CSDL or openapi spec to generate their outputs. In particular the next goal are automatic updated openapi specs for documenetation, provided by PineJS directly.
I'll keep it on a watch and in the meantime I'll figure out how to add it to the openapi spec, I'm thinking of copy/pasta the block from the single entity documentation.
Thanks a lot again, best regards and have a good start into 2023
Harald
Hi Harald,
Thanks for the info, and cool that you are building APIs with this feature.
I'll put support for FilterSegmentSupported
into the backlog.
Hi Harald,
Could you please check whether https://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/a91398b3bbb24fb49054af7e275e6a673981a60c/examples/annotations.openapi3.json#/ matches your expectation?
The example shows /$filter(...)
segments on a root entity set and on a collection-valued navigation property, each with DELETE
and PATCH
.
Thanks in advance
Hi Ralf,
big thanks for the responsiveness and sending over an example to review!
The provided openapi spec looks exactly as the OData V4 core spec, so I think it's as expected. We internally discussed it and unfortunately, our filtered collection actions for Delete and Patch follow the old V3 implementation:
DELETE /AllSet?$filter = {filter_expression}
PATCH /AllSet?$filter = {filter_expression}
How we will approach this now is:
One completely just curious question during our internal discussion was, why the filteredCollection PATCH and DELETE are ended with a $each
. This feels redundant and from our understanding doesn't represent the otherwise full and unambiguous expressiveness of OData.
Thanks for your friendly and open support!
Harald
Hi Harald,
Assume we have a bound function foo
with two overloads, one bound to a single thingy, and one bound to a collection of thingies.
This leads to the following request patterns
Request | Meaning |
---|---|
GET /thingies/foo() |
call the collection-bound overload on all thingies |
GET /thingies/42/foo() |
call the single-bound overload on the thingy with key 42 |
GET /thingies/$filter(color eq 'red')/foo() |
call the collection-bound overload on all red thingies |
GET /thingies/$filter(color eq 'red')/$each/foo() |
call the single-bound overload on each single red thingy |
The request with the URL ending in /$each
is kind of an iterator over the filtered collection and allows us to decide which overload to call.
We have the same ambiguity with PATCH
because we allow update requests to collections now, sending a delta payload as the request body.
Request | Meaning |
---|---|
PATCH /thingies |
update the collection of all thingies with the provided delta request body |
PATCH /thingies/$each |
update each thingy with the provided single-update request body |
And we use the same pattern for DELETE
requests although we haven't yet specified a meaning for DELETE /thingies
.
The function call example also shows why we added the filter in the path. If the collection-bound overload returns a collection, there are two collections to filter: the input and the output of the function.
Having the filter query option always filter the output of an operation simplifies things.
Hope this explains how we arrived at the current URL syntax.
Ralf
Hello and Happy New Year!
I'd like to understand if there is a way to document on the resource path
/<resource>
the DELETE and PATCH actions. I understand that from the http://docs.oasis-open.org/odata/odata-openapi/v1.0/odata-openapi-v1.0.html there is no mapping specified for OData to Openapi for DELETE or PATCH a collection on a resource, but from OData itself it's an allowed action. From the OData core specification: http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity I read a MAY restrict to the single entity URLFrom my understanding this would allow requests to a resource as follows eg OData URL convention examples
DELETE http://host/service/Products?$filter=Name in ('Milk', 'Cheese')
PATCH http://host/service/Products?$filter=Name in ('Milk', 'Cheese') { payload }
Thanks in advance and best regards