Changes

Jump to navigation Jump to search
1,317 bytes added ,  11:32, 12 October 2018
* 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
* <code>%input</code> annotations, support Support for inputserver-specific content-type parameters* Since {{Versionside quality factors in the [[#Content Negotiation|8.4}}: <code>%rest:singleproduces</code> ]] annotation to cancel running RESTXQ functions
<br />
All RESTXQ [[XQuery 3.0#Annotations|annotations]] are assigned to the <code><nowiki>http://exquery.org/ns/restxq</nowiki></code> namespace, which is statically bound to the {{Code|rest}} prefix. A ''Resource Function'' is an XQuery function that has been marked up with RESTXQ annotations. When an HTTP request comes in, a resource function will be invoked that matches the constraints indicated by its annotations.
Whenever If a RESTXQ URL is requested, the [[Options#RESTXQPATH{{Option|RESTXQPATH]] }} module directory and its sub-directories will be traversed, and all [[XQuery Extensions#Suffixes|XQuery files]] will be parsed for functions with RESTXQ annotations in library modules (detected by the extension {{Code|.xqm}}) and main modules (detected by Sub-directories that include an {{Code|.xqignore}}). In main expressions, the main module file will never be evaluated. All modules will be cached and parsed again when their timestamp changesskipped.
A sub-directory To speed up processing, the functions of the existing XQuery modules are automatically cached in main memory:* Functions will not be invalidated and parsed for RESTXQ files again if it contains a file named the timestamp of their module changes.* File monitoring can be adjusted via the {{CodeOption|.ignorePARSERESTXQ}}option. Module caching can be turned on by setting [[Options#CACHERESTXQ|CACHERESTXQ]] to true. The option is helpful in In productive environments with a high load, but it may be recommendable to change the timeout, or completely disable monitoring.* If files should not be are replaced while the web server is running. If files are still replaced, the RESTXQ module cache must should be explicitly invalidated by calling the static root path {{Code|/.init}}or by calling the [[RESTXQ Module#rest:init|rest:init]] function.
==Examples==
%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){
&lt;response type='form'&gt;
&lt;message&gt;{ $message }&lt;/message&gt;
Two following annotations can be used to restrict functions to specific content types:
* '''HTTP Content Types''': a A function will only be invoked if the HTTP {{Code|Content-Type}} header of the request matches one of the given mime content types. Example:
<pre class="brush:xquery">%rest:consumes("application/xml", "text/xml")</pre>
* '''HTTP Accept''': a A function will only be invoked if the HTTP {{Code|Accept}} header of the request matches one of the defined mime content types. Example:
<pre class="brush:xquery">%rest:produces("application/atom+xml")</pre>
By default, both mime content types are {{Code|*/*}}. Quality factors supplied by a client will also be considered in the path selection process.If a client supplies the following accept header…
<pre>
</pre>
…and if two RESTXQ functions exist with the same {{Code|path}} annotation and , one with the {{Code|produces}} annotations annotation <code>*/*</code> , and another with <code>text/html</code>, respectively, the second function with the second annotation will be called, because the quality factor for <code>text/html</code> documents is higher than the one for arbitrary other mime typeshighest.
Server-side quality factors are supported as well: If multiple function candidates are left over after the above steps, the <code>qs</code> parameter will be considered. The function with the highest quality factor will be favored: <pre class="brush:xquery">%rest:produces("text/html;qs=1")%rest:produces("*/*;qs=0.8")</pre> Note that this the annotation will ''not'' affect the content-type of the HTTP actual response. Instead, you You will need to add a supply an additional <code>[[#Output|%output:media-type]]</code> annotation.
===HTTP Methods===
===Input options===
Conversion options for [[Options#JSONPARSER|JSON]], [[Options#CSVPARSER|CSV ]] and [[Options#HTMLPARSER|HTML ]] can also be specified via annotations using with the <code>input</code> prefix. The following function interprets the input as text with the CP1252 encoding and treats the first line of the textual input as CSV header:
<pre class="brush:xquery">
%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)
};
%rest:POST("{$data}")
%rest:consumes("multipart/mixed") (: optional :)
function page:multipart($data as item()*){
"Number of items: " || count($data)
};
%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) }"/>
};
%rest:path("/upload")
%rest:form-param("files", "{$files}")
function page:upload($files){
for $name in map:keys($files)
let $content := $files($name)
==Query Execution==
{{Mark|Introduced with Version 8.4}}: <code>%rest:single</code> annotation. In many RESTXQ search scenarios, input from browser forms is processed and search results are returned. User experience can generally be made more interactive if an updated search request is triggered with each key click. However, such search patterns this may lead to numerous many expensive parallel requests, from which only the result of the last request will be relevant for the client.
With the <code>%rest:single</code> annotation, it can be enforced that only one instance of a function will be executed for the same client. If the same function will be called for the second time, the already running query will be stopped, and the HTTP error code {{Code|410460}} (Gone) will be returned instead:
<pre class="brush:xquery">
(: If fast enough, returns the result. Otherwise, if called again, raises 410 460 :)
declare
%rest:path("/search")
By specifying a string along with the annotation, functions can be bundled together, and one request can be canceled by calling another one.
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>410460</code>, and the second one will return <xml>stopped</xml>.
<pre class="brush:xquery">
==Custom Response==
Custom responses can be built from within generated in XQuery by returning an <code>rest:response</code> element, 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 more optional child nodes that will be serialized as usual. A function that reacts yields a response on an unknown resource may look as follows:
<pre class="brush:xquery">
declare %output:method("text") %rest:path("") function page:error404() {
<rest:response>
<http:response status="404" message="I was not found.">
<http:header name="Content-Language" value="en"/>
<http:header name="Content-Type" value="text/htmlplain; charset=utf-8"/>
</http:response>
</rest:response>, "The requested resource is not available."
};
</pre>
%output:method("json")
%output:json("format=jsonml")
function page:cities(){
element cities {
db:open('factbook')//city/name
%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>
declare
%rest:path("/check/{$user}")
function page:check($user){
if($user = ('jack', 'lisa'))
then 'User exists'
%rest:error("err:user")
%rest:error-param("description", "{$user}")
function page:user-error($user){
'User "' || $user || '" is unknown'
};
declare
%rest:path("/teapot")
function page:teapot(){
fn:error(xs:QName('error'), "I'm a teapot", 418)
};
};
</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=
=References=
Currently, the following external resources on RESTXQ existDocumentation:
* [http://exquery.org/spec/restxq RESTXQ Specification], First Draft
* [http://www.adamretter.org.uk/presentations/restxq_mugl_20120308.pdf RESTXQ]. Slides, MarkLogic User Group London, 2012
* [http://files.basex.org/publications/xmlprague/2013/Develop-RESTXQ-WebApps-with-BaseX.pdf Web Application Development]. Slides from XMLPrague 2013
 
Examples:
 
* Sample code combining XQuery and JavaScript: [http://balisage.net/Proceedings/vol17/author-pkg/Galtman01/BalisageVol17-Galtman01.html Materials] and [http://balisage.net/Proceedings/vol17/html/Galtman01/BalisageVol17-Galtman01.html paper] from Amanda Galtman, Balisage 2016.
* [[DBA]]: The Database Administration interface, bundled with the full distributions of BaseX.
=Changelog=
 
;Version 9.0
 
* Added: Support for server-side quality factors in the [[#Content Negotiation|<code>%rest:produces</code>]] annotation
* Updated: Status code {{Code|410}} was replaced with {{Code|460}}
* Removed: {{Code|restxq}} prefix
;Version 8.4
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu