Dear all,
First of all, I hope everything is fine and all of you are staying healthy!
When I read again the docs about Content Negotiation in RestXQ I noticed the sentence:
Functions can be restricted to specific Media Types. The default type is|*/*|.
So I wrote the two RestXQ signaures [1] with the expectation of *fallback()* behaving as a catch-all for mime-types not declared in *specific(**)*.
At that point, when calling the service with something stating "Content-Type: application/xml" BaseX yields the following error:
Stopped at /....: [basex:restxq] Several functions found for path "test": - ccp_ui:test [text/plain] - ccp_ui:test2 [text/plain]
If I specify an explicit %rest:consumes("*/*") in the annotations of fallback(), specific() correctly intercepts the request.
Unfortunately at that point calling with "Content-Type: text/plain" which should slip through the functions and be catched by fallback() yields instead:
No function found that matches the request.
So there is no combination, to my knowledge, to implement my use-case correctly ... besides handling mime-types explicitly in code (which is rather uncomfortable).
I'm using BaseX 9.4.5 at the moment.
Do you have any hint on this?
Thank you very much.
Marco.
[1]
declare %rest:path("test") %rest:POST("{$body}") %rest:consumes("text/csv", "application/xml", "application/json") %output:method("text") function s:specific($body as document-node()) { "Treated as document" };
declare %rest:path("test") %rest:POST("{$body}") %output:method("text") function s:fallback($body as item()) { "Treated as binary" };
Hi Marco,
If I specify an explicit %rest:consumes("*/*") in the annotations of fallback(), specific() correctly intercepts the request.
That was misleading: It shouldn’t make a difference if the generic annotation is specified or omitted. This has been fixed.
Unfortunately at that point calling with "Content-Type: text/plain" which should slip through the functions and be catched by fallback() yields instead:
Your observations (and similar ones that we came across in one of our projects) motivated me to have another intense look at the content negotiation code (which got fairly complex, due to all the quality factor checks). I believe I found a solution that matches the requirements without compromising backward compatibility. Details (for those who are interested) can be found in [1].
A new snapshot is available [2], I would be happy if you could test it for us.
Ciao, Christian
[1] https://github.com/BaseXdb/basex/commit/bde52a5ef88e327a7e3f6ad35036cec92767... [2] https://files.basex.org/releases/latest/
declare %rest:path("test") %rest:POST("{$body}") %rest:consumes("text/csv", "application/xml", "application/json") %output:method("text") function s:specific($body as document-node()) { "Treated as document" };
declare %rest:path("test") %rest:POST("{$body}") %output:method("text") function s:fallback($body as item()) { "Treated as binary" };
Hi Christian,
"negotiation code (which got fairly complex, due to all the quality factor checks)."
I had no doubt about this ... and it was confirmed after looking at the code referenceyou attached. I think that server software such as Jetty, Tomcat a.s.o. should provide tools and APIs for managing Content Negotiation OOTB. Nevertheless I installed the new snapshot and now my use case is correctly supported! Thanks a lot for the prompt support as usual! Bis bald, Marco.
On 18/02/21 21:22, Christian Grün wrote:
Hi Marco,
If I specify an explicit %rest:consumes("*/*") in the annotations of fallback(), specific() correctly intercepts the request.
That was misleading: It shouldn’t make a difference if the generic annotation is specified or omitted. This has been fixed.
Unfortunately at that point calling with "Content-Type: text/plain" which should slip through the functions and be catched by fallback() yields instead:
Your observations (and similar ones that we came across in one of our projects) motivated me to have another intense look at the content negotiation code (which got fairly complex, due to all the quality factor checks). I believe I found a solution that matches the requirements without compromising backward compatibility. Details (for those who are interested) can be found in [1].
A new snapshot is available [2], I would be happy if you could test it for us.
Ciao, Christian
[1] https://github.com/BaseXdb/basex/commit/bde52a5ef88e327a7e3f6ad35036cec92767... [2] https://files.basex.org/releases/latest/
declare %rest:path("test") %rest:POST("{$body}") %rest:consumes("text/csv", "application/xml", "application/json") %output:method("text") function s:specific($body as document-node()) { "Treated as document" };
declare %rest:path("test") %rest:POST("{$body}") %output:method("text") function s:fallback($body as item()) { "Treated as binary" };
basex-talk@mailman.uni-konstanz.de