Dear Marco,
Thanks for your suggestions on how to extend RESTXQ to provide better support for multipart requests.
I am also passing your proposal on to Adam Retter of eXist-db, as it might be interesting to define a generic solution for all implementations. Adam, do you think that this could be a valuable extension for RESTXQ 2.0? Did you already tackle RESTXQ multipart features in eXist-db? The current solution in BaseX is documented in [2]. One clear restriction (as Marco notes in his proposal) is we are currently ignoring all content types information.
Thanks and cheers, Christian
[1] https://github.com/exquery/exquery/issues [2] http://docs.basex.org/wiki/RESTXQ#Multipart_Types
On Thu, Apr 5, 2018 at 1:19 PM, Marco Lettere m.lettere@gmail.com wrote:
Dear Christian and BaseX community,
working with multipart requests and RestXQ lately, we have the feeling that there could be a way to intercept the structure of the request with annotations in order to perform a more fine grained access to the single parts.
At the moment the docs state the following example where, due to the consumes annotation reporting multipart/mixed, the data is returned as a sequence of items:
declare %rest:path("/multipart") %rest:POST("{$data}") %rest:consumes("multipart/mixed") (: optional :) function page:multipart($data as item()*) { "Number of items: " || count($data) };
Do you think that an approach where the content negotiation is refined to single parts could be implementable?
What we have in mind is something like the following snippet.
Besides the usual sequence based representation of the body, parts are extracted as variables (part named “partname1” with $part1 and type validated/coerced to the function signature and so on).
declare %rest:path("/multipart") %rest:POST("{$data}”) (: {$data} Could be removed at all or is out of standard? :)
%rest:consumes("multipart/mixed") (: optional :)
%input:part("{$part1}", "partname1") (: partname could be inferred from Content-Disposition and Content-Type for type coercion applied as usually with single-part requests :)
%input:part("{$part2}", "partname2")
function p:multipart($data as item()*, $part1 as xs:binary, $part2 as node()) { p:do-something-with($part1) };
Maybe even the serialization method could be declared... declare %rest:path("/multipart") %rest:POST("{$data}") %rest:consumes("multipart/mixed") (: optional :) %input:part("{$part1}", "partname", "csv;separator=','") (: Just as an example ...:) function p:multipart($data as item()*, $part1 as node()) { p:do-something-with($part1) }; Finally a check on the part count could be enforced in order to disallow requests that do not match declare %rest:path("/multipart") %rest:POST("{$data}") %rest:consumes("multipart/mixed") (: optional :) %input:part("{$part1}", "partname", "csv,separator=','") %input:part-count(2) function p:multipart($data as item()*, $part1 as node()) { p:do-something-with($part1) }; This makes for a nice, declarative way of extracting parts or ensuring that the structure of the requests respects a given REST service contract.
We understand that RestXQ is a shared formalization effort in the XML community but maybe there could be some opportunity to experiment and propose an addition to the specification?
As usual thanks a lot for your attention.
Best regards
Marco.