Changes

Jump to navigation Jump to search
576 bytes removed ,  18:39, 1 December 2023
m
Text replacement - "syntaxhighlight" to "pre"
</response>
};
</syntaxhighlightpre>
If the URI http://localhost:8080/hello/World is accessed, the result will be:
<syntaxhighlight pre lang="xml">
<response>
<title>Hello World!</title>
</response>
</syntaxhighlightpre>
The next function demonstrates a POST request:
</response>
};
</syntaxhighlightpre>
If you post something (e.g. using curl or the embedded form at http://localhost:8080/)...
<syntaxhighlight pre lang="shell">
curl -i -X POST --data "message='CONTENT'" http://localhost:8080/form
</syntaxhighlightpre>
...you will receive something similar to the following result:
<syntaxhighlight pre lang="shell">
HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8
Content-Length: 107
Server: Jetty(8.1.11.v20130520)
</syntaxhighlightpre>
<syntaxhighlight pre lang="xml">
<response type="form">
<message>'CONTENT'</message>
<user-agent>curl/7.31.0</user-agent>
</response>
</syntaxhighlightpre>
=Request=
declare %rest:path("/a/path/{$with}/some/{$variable}")
function page:test($with, $variable as xs:integer) { ... };
</syntaxhighlightpre>
<!-- TODO how matching works -->
declare %rest:path("app/{$path=.+}")
function page:others($path) { ... };
</syntaxhighlightpre>
<!-- TODO how matching works -->
%rest:consumes("text/xml")
function page:xml($body) { $body };
</syntaxhighlightpre>
====Producing Data====
%rest:produces("application/xml", "text/xml")
function page:xml() { <xml/> };
</syntaxhighlightpre>
Note that the annotations will ''not'' affect the type of the actual response: You will need to supply an additional <code>[[#Output|%output:media-type]]</code> annotation or (if a single function may produce results of different types) generate an apt [[#Custom_Response|Custom Response]].
...
declare function %rest:produces("*/*") ...
</syntaxhighlightpre>
…the first of these function will be chosen, as the quality factor for <code>text/html</code> documents is highest.
...
declare function %rest:produces("*/*;qs=0.5") ...
</syntaxhighlightpre>
===HTTP Methods===
declare %rest:GET %rest:POST %rest:path("/post")
function page:post() { "This was a GET or POST request" };
</syntaxhighlightpre>
The POST and PUT annotations may optionally take a string literal in order to map the HTTP request body to a [[#Parameters|function argument]]. Once again, the target variable must be embraced by curly brackets:
declare %rest:PUT("{$body}") %rest:path("/put")
function page:put($body) { "Request body: " || $body };
</syntaxhighlightpre>
====Custom Methods====
"Size of body: " || bin:length($body)
};
</syntaxhighlightpre>
If an OPTIONS request is received, and if no function is defined, an automatic response will be generated, which includes an <code>Allow</code> header with all supported methods.
"Number of rows: " || count($csv/csv/record)
};
</syntaxhighlightpre>
===Multipart Types===
"Number of items: " || count($data)
};
</syntaxhighlightpre>
==Parameters==
<result id="{ $id }" sum="{ sum($add) }"/>
};
</syntaxhighlightpre>
===HTML Form Fields===
<pre lang='xquery'>
%rest:form-param("city", "{$city}", "no-city-specified")
</syntaxhighlightpre>
The values are the result of HTML forms submitted with the (default) content type <code>application/x-www-form-urlencoded</code>:
<syntaxhighlight pre lang="xml">
<form action="/process" method="POST" enctype="application/x-www-form-urlencoded">
<input type="text" name="city"/>
<input type="submit"/>
</form>
</syntaxhighlightpre>
====File Uploads====
Files can be uploaded to the server by using the content type {{Code|multipart/form-data}} (the HTML5 {{Code|multiple}} attribute enables the upload of multiple files):
<syntaxhighlight pre lang="xml">
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="files" multiple="multiple"/>
<input type="submit"/>
</form>
</syntaxhighlightpre>
The file contents are placed in a [[Map Module|map]], with the filename serving as key. The following example shows how uploaded files can be stored in a temporary directory:
)
};
</syntaxhighlightpre>
===HTTP Headers===
%rest:header-param("User-Agent", "{$user-agent}")
%rest:header-param("Referer", "{$referer}", "none")
</syntaxhighlightpre>
===Cookies===
%rest:cookie-param("username", "{$user}")
%rest:cookie-param("authentication", "{$auth}", "no_auth")
</syntaxhighlightpre>
==Query Execution==
}</ul>
};
</syntaxhighlightpre>
By adding a string value to with the annotation, functions can be bundled together, and a running query can be canceled by calling another one that has the same annotation value. This is shown by another example, in which the first function can be interrupted by the second one. If you call both functions in separate browser tabs, you will note that the first tab will return <code>460</code>, and the second one will return <xml>stopped</xml>.
<xml>stopped</xml>
};
</syntaxhighlightpre>
The following things should be noted:
"The requested resource is not available."
};
</syntaxhighlightpre>
For the time being, it is not possible to create multipart responses.
The server can invite the client (e.g., the web browser) to make a second request to another URL by sending a 302 response:
<syntaxhighlight pre lang="xml">
<rest:response>
<http:response status="302">
</http:response>
</rest:response>
</syntaxhighlightpre>
The convenience function {{Function|Web|web:redirect}} can be called to create such a response.
'Stored documents: ' || count(db:get('app'))
};
</syntaxhighlightpre>
===Forwards===
A server-side redirect is called forwarding. It reduces traffic among client and server, and the forwarding will not change the URL seen from the client’s perspective:
<syntaxhighlight pre lang="xml">
<rest:forward>new-location</rest:forward>
</syntaxhighlightpre>
The response can also be created with the convenience function {{Function|Web|web:forward}}.
'Keep it simple, stupid'
};
</syntaxhighlightpre>
===Annotations===
}
};
</syntaxhighlightpre>
The next function, when called, generates XHTML headers, and {{Code|text/html}} will be set as content type:
</html>
};
</syntaxhighlightpre>
===Response Element===
'Not that simple anymore'
};
</syntaxhighlightpre>
=Error Handling=
web:error(418, "I'm a pretty teapot")
};
</syntaxhighlightpre>
In contrast to the standard <code>fn:error</code> function, a status code can be supplied, and the response body will only contain the specified error message and no stack trace.
'User "' || $user || '" is unknown'
};
</syntaxhighlightpre>
==Catch HTTP Errors==
Errors that occur outside RESTXQ can be caught by adding {{Code|error-page}} elements with an error code and a target location to the {{Code|web.xml}} configuration file (find more details in the [http://www.eclipse.org/jetty/documentation/current/custom-error-pages.html Jetty Documentation]):
<syntaxhighlight pre lang="xml">
<error-page>
<error-code>404</error-code>
<location>/error404</location>
</error-page>
</syntaxhighlightpre>
The target location may be another RESTXQ function. The {{Function|Request|request:attribute}} function can be used to request details on the caught error:
"Error message: " || request:attribute("javax.servlet.error.message")
};
</syntaxhighlightpre>
=User Authentication=
'Remote host name: ' || request:remote-hostname()
};
</syntaxhighlightpre>
=References=
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu