1. Capturing the Request Body with %rest:POST and %rest:PUT

The function annotations %rest:POST and %rest:PUT may take an optional string literal which maps the HTTP request body to a named function parameter. The same syntax as that used for URI templates is applied. For example %rest:POST("{$request-body}") would inject the request body into the function through the function parameter named $request-body.

Consider the following XQuery function

  %xdmp:update (: %xdmp:update explained in Update Transactions :)
function insert($uri as xs:string, $request-body as document-node(element())) {
  xdmp:document-insert($uri, $request-body)

The following curl command could invoke that function, inserting a new document into MarkLogic.

curl -X PUT -H "Content-Type: text/xml" \
     -d '<wheel>hello</wheel>' http://localhost:8080/insert/wheel.xml

2. Content Types

XQRS will convert the Content of the Request Body into an XQuery type based on the Content-Type header sent by the client. Please see the following table which shows the mapping of Content Types to XQuery Types.

Content-Type XQuery Parameter Type
text/xml document-node(element())
Ends with "+xml"
application/json document-node(object-node())    OR
Ends with "+json"
text/n3 sem:triple*
text/* Automatic Type Conversion
any type that inherits from xs:anyAtomicType
Including xs:string
multipart/* Sequence. Covered in Multipart Types section
anything not included above binary()    OR

Multipart Types "multipart/mixed" messages

XQRS supports multipart/mixed POST and PUT requests, enabling you to receive a sequence of items for a Parameter if you so wish. Consider the following example which can receive a sequence of XML documents.

function multipart($items as document-node(element(doc))+) {
  for $doc in $items
  return process($doc)

To invoke such a function, you could use a curl command like the following example

curl -F "metadata=@apples.xml; type=text/xml " \
     -F "content=@pears.xml; type=text/xml" \
     -F "content=@bananas.xml; type=text/xml" \
     -X POST http://localhost:8080/multipart

Each message in the body can be a different Content Type, so you could in theory post a few XML documents followed by some JSON documents followed by some RDF Triples in Turtle format all in the same request. In this scenario you'll need to set set the function parameter type to item()*