Changes

Jump to navigation Jump to search
24,674 bytes added ,  17:39, 1 December 2023
m
Text replacement - "syntaxhighlight" to "pre"
This page is part presents one of the [[Developer SectionWeb Application]]services. It describes how to use the RESTfulXQ RESTXQ API of BaseX.
At XML Prague Conference 2012RESTXQ, introduced by [http://www.adamretter.org.uk/ Adam Retter introduced RESTfulXQ], is an API that facilitates the use of XQuery as a server-side processing language for the Web. It has been inspired by the Java [https://en.wikipedia. org/wiki/Java_API_for_RESTful_Web_Services JAX-RS API]: It adds webapplication development power provides a pre-defined set of XQuery 3.0 annotations for mapping HTTP requests to XQueryfunctions, which in turn generate and return HTTP responses.
As BaseX provides various extensions to the original draft of {{Version|7.2}} RESTfulXQ is supported by BaseX.the specification:
* Multipart types are supported, including {{Code|multipart/form-data}}
* A {{Code|%rest:error}} annotation can be used to catch XQuery errors
* Servlet errors can be redirected to other RESTXQ pages
* A [[RESTXQ Module]] provides some helper functions
* Parameters are implicitly cast to the type of the function argument
* The [[#Paths|Path Annotation]] can contain regular expressions
* <code>%input</code> annotations, support for input-specific content-type parameters
* <code>%rest:single</code> annotation to cancel running RESTXQ functions
* Quality factors in the [[#Content Negotiation|Accept header]] will be evaluated
* Support for server-side quality factors in the [[#Content Negotiation|<code>%rest:produces</code>]] annotation
* Better support for the OPTIONS and HEAD methods
<br/>
=Introduction=
=Getting started=Preliminaries==
<!-- TODO add how to run without github package -->The RESTXQ service is accessible via {{Code|http://localhost:8080/}}.
Get a fresh copy of All RESTXQ [[httpsXQuery 3.0#Annotations|annotations]] are assigned to the <code><nowiki>http://githubexquery.comorg/ns/restxq</basexdbnowiki></basex-api basex-api] from our github repositoriescode> namespace, which is statically bound to the {{Code|rest}} prefix. It contains the base server architecureA ''Resource Function'' is an XQuery function that has been marked up with RESTXQ annotations. Refer to [[Startup#BaseX When an HTTP Server|BaseX HTTP Server]] for detailsrequest comes in, a resource function will be invoked that matches the constraints indicated by its annotations.
To start If a RESTXQ URL is requested, the server{{Option|RESTXQPATH}} module directory and its subdirectories will be traversed, there are two possibilitiesand all [[XQuery Extensions#Suffixes|XQuery files]] will be parsed for functions with RESTXQ annotations. Subdirectories that include an {{Code|.ignore}} file will be skipped.
* Inside To speed up processing, the basex-api directory run functions of the command <code>mvn jettyexisting XQuery modules are automatically cached in main memory:run</code>* Functions will be invalidated and parsed again if the timestamp of their module changes. (stop with <code>CTRL + C</code>)* Run File monitoring can be adjusted via the script <code>etc/basexhttp</code> (inside basex-api package){{Option|PARSERESTXQ}} option. There is In productive environments with a script high load, it may be recommendable to stop change the timeout, or completely disable monitoring.* If files are replaced while the web serveris running, located in the same folderRESTXQ module cache should be explicitly invalidated by calling the static root path {{Code|/.init}} or by calling the {{Function|RESTXQ|rest:init}} function.
By default the server will be accessible at http://localhost:8984/. The serverroot is <code>src/main/webapp</code>.==Examples==
A first RESTXQ function is shown below:
<pre lang=Server configuration'xquery'>module namespace page =With the first serverrun a configuration file will be put to the serverroot (by default <code>src/main'http:/webapp/.basex</code>). Other configurations may be done within <code>srcorg/mainexamples/webapp/WEBweb-INF/web.xml</code>.page';
E.G. in <code>.basex<declare %rest:path("hello/code> pathes for database {$who}") %rest:GET function page:hello(variable <code>DBPATH$who) { </coderesponse>), RESTfulXQ modules (variable <codetitle>HTTPPATHHello { $who }!</codetitle>) and [[Packaging | BaseX Package]] repository (variable <code/response>REPOPATH};</codepre>) are declared.
If the URI http://localhost:8080/hello/World is accessed, the result will be:
<pre lang="xml">
<response>
<title>Hello World!</title>
</response>
</pre>
=RESTfulXQ Modules=The next function demonstrates a POST request:
All RESTfulXQ modules can be accessed <pre lang='xquery'>declare %rest:path("/form") %rest:POST %rest:form-param("message","{$message}", "(no message)") %rest:header-param("User-Agent", "{$agent}")function page:hello-postman( $message as xs:string, $agent as xs:string*) as element(response) { <response type='form'> <message>{ $message }</message> <user-agent>{ $agent }</user-agent> </response>};</pre> If you post something (e.g. using curl or the embedded form at http://localhost:89848080/)... <pre lang="shell">curl -i -X POST --data "message='CONTENT'" http://localhost:8080/form</pre> ...you will receive something similar to the following result: <pre lang="shell">HTTP/1.1 200 OKContent-Type: application/xml; charset=UTF-8Content-Length: 107Server: Jetty(8.1.11.v20130520)</pre> <pre lang="xml"><response type="form"> <message>'CONTENT'</message> <user-agent>curl/7.31.0</user-agent></response></pre> =Request= This section shows how annotations are used to handle and process HTTP requests. ==Constraints== Constraints restrict the HTTP requests that a resource function may process. ===Paths=== A resource function must have a single ''Path Annotation'' with a single string as argument. The function will be called if a URL matches the path segments and templates of the argument. ''Path templates'' contain variables in curly brackets, and map the corresponding segments of the request path to the arguments of the resource function. The first slash in the path is optional. The following example contains a path annotation with three segments and two templates. One of the function arguments is further specified with a data type, which means that the value for <code>$variable</code> will be cast to an <code>xs:integer</code> before being bound: <pre lang='xquery'>declare %rest:path("/a/path/{$with}/some/{$variable}") function page:test($with, $variable as xs:integer) { ... };</pre><!-- TODO how matching works --> Variables can be enhanced by regular expressions: <pre lang='xquery'>(: Matches all paths with "app" as first, a number as second, and "order" as third segment :)declare %rest:path("app/{$code=[0-9]+}/order") function page:order($code) { ... }; (: Matches all other all paths starting with "app/" :)declare %rest:path("app/{$path=.+}") function page:others($path) { ... };</pre><!-- TODO how matching works --> If multiple path candidates are found for the request, the one with more segments will be preferred. ===Content Negotiation=== Functions can be restricted to specific Media Types. The default type is {{Code|*/*}}. Multiple types can either be specified by a single or by multiple annotations. ====Consuming Data==== A function will only be taken into consideration if the HTTP {{Code|Content-Type}} header of the request matches one of the given types: <pre lang='xquery'>declare %rest:POST("{$body}") %rest:path("/xml") %rest:consumes("application/xml") %rest:consumes("text/xml")function page:xml($body) { $body };</pre> ====Producing Data==== A function will only be chosen if the HTTP {{Code|Accept}} header of the request matches one of the given types: <pre lang='xquery'>declare %rest:path("/xml") %rest:produces("application/xml", "text/xml")function page:xml() { <xml/> };</pre> 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]]. ====Quality Factors==== A client can supply quality factors to influence the server-side function selection process. If a client sends the following HTTP header with quality factors… <pre>Accept: */*;q=0.5,text/html;q=1.0</pre> …and if two RESTXQ functions exist for the addressed path with two different annotations for producing data… <pre lang='xquery'>declare function %rest:produces("text/html") ......declare function %rest:produces("*/*") ...</pre> …the first of these function will be chosen, as the quality factor for <code>text/html</code> documents is highest. As we cannot ensure that the client may supply quality factors, the selection process can also be controlled server-side. The <code>qs</code> parameter can be attached server-side to the Media Type. If multiple functions are left in the selection process, the one with the highest quality factor will be favored: <pre lang='xquery'>declare function %rest:produces("application/json;qs=1") ......declare function %rest:produces("*/*;qs=0.5") ...</pre> ===HTTP Methods=== ====Default Methods==== The HTTP method annotations are equivalent to all [https://en.wikipedia.org/wiki/HTTP#Request_methods HTTP request methods] except TRACE and CONNECT. Zero or more methods may be used on a function; if none is specified, the function will be invoked for each method. The following function will be called if GET or POST is used as request method: <pre lang='xquery'>declare %rest:GET %rest:POST %rest:path("/restxqpost") function page:post() { "This was a GET or POST request" };</pre> 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: <pre lang='xquery'>declare %rest:PUT("{$body}") %rest:path("/put") function page:put($body) { "Request body: " || $body };</pre> ====Custom Methods==== Custom HTTP methods can be specified with the {{Code|%rest:method}} annotation. An optional body variable can be supplied as second argument: <pre lang='xquery'>declare %rest:path("binary-size") %rest:method("SIZE", "{$body}")function page:patch( $body as xs:base64Binary) { "Request method: " || request:method(), "Size of body: " || bin:length($body)};</pre> 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. If a HEAD request is received, and if no function is defined, the corresponding GET function will be processed, but the response body will be discarded. ==Content Types== The body of a POST or PUT request will be converted to an XQuery item. Conversion can becontrolled by specifying a content type. It follows instructions on how can be further influencedby specifying additional content-type parameters: {| class="wikitable"|- valign="top"! Content-Type! Parameters (<code>;name=value</code>)! Type of resulting XQuery item|- valign="top"| {{Code|text/xml}}, {{Code|application/xml}}|| {{Code|document-node()}}|- valign="top"| {{Code|text/*}}|| {{Code|xs:string}}|- valign="top"| {{Code|application/json}}| [[JSON Module#Options|JSON Options]]| {{Code|document-node()}} or {{Code|map(*)}}|- valign="top"| {{Code|text/html}}| [[HTML Module#Options|HTML Options]]| {{Code|document-node()}}|- valign="top"| {{Code|text/comma-separated-values}}| [[CSV Module#Options|CSV Options]]| {{Code|document-node()}} or {{Code|map(*)}}|- valign="top"| ''others''|| {{Code|xs:base64Binary}}|- valign="top"| {{Code|multipart/*}}|| sequence (see next paragraph)|} For example, if <code>application/json;lax=yes</code> is specified as content type, the input will be transformed to JSON, and the lax QName conversion rules will be applied, as described in the [[JSON Module]]. ===Input options=== Conversion options for {{Option|JSON}}, {{Option|CSV}} and {{Option|HTML}} can also be specified via annotations with the <code>input</code> prefix. The following function interprets the input as text with the CP1252 encoding and treats the first line as header: <pre lang='xquery'>declare %rest:path("/store.csv") %rest:POST("{$csv}") %input:csv("header=true,encoding=CP1252")function page:store-csv($csv as document-node()) { "Number of rows: " || count($csv/csv/record)};</pre> ===Multipart Types=== The single parts of a multipart message are represented as a sequence,and each part is converted to an XQuery item as described in the last paragraph. A function that is capable of handling multipart types is identical to other RESTXQ functions: <pre lang='xquery'>declare %rest:path("/multipart") %rest:POST("{$data}") %rest:consumes("multipart/mixed") (: optional :)function page:multipart($data as item()*) { "Number of items: " || count($data)};</pre> ==Parameters== The following annotations can be used to bind request values to function arguments. Values will implicitly be cast to the type of the argument. ===Query Parameters=== The value of the ''first parameter'', if found in the [[Request_Module#Conventions|query component]], will be assigned to the variable specified as ''second parameter''. If no value is specified in the HTTP request, all additional parameters will be bound to the variable (if no additional parameter is given, an empty sequence will be bound): <pre lang='xquery'>declare %rest:path("/params") %rest:query-param("id", "{$id}") %rest:query-param("add", "{$add}", 42, 43, 44)function page:params($id as xs:string?, $add as xs:integer+) { <result id="{ $id }" sum="{ sum($add) }"/>};</pre> ===HTML Form Fields=== Form parameters are specified the same way as [[#Query Parameters|query parameters]]: <pre lang='xquery'>%rest:form-param("city", "{$city}", "no-city-specified")</pre> The values are the result of HTML forms submitted with the (default) content type <code>application/x-www-form-urlencoded</code>: <pre lang="xml"><form action="/process" method="POST" enctype="application/x-www-form-urlencoded"> <input type="text" name="city"/> <input type="submit"/></form></pre> ====File Uploads==== Files can be uploaded to write such the server by using the content type {{Code|multipart/form-data}} (the HTML5 {{Code|multiple}} attribute enables the upload of multiple files): <pre lang="xml"><form action="/upload" method="POST" enctype="multipart/form-data"> <input type="file" name="files" multiple="multiple"/> <input type="submit"/></form></pre> The file contents are placed in a module[[Map Module|map]], with the filename serving as key.The following example shows how uploaded files can be stored in a temporary directory: <pre lang='xquery'>declare %rest:POST %rest:path("/upload") %rest:form-param("files", "{$files}")function page:upload($files) { for $name in map:keys($files) let $content := $files($name) let $path := file:temp-dir() || $name return ( file:write-binary($path, $content), <file name="{ $name }" size="{ file:size($path) }"/> )};</pre> ===HTTP Headers=== Header parameters are specified the same way as [[#Query Parameters|query parameters]]: <pre lang='xquery'>%rest:header-param("User-Agent", "{$user-agent}")%rest:header-param("Referer", "{$referer}", "none")</pre> ===Cookies=== Cookie parameters are specified the same way as [[#Query Parameters|query parameters]]: <pre lang='xquery'>%rest:cookie-param("username", "{$user}")%rest:cookie-param("authentication", "{$auth}", "no_auth")</pre>
To a regular model you add a namespace for REST annotations. With <code>%</code> followed by the namespace one applies REST annotations to existing functions. These annotations define when a modules function should be invoked and with what arguments.==Query Execution==
<pre class="brush:xquery">(:~ : A simple module In many web search scenarios, user input from browser forms is processed and search results are returned. Such operations can be made more interactive by sending a new search request to the server with REST-annotations :)module namespace hw = 'http://basexeach key click.org/modules/restxq-demo';declare namespace restHowever, this may lead to many parallel server-hw = 'http://exqueryside requests, from which only the result of the last request will be relevant for the client.org/ns/rest/annotation';
With the <code>%rest:single</code> annotation, it can be enforced that only one instance of a function will run at the same time and for the same client. If the same function will be called for the second time, a currently executed query will be stopped, and the HTTP error code {{Code|460}} will be returned instead:
 
<pre lang='xquery'>
(: If fast enough, returns the result. Otherwise, if called again, raises 460 :)
declare
%rest-hw:path("{$path}/search") %outputrest:mediaquery-typeparam("application/xmlterm", "{$term}") %rest:singlefunction hwpage:demosearch($path term as xs:string) as document{ <ul>{ for $result in db:get('large-nodedb')//*[text() = $term] return <li>{$result }</li> }</ul> &lt};</pre> 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&gt;>stopped</xml>. <pre lang='xquery'>declare Hello World! You accessed the %rest:path ("/compute") %rest:single("EXPENSIVE")function local:compute() {$path} (1 to 100000000000000)[.= 0] &lt}; declare %rest:path("/stop") %rest:single("EXPENSIVE")function local:stop() { <xml>stopped</xml&gt;>};</pre> The following things should be noted:
* If you accessed a query will be canceled, there will be no undesirable side effects. For example, it won’t be possible to abort a query if it is currently updating the server database or performing any other I/O operations. As a result, the termination of a running query can take some more time as expected.* The currently executed function is bound to the current session. This way, a client will not be able to cancel requests from other clients. As a result, functions can only be stopped if there was at localhost:8984/restxq/demo-module you would seeleast one previous successful response, in which initial session data was returned to the client.
<pre class="brush:xml">&lt;xml&gt; Hello World! You accessed the path demo-module.&lt;/xml&gt;</pre>Response=
By default, a successful request is answered with the HTTP status code {{Code|200}} (OK) and is followed by the given content. An erroneous request leads to an error code and an optional error message (e.g. {{Code|404}} for “resource not found”).
A {{Code|Server-Timing}} HTTP header is attached to each response. It indicates how much time was spent for parsing, compiling, evaluating and serializing the query. The last value will not necessarily reflect the full time for serializing the result, as the header is generated before the result is sent to the client. Server-side serialization can be enforced by annotating a function with the <code>[[#Query Execution|%rest:single]]</code> annotation.
=RESTful Annotations=Custom Response==
A List of all implemented annotations. As sample namespace for REST annotations Custom responses can be generated in XQuery by returning an <code>rest:response</code> is usedelement, an <code>http:response</code> child node that matches the syntax of the [http://expath.org/spec/http-client EXPath HTTP Client Module] specification, and optional child nodes that will be serialized as usual.A function that yields a response on an unknown resource may look as follows:
<pre lang='xquery'>
declare %output:method("text") %rest:path("") function page:error404() {
<rest:response>
<http:response status="404">
<http:header name="Content-Language" value="en"/>
<http:header name="Content-Type" value="text/plain; charset=utf-8"/>
</http:response>
</rest:response>,
"The requested resource is not available."
};
</pre>
==Path Annotation (constraint)==<code>%rest:path("/a/path/{$with}/some/{$variable}")</code>if url matches For the given patterntime being, variables (in curly brackets) will be assigned. The variables serve as input arguments for the function. The type will be converted, as defined by the functionit is not possible to create multipart responses.
==Forwards and Redirects== ===Redirects=== The server can invite the client (e.g., the web browser) to make a second request to another URL by sending a 302 response: <pre lang="xml"><rest:response> <http:response status="302"> <http:header name="Location" value="new-location"/> </http:response></rest:response></pre> The convenience function {{Function|Web|web:redirect}} can be called to create such a response. In the XQuery context, redirects are particularly helpful if [[XQuery Update|Updates]] are performed. An updating request may send a redirect to a second function that generates a success message, or evaluates an updated database: <pre lang='xquery'>declare %updating %rest:path('/app/init') function local:create() { db:create('app', <root/>, 'root.xml'), db:output(web:redirect('/app/ok'))}; declare %rest:path('/app/ok') function local:ok() { 'Stored documents: ' || count(db:get('app'))};</pre> ===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: <pre lang="xml"><rest:forward>new-location</rest:forward></pre> The response can also be created with the convenience function {{Function|Web|web:forward}}. With {{Announce|Version 11}}, a log entry with the status code {{Code|204}} will be output before the forwarding takes place. ==Output== The content-type of a response can be influenced by the user via [[Serialization|Serialization Parameters]]. The steps are described in the [[REST#Content Type|REST]] chapter. In RESTXQ, serialization parameters can be specified in the query prolog, via annotations, or within the REST response element: ===Query Prolog=== In main modules, serialization parameters may be specified in the query prolog. These parameters will then apply to all functions in a module. In the following example, the content type of the response is overwritten with the {{Code|media-type}} parameter: <pre lang='xquery'>declare option output:media-type 'text/plain'; declare %rest:path("version1") function page:version1() { 'Keep it simple, stupid'};</pre> ===Annotations=== Global serialization parameters can be overwritten via <code>%output</code> annotations. The following example serializes XML nodes as JSON, using the [[JSON Module|JsonML]] format: <pre lang='xquery'>declare %rest:path("cities") %output:method("json") %output:json("format=jsonml")function page:cities() { element cities { db:get('factbook')//city/name }};</pre> The next function, when called, generates XHTML headers, and {{Code|text/html}} will be set as content type: <pre lang='xquery'>declare %rest:path("done") %output:method("xhtml") %output:omit-xml-declaration("no") %output:doctype-public("-//W3C//DTD XHTML 1.0 Transitional//EN") %output:doctype-system("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")function page:html() { <html xmlns="http://www.w3.org/1999/xhtml"> <body>done</body> </html>};</pre> ===Response Element=== Serialization parameters can also be specified in a REST reponse element in a query. Serialization parameters will be overwritten: <pre lang='xquery'>declare %rest:path("version3") function page:version3() { <rest:response> <output:serialization-parameters> <output:media-type value='text/plain'/> </output:serialization-parameters> </rest:response>, 'Not that simple anymore'};</pre> =Error Handling= If an error is raised when RESTXQ code is parsed, compiled or evaluated, an HTTP response with the status code 500 is generated. By default, all server-side errors will be passed on to the client. This is particularly helpful during the development process. In a productive environment, however, it is advisable not to expose errors to the client. This can be realized via the {{Option|RESTXQERRORS}} option. If disabled, * XQuery modules that cannot be parsed will be ignored and* full error messages and stack traces will be suppressed and not included in the HTTP response. The full error information can still be looked up in the database logs. ==Raise Errors== With {{Function|Web|web:error}}, you can abort query evaluation, enforce a premature HTTP response and report errors back to the client: <pre lang='xquery'>declare %rest:path("/teapot")function page:teapot() { web:error(418, "I'm a pretty teapot")};</pre> 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. ==Catch XQuery Errors== XQuery runtime errors can be processed via ''error annotations''. Error annotations have one or more arguments, which represent the error codes to be caught. The codes equal the names of the [[XQuery 3.0#Try.2FCatch|try/catch]] construct: {| class="wikitable"|- valign="top"! Precedence! Syntax!Example|- valign="top"| 1| <code>prefix:name</code><br/><code>Q{uri}name</code>| <code>err:FORG0001</code><br/><code><nowiki>Q{http://www.w3.org/2005/xqt-errors}FORG0001</nowiki></code>|-valign="top"| 2| <code>prefix:*</code><br/><code>Q{uri}*</code>| <code>err:*</code><br/><code><nowiki>Q{http://www.w3.org/2005/xqt- TODO how matching works errors}*</nowiki></code>|-valign="top"| 3| <code>*:name</code>| <code>*:FORG0001</code>|-valign="top"| 4| <code>*</code>| <code>*</code>|} All error codes that are specified for a function must have the same precedence.The following rules apply when catching errors: * Codes with a higher precedence (smaller number) will be given preference.* A global RESTXQ error will be raised if two functions with conflicting codes are found. Similar to try/catch, the pre-defined variables ({{Code|code}}, {{Code|description}}, {{Code|value}}, {{Code|module}}, {{Code|line-number}}, {{Code|column-number}}, {{Code|additional}}) can be bound to variables via ''error parameter annotations'', which are specified the same way as [[#Query Parameters|query parameters]]. Errors may occur unexpectedly. However, they can also be triggered by a query, as demonstrated by the following example: <pre lang='xquery'>declare %rest:path("/check/{$user}")function page:check($user) { if($user = ('jack', 'lisa')) then 'User exists' else fn:error(xs:QName('err:user'), $user)}; declare %rest:error("err:user") %rest:error-param("description", "{$user}")function page:user-error($user) { 'User "' || $user || '" is allowed unknown'};</pre> ==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 have the {{Code|web.xml}} configuration file (find more details in the [http://www.eclipse.org/jetty/documentation/current/custom-error-pages.html Jetty Documentation]): <pre lang="xml"><error-page> <error-code>404</error-code> <location>/error404</location><strong/error-page>at least one</strongpre>  The target location may be another RESTXQ function. The {{Function|Request|request:attribute}} function can be used to request details on the caught error: <pre lang='xquery'>declare %rest:path annotation("/error404") function page:error404() { "URL: " || request:attribute("javax.servlet.error.request_uri") || ", " || "Error message: " || request:attribute("javax.servlet.error.message")};</pre> =User Authentication= If you want to provide restricted access to parts of a web applications, you will need to check permissions before returning a response to the client. The [[Permissions]] layer is a nice abstraction for defining permission checks. =Functions= The [[Request Module]] contains functions for accessing data related to the current HTTP request. Two modules exist for setting and retrieving server-side session data of the current user ([[Session Module]]) and all users known to the HTTP server ([[Sessions Module]]). The [[RESTXQ Module]] provides functions for requesting RESTXQ base URIs and generating a [https://www.w3.org/Submission/wadl/ WADL description] of all services. Please note that the namespaces of all of these modules must be explicitly specified via module imports in the query prolog. The following example returns the current host name: <pre lang='xquery'>import module namespace request = "http://exquery.org/ns/request"; declare %rest:path("/host-name") function page:host() { 'Remote host name: ' || request:remote-hostname()};</pre>
=References=
==HTTP Method Annotations (constraints)==Documentation:
* Simple Method Annotations[http://exquery.org/spec/restxq RESTXQ Specification], First Draft%rest* [http:GET//www.adamretter.org.uk/papers/restful-xquery_january-2012.pdf RESTful XQuery, Standardised XQuery 3.0 Annotations for REST]. Paper, XMLPrague, 2012%rest* [http:HEAD//www.adamretter.org.uk/presentations/restxq_mugl_20120308.pdf RESTXQ]. Slides, MarkLogic User Group London, 2012%rest* [https:DELETE//files.basex.org/publications/xmlprague/2013/Develop-RESTXQ-WebApps-with-BaseX.pdf Web Application Development]. Slides from XMLPrague 2013
<!-- TODO add some descripton -->Examples:
* Content Method Annotations%restSample code combining XQuery and JavaScript:POST%rest[https:POST("{$post//www.balisage.net/Proceedings/vol17/author-pkg/Galtman01/BalisageVol17-body}")%restGaltman01.html Materials] and [https:PUT//www.balisage.net/Proceedings/vol17/html/Galtman01/BalisageVol17-Galtman01.html paper] from Amanda Galtman, Balisage 2016.%rest* [[DBA]]:PUT("{$put-body}")The Database Administration interface, bundled with the full distributions of BaseX.
<!-- TODO add some descripton -->=Changelog=
==Media Type Annotations (constraint)==;Version 11.0* HTTP Content Type<br/><code>%rest:consumes()</code> one or more media-types as string. e.g.<code>%restUpdated:consumes("application/xml", "text/xml")* HTTP Accept<br/><code>%rest[[#Forwards|Forwards]]:produces()</A log entry with the status code> one media-type as string. e.g{{Code|204}} will be output. <code>%rest:produces("application/atom+xml")</code>
These default to <code>;Version 9.6*/*</code>, if no mediaUpdated: [[#Response|Response]]: {{Code|Server-type annotations are givenTiming}} HTTP header.
==Query String Annotations (Parameter)==;Version 9.5<code>%rest* Updated: [[#Raise Errors|Raise Errors]]:query-param()</Status code>Assigns <em>first parameter</em> {{Code|400}} changed to the variable in <em>second parameter</em> if found in the [http://en.wikipedia.org/wiki/Query_string Query String]. As optional <em>third parameter</em> a default value may be given. Is no default set and the parameter not contained in the Query-String{{Code|500}}, the REST annotation will be ignored.The variable will be type-casted to match the function declarationomit stack trace.
Examples;Version 9.3* <code>%restUpdated: [[#Custom Methods|Custom Methods]]:query-param("parameter", "{$value}", "default")</code>Better support for the OPTIONS and HEAD methods.* <code>%restUpdated: [[#Catch XQuery Errors|XQuery Errors]]:query-param("answer", "{$answer}", 42)</Suppress stack trace and error code>in the HTTP response.* <code>%Removed: {{Code|rest:query-paramredirect}} element ("search", "{$search-param{Function|Web|web:redirect}"} can be used instead)</code>
;Version 9.2
* Updated: Ignore XQuery modules that cannot be parsed
==HTML Form field Annotations (Parameter)==;Version 9.0* Added: Support for server-side quality factors in the [[#Content Negotiation|<code>%rest:form-param()produces</code>same usage as [[#Query String Annotations (Parameter)]], but extracted from POST or GET.annotation* Updated: Status code {{Code|410}} was replaced with {{Code|460}}* Removed: {{Code|restxq}} prefix
;Version 8.4* Added: <!-- TODO remark on file submission --code>%rest:single</code> annotation
==HTTP Header Annotations (Parameter)==;Version 8.1* Added: support for input-specific content-type parameters* Added: <code>%rest:header-param()input</code>same usage as [[#Query String Annotations (Parameter)]], but extracted from HTTP Header.annotations
Examples;Version 8.0* <code>%restAdded:header-param("User-Agent","{$user-agent}")</code>Support for regular expresssions in the [[#Paths|Path Annotation]]* <code>%restAdded:Evaluation of quality factors that are supplied in the [[#Content Negotiation|Accept header-param("Referer","{$referer}", "none")</code>]]
==Cookie Annotations (Parameter)==;Version 7.9<code>%rest* Updated:cookie-param()</code>same usage as [[#Query String Annotations (Parameter)Catch XQuery Errors|XQuery Errors]], but extracted from Cookie.extended error annotations* Added: {{Code|%rest:method}}
Examples;Version 7.7* <code>%restAdded: [[#Error Handling|Error Handling]], [[#File Uploads|File Uploads]], [[#Multipart Types|Multipart Types]]* Updated:cookie-paramRESTXQ function may now also be specified in main modules ("username","suffix: {{$userCode|*.xq}}")</code>.* <code>%Updated: the RESTXQ prefix has been changed from {{Code|restxq}} to {{Code|rest}}.* Updated: parameters are implicitly cast to the type of the function argument* Updated:cookie-param("authentication","the RESTXQ root url has been changed to {{$authCode|http://localhost:8080/}}", "no_auth")</code>
[[Category;Version 7.5* Added:Server]][[Categorynew XML elements {{Code|<rest:redirect/>}} and {{Code|<rest:Developer]]forward/>}}
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu