Difference between revisions of "REST"

From BaseX Documentation
Jump to navigation Jump to search
m (Typo in external declaration of $x and $y instead of $a and $b which are used throughout the example.)
 
(134 intermediate revisions by 6 users not shown)
Line 1: Line 1:
This page is part of the [[Developer Section]]. It describes how to use the REST API of BaseX.
+
This page presents one of the [[Web Application]] services. It describes how to use the REST API of BaseX.
  
BaseX offers a RESTful API for accessing distributed XML resources.
+
BaseX offers a RESTful API for accessing database resources via URLs.
REST ([http://en.wikipedia.org/wiki/Representational_State_Transfer REpresentational State Transfer])
+
REST ([https://en.wikipedia.org/wiki/Representational_State_Transfer REpresentational State Transfer])
 
facilitates a simple and fast access to databases through HTTP. The HTTP methods
 
facilitates a simple and fast access to databases through HTTP. The HTTP methods
 
GET, PUT, DELETE, and POST can be used to interact with the database.
 
GET, PUT, DELETE, and POST can be used to interact with the database.
  
The REST implementation has formerly been based on JAX-RX,
+
=Usage=
a generic layer to provide unified access to XML databases and resources. With
 
{{Version|7.0}}, it has been replaced with a native REST
 
implementation that allows a closer integration with XQuery, WebDAV, and other
 
features of BaseX. If you have worked with JAX-RX before, please take some time to
 
understand the differences between the old and new API.
 
  
=Starting HTTP Server=
+
By default, REST services are available at {{Code|http://localhost:8984/rest/}}. If no default credentials are specified in the URL or when starting the web application, they will be requested by the client ([[Web Application#User Management|see further]]).
  
First of all, launch the [[Startup#BaseX HTTP Server|BaseX HTTP Server]], which will itself start an instance of the [http://jetty.codehaus.org/jetty/ Jetty WebServer], which listens to the default port <code>8984</code> by default (check out the additional [[Startup Options#BaseX HTTP Server|command-line options]]).
+
A web browser can be used to perform simple GET-based REST requests and display the response. Some alternatives for using REST are listed in the [[#Usage Examples|Usage Examples]].
 
 
Most browsers can be used to get to know the REST API, and to directly display the results.
 
When requesting the first result, you will have to enter some database credentials
 
(default: <code>admin</code>/<code>admin</code>, [[#User Management|see below]]).
 
Some alternatives for using REST are listed in the [[#Usage Examples|Usage Examples]].
 
  
 
=URL Architecture=
 
=URL Architecture=
 
   
 
   
 
The root URL lists all available databases. The following examples assume that
 
The root URL lists all available databases. The following examples assume that
you have created a database instance from the [http://files.basex.org/xml/factbook.xml factbook.xml] document:
+
you have created a database instance from the [https://files.basex.org/xml/factbook.xml factbook.xml] document:
 
   
 
   
 
:<code>http://localhost:8984/rest</code>
 
:<code>http://localhost:8984/rest</code>
 
   
 
   
<pre class="brush:xml">  
+
<syntaxhighlight lang="xml">
 
<rest:databases resources="1" xmlns:rest="http://basex.org/rest">
 
<rest:databases resources="1" xmlns:rest="http://basex.org/rest">
 
   <rest:database resources="1" size="1813599">factbook</rest:database>
 
   <rest:database resources="1" size="1813599">factbook</rest:database>
 
</rest:databases>
 
</rest:databases>
</pre>  
+
</syntaxhighlight>
  
 
The resources of a database can be listed by specifying the database, and potential sub directories, in the URL.
 
The resources of a database can be listed by specifying the database, and potential sub directories, in the URL.
Line 40: Line 30:
 
:<code>http://localhost:8984/rest/factbook</code>
 
:<code>http://localhost:8984/rest/factbook</code>
  
<pre class="brush:xml">  
+
<syntaxhighlight lang="xml">
 
<rest:database name="factbook" resources="1" xmlns:rest="http://basex.org/rest">
 
<rest:database name="factbook" resources="1" xmlns:rest="http://basex.org/rest">
 
   <rest:resource type="xml" content-type="application/xml" size="77192">factbook.xml</rest:resource>
 
   <rest:resource type="xml" content-type="application/xml" size="77192">factbook.xml</rest:resource>
 
</rest:database>
 
</rest:database>
</pre>  
+
</syntaxhighlight>
 
   
 
   
 
The contents of a database can be retrieved by directly addressing the resource:
 
The contents of a database can be retrieved by directly addressing the resource:
Line 50: Line 40:
 
:<code>http://localhost:8984/rest/factbook/factbook.xml</code>
 
:<code>http://localhost:8984/rest/factbook/factbook.xml</code>
 
   
 
   
If a file with the mime type <code>application/xquery</code> is addressed, it will be evaluated, and the result will be returned:
 
 
:<code>http://localhost:8984/rest/factbook/index.xq</code>
 
 
 
If a resource is not found, an HTTP response will be generated with <code>404</code> as status code.
 
If a resource is not found, an HTTP response will be generated with <code>404</code> as status code.
 
   
 
   
==Operations==
 
 
GET and POST requests support the following '''operations''':
 
 
* '''Query''':<br/>Evaluates an XPath/XQuery expression. If a database or database path is specified in the URL, it is used as initial query context.
 
* '''Run''':<br/>Runs a query file located on the server. The query directory is defined by the <code>[[Options#HTTPPATH|HTTPPATH]]</code> option.
 
* '''Command''':<br/>Executes a [[Commands|database command]].
 
* '''Get''':<br/>This is the default operation for the GET operation (it is not possible to use this operation in a POST request). It returns a list of all databases, the resources of a database or the addressed resource. If a resource with content type <code>application/xquery</code> is addressed, it will be evaluated first, and the result will be returned.
 
 
 
==Parameters==
 
==Parameters==
 
   
 
   
Additionally, the following '''parameters''' can be applied to the operations:
+
The following '''parameters''' can be applied to the operations:
  
 
* '''Variables''':<br/>External variables can be ''bound'' before a query is evaluated ([[REST#Assigning Variables|see below]] for more).
 
* '''Variables''':<br/>External variables can be ''bound'' before a query is evaluated ([[REST#Assigning Variables|see below]] for more).
 
* '''Context''':<br/>The <code>context</code> parameter may be used to provide an initial XML context node.
 
* '''Context''':<br/>The <code>context</code> parameter may be used to provide an initial XML context node.
* '''Options''' ({{Mark|Introduced with Version 7.1.1}}):<br/>Specified [[Options]] are applied before the actual operation will be performed.
+
* '''Options''':<br/>Specified [[Options]] are applied before the actual operation will be performed.
 
* '''Serialization''':<br/>All [[Serialization]] parameters known to BaseX can be specified as query parameters. Parameters that are specified within a query will be interpreted by the REST server before the output is generated.
 
* '''Serialization''':<br/>All [[Serialization]] parameters known to BaseX can be specified as query parameters. Parameters that are specified within a query will be interpreted by the REST server before the output is generated.
* '''Wrap''':<br/>The <code>wrap</code> parameter encloses all query results with XML elements, using the <code>http://basex.org/rest</code> namespace.
 
  
 
While '''Options''' can be specified for all operations, the remaining parameters will only make sense for '''Query''' and '''Run'''.
 
While '''Options''' can be specified for all operations, the remaining parameters will only make sense for '''Query''' and '''Run'''.
  
=Request Methods=
+
=Request=
 
    
 
    
==GET Requests==
+
==GET Method==
 
   
 
   
 
If the GET method is used, all query parameters are directly specified within the URL.
 
If the GET method is used, all query parameters are directly specified within the URL.
 +
Additionally, the following '''operations''' can be specified:
 +
 +
* {{Code|query}}: Evaluate an XQuery expression. If a database or database path is specified in the URL, it is set as query context.
 +
* {{Code|command}}: Execute a single [[Commands|database command]].
 +
* {{Code|run}}: Evaluate an XQuery file or command script located on the server. The file path is resolved against the directory specified by {{Option|RESTPATH}} (before, it was resolved against {{Option|WEBPATH}}). Similar to {{Code|query}}, a database or database path is set as context.
  
 
; Examples
 
; Examples
  
* The first example lists all resources found in the '''tmp''' path of the ''factbook'' database:<br/><code>http://localhost:8984/rest/factbook/tmp</code>
+
* Lists all resources found in the '''tmp''' path of the ''factbook'' database:<br/><code>http://localhost:8984/rest/factbook/tmp</code>
  
* The first example prints the city names from the ''factbook'' database and encloses all results with a <code>&lt;rest:result/&gt;</code> elements:<br/><code>http://localhost:8984/rest/factbook?query=//city/name&wrap=yes</code>
+
* Returns the number of documents in a database:<br/><code>http://localhost:8984/rest/database?query=count(.)</code>
  
* In the next request, <code>US-ASCII</code> is chosen as output encoding, and the query <code>eval.xq</code> is evaluated:<br/><code>http://localhost:8984/rest?run=eval.xq&encoding=US-ASCII</code>
+
* Serializes a document as JSONML:<br/><code>http://localhost:8984/rest/factbook/factbook.xml?method=json&json=format=jsonml</code>
  
* The next URL turns on XML wrapping and lists all database users that are known to BaseX:<br/><code>http://localhost:8984/rest?command=show+users</code>
+
* <code>US-ASCII</code> is chosen as output encoding, and the query <code>eval.xq</code> is evaluated:<br/><code>http://localhost:8984/rest?run=eval.xq&encoding=US-ASCII</code>
  
* The last example includes an to disallow [[Options#XQUERY3|XQuery 3.0]] expressions:<br/><code>http://localhost:8984/rest?query=12345&xquery3=false</code>
+
* The next URL lists all database users that are known to BaseX:<br/><code>http://localhost:8984/rest?command=show+users</code>
  
==POST Requests==
+
==POST Method==
  
The body of a POST request is interpreted as XML fragment, which specifies the
+
The body of a POST request is interpreted as XML fragment, which specifies the operation to perform.
operation to perform. The body must conform to a given [[REST POST Schema]].
+
The name of the root element determines how the body will be evaluated:
 +
 
 +
* {{Code|commands}}: Run [[Commands#Command Scripts|Command Script]]
 +
* {{Code|query}}: Execute XQuery expression
 +
* {{Code|run}}: Run server-side file (query or command script)
 +
* {{Code|command}}: Execute single command
 +
 
 +
The root element may be bound to the optional REST namespace. Existing command scripts can be sent to the server without any modifications:
 +
 
 +
* Create an empty database and return database information:
 +
<syntaxhighlight lang="xml">
 +
<commands>
 +
  <create-db name='db'/>
 +
  <info-db/>
 +
</commands>
 +
</syntaxhighlight>
 +
 
 +
For the other commands, the following child elements are supported:
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Name
 +
! Description
 +
|-
 +
| {{Code|text}}
 +
| Required; contains the query string, command string, or file to be run
 +
|-
 +
| {{Code|parameter}}
 +
| Serialization parameter (with {{Code|@name}} and {{Code|@value}} attributes)
 +
|-
 +
| {{Code|option}}
 +
| Database option (with {{Code|@name}} and {{Code|@value}} attributes)
 +
|-
 +
| {{Code|variable}}
 +
| Variable bindings
 +
|-
 +
| {{Code|context}}
 +
| Initial context item
 +
|}
  
 
; Examples
 
; Examples
  
* The following query returns the first five city names of the <b>factbook</b> database:  
+
* Return the first five city names of the <b>factbook</b> database:
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
<query xmlns="http://basex.org/rest">
+
<rest:query xmlns:rest="http://basex.org/rest">
   <text><![CDATA[ (//city/name)[position() <= 5] ]]></text>
+
   <rest:text><![CDATA[ (//city/name)[position() <= 5] ]]></rest:text>
</query>
+
</rest:query>
</pre>
+
</syntaxhighlight>
  
* The second query returns the string lengths of all text nodes, which are found in the node that has been specified as initial context node:
+
* Return string lengths of all text nodes that are found in the node that has been specified as initial context node:
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
<rest:query xmlns:rest="http://basex.org/rest">
+
<query>
   <rest:text>for $i in .//text() return string-length($i)</rest:text>
+
   <text>for $i in .//text() return string-length($i)</text>
   <rest:context>
+
   <context>
 
     <xml>
 
     <xml>
 
       <text>Hello</text>
 
       <text>Hello</text>
 
       <text>World</text>
 
       <text>World</text>
 
     </xml>
 
     </xml>
   </rest:context>
+
   </context>
</rest:query>
+
</query>
</pre>
+
</syntaxhighlight>
  
* The following request returns the registered database users encoded in <code>ISO-8859-1</code>:
+
* Return the registered database users encoded in <code>ISO-8859-1</code>:
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
<command xmlns="http://basex.org/rest">
+
<command>
 
   <text>show users</text>
 
   <text>show users</text>
 
   <parameter name='encoding' value='ISO-8859-1'/>
 
   <parameter name='encoding' value='ISO-8859-1'/>
 
</command>
 
</command>
</pre>
+
</syntaxhighlight>
  
* This example creates a new database from the specified input and retains all whitespaces ({{Mark|works since Version 7.1.1}}):
+
* Create a new database from the specified input and preserve all whitespaces:
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
<command xmlns="http://basex.org/rest">
+
<command>
 
   <text>create db test http://files.basex.org/xml/xmark.xml</text>
 
   <text>create db test http://files.basex.org/xml/xmark.xml</text>
 
   <option name='chop' value='false'/>
 
   <option name='chop' value='false'/>
 
</command>
 
</command>
</pre>
+
</syntaxhighlight>
  
* The last request runs a query <code>query.xq</code> located in the directory specified by <code>[[Options#HTTPPATH|HTTPPATH]]</code>:
+
* Bind value to the {{Code|$person}} variable and run query <code>find-person.xq</code>, which must be located in the directory specified by {{Option|WEBPATH}}:
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
<run xmlns="http://basex.org/rest">
+
<run>
   <text>query.xq</text>
+
  <variable name='person' value='Johannes Müller'/>
 +
   <text>find-person.xq</text>
 
</run>
 
</run>
</pre>
+
</syntaxhighlight>
  
==PUT Requests==
+
==PUT Method==
 
   
 
   
 
The PUT method is used to create new databases, or to add or update existing database resources:
 
The PUT method is used to create new databases, or to add or update existing database resources:
Line 154: Line 174:
 
There are two ways to store non-XML data in BaseX:
 
There are two ways to store non-XML data in BaseX:
  
* '''Store as raw''':<br/> If application/octet-stream is chosen as content-type the input data is added as raw.
+
* '''Store as Raw Data''':<br/> If <code>application/octet-stream</code> is chosen as content-type, the input is added as [[Binary Data]].
* '''Convert to XML''':<br/> Raw data can be explicitly converted to XML by specifying the content-type.
+
* '''Convert to XML''':<br/> Incoming data is converted to XML if a parser is available for the specified content-type. The following content types are supported:
 +
** <code>application/json</code>: Stores JSON as XML.
 +
** <code>text/plain</code>: Stores plain text input as XML.
 +
** <code>text/comma-separated-values</code>: Stores CSV text input as XML.
 +
** <code>text/html</code>: Stores HTML input as XML.
  
Trying to add raw data without specifying the content type will lead to a <code>400</code> (BAD REQUEST) exception. The following content types are available:
+
Conversion can be influenced by specifying additional content-type parameters (see [[RESTXQ#Content Types|RESTXQ]] for more information).
  
* '''application/octet-stream''': Stores input data as raw file.
+
If raw data is added and if no content type, or a wrong content, is specified, a <code>400</code> (BAD REQUEST) error will be raised.
* '''application/json''': Stores JSON as XML.
 
* '''application/jsonml''': Stores JSONML input as XML.
 
* '''text/plain''': Stores plain text input as XML.
 
* '''text/csv''': Stores CSV text input as XML.
 
* '''text/html''': Strores html input as XML.
 
  
 
; Examples
 
; Examples
  
* A new database with the name <b>XMark</b> is created. If XML input is sent in the HTTP body, the resulting database resource will be called <b>XMark.xml</b>:<br/><code><nowiki>http://admin:admin@localhost:8984/rest/XMark</nowiki></code>
+
* A new database with the name <b>XMark</b> is created. If XML input is sent in the HTTP body, the resulting database resource will be called <b>XMark.xml</b>:<br/><code><nowiki>http://localhost:8984/rest/XMark</nowiki></code>
* A new database is created, and no whitespaces will be removed from the passed on XML input ({{Mark|works since Version 7.1.1}}):<br/><code><nowiki>http://admin:admin@localhost:8984/rest/XMark?chop=false</nowiki></code>
+
* A new database is created, and no whitespaces will be removed from the passed on XML input:<br/><code><nowiki>http://localhost:8984/rest/XMark?chop=false</nowiki></code>
* The contents of the HTTP body will be taken as input for the document <b>one.xml</b>, which will be stored in the <b>XMark</b> database:<br/><code><nowiki>http://admin:admin@localhost:8984/rest/XMark/one.xml</nowiki></code>
+
* The contents of the HTTP body will be taken as input for the document <b>one.xml</b>, which will be stored in the <b>XMark</b> database:<br/><code><nowiki>http://localhost:8984/rest/XMark/one.xml</nowiki></code>
  
 
An HTTP response with status code <code>201</code> (CREATED)
 
An HTTP response with status code <code>201</code> (CREATED)
Line 178: Line 197:
 
could not be completed).
 
could not be completed).
  
==DELETE Requests==
+
Have a look at the [[REST#Usage Examples|usage examples]] for more detailed examples using Java and shell tools like cURL.
+
 
 +
==DELETE Method==
 +
 
 
The DELETE method is used to delete databases or resources within a database.
 
The DELETE method is used to delete databases or resources within a database.
  
 
; Example
 
; Example
* The <b>factbook</b> database is deleted:<br/><code><nowiki>http://admin:admin@localhost:8984/rest/factbook</nowiki></code>
+
* The <b>factbook</b> database is deleted:<br/><code><nowiki>http://localhost:8984/rest/factbook</nowiki></code>
* All resources of the <b>XMark</b> database are deleted that reside in the <b>tmp</b> path:<br/><code><nowiki>http://admin:admin@localhost:8984/rest/XMark/tmp/</nowiki></code>
+
* All resources of the <b>XMark</b> database are deleted that reside in the <b>tmp</b> path:<br/><code><nowiki>http://localhost:8984/rest/XMark/tmp/</nowiki></code>
 
   
 
   
 
The HTTP status code <code>404</code> is returned if no database is specified.
 
The HTTP status code <code>404</code> is returned if no database is specified.
Line 191: Line 212:
 
=Assigning Variables=
 
=Assigning Variables=
  
==GET Requests==
+
==GET Method==
  
 
All query parameters that have not been processed before will be treated as variable assignments:
 
All query parameters that have not been processed before will be treated as variable assignments:
  
; Examples
+
; Example
  
* The following request binds a single variable to the query to be processed:<br/><code>http://localhost:8984/rest?query=$text&text=Hello+World</code>
+
* The following request assigns two variables to a server-side query file <code>mult.xq</code> placed in the HTTP directory:<br/><code>http://localhost:8984/rest?run=mult.xq&$a=21&$b=2</code>
 
+
<syntaxhighlight lang="xquery">
* The following request assigns two variables to a server-side query file <code>mult.xq</code> placed in the database <code>DB</code>:<br/><code>http://localhost:8984/rest/DB/mult.xq?a=21&b=2</code>
 
<pre class="brush:xquery">
 
 
(: XQuery file: mult.xq :)
 
(: XQuery file: mult.xq :)
 
declare variable $a as xs:integer external;
 
declare variable $a as xs:integer external;
 
declare variable $b as xs:integer external;
 
declare variable $b as xs:integer external;
$a * $b
+
<mult>{ $a * $b }</mult>
</pre>
+
</syntaxhighlight>
  
Variables can also be explicitly prefixed with a dollar sign (<code>$</code>); this way, those variables can be bound as well that would otherwise be interpreted in a different way (e.g.: <code>$method</code>).
+
The dollar sign can be omitted as long as the variable name does not equal a parameter keyword (e.g.: <code>method</code>).
  
==POST Requests==
+
==POST Method==
  
 
If <code>query</code> or <code>run</code> is used as operation, external variables can be specified via the <code><variable/></code> element:
 
If <code>query</code> or <code>run</code> is used as operation, external variables can be specified via the <code><variable/></code> element:
  
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
 
<query xmlns="http://basex.org/rest">
 
<query xmlns="http://basex.org/rest">
   <text>
+
   <text><![CDATA[
     declare variable $x as xs:integer external;
+
     declare variable $a as xs:integer external;
     declare variable $y as xs:integer external;
+
     declare variable $b as xs:integer external;
     $x * $y
+
     <mult>{ $a * $b }</mult>
   </text>
+
   ]]></text>
   <variable name="x" value="21"/>
+
   <variable name="a" value="21"/>
   <variable name="y" value="2"/>
+
   <variable name="b" value="2"/>
 
</query>
 
</query>
</pre>
+
</syntaxhighlight>
 
 
=User Management=
 
 
 
By default, the HTTP server is started with no predefined user. Users and passwords can be sent via [http://en.wikipedia.org/wiki/Basic_access_authentication HTTP basic authentication] with each HTTP request. As alternative, users and passwords can also be stored server-side in the "org.basex.user" and "org.basex.password" system properties before the HTTP server is started, or specified as [[Startup Options#BaseX HTTP Server|command-line arguments]].
 
  
With cURL, and most browsers, you can specify the user name and password with each HTTP request within the request string as plain text, using the format <code>USER:PASSWORD@URL</code>. An example:
+
=Response=
  
: <code>http://admin:admin@localhost:8984/rest/factbook</code>
+
==Content Type==
  
=Content Type=
+
As the content type of a REST response cannot necessarily be dynamically determined, it can be enforced by the user. The final content type of a REST response is chosen as follows:
  
As the content type of a REST response cannot be dynamically determined in all cases, it can be manually adjusted by the user. The final content type of a REST response is chosen in several steps:
+
# If the serialization parameter <code>[[Serialization|media-type]]</code> is supplied, it will be adopted as content-type.
 +
# Otherwise, if the serialization parameter <code>[[Serialization|method]]</code> is supplied, the content-type will be chosen according to the following mapping:
 +
#* <code>xml</code>, <code>adaptive</code>, <code>basex</code> → <code>application/xml</code>
 +
#* <code>xhtml</code> → <code>text/html</code>
 +
#* <code>html</code> → <code>text/html</code>
 +
#* <code>text</code> → <code>text/plain</code>
 +
#* <code>json</code> → <code>application/json</code>
 +
# If no media-type or serialization method is supplied, the content type of a response depends on the chosen REST operation:
 +
#* '''Query'''/'''Run''' → <code>application/xml</code>
 +
#* '''Command''' → <code>text/plain</code>
 +
#* '''Get''' → <code>application/xml</code>, or content type of the addressed resource
  
# By default, the content type of a response depends on the chosen operation:
+
Serialization parameters can either be supplied as [[#Parameters|query parameters]] or within the query.
#* '''Query'''/'''Run''' ? <code>application/xml</code>
 
#* '''Command''' ? <code>text/plain</code>
 
#* '''Get''' ? <code>application/xml</code>, or content type of the addressed resource
 
# The default content type is overwritten if a [[Serialization|serialization method]] is specified, either as [[#Query Parameters|query parameter]] or within the XQuery expression. The following methods are available:
 
#* <code>xml</code> ? <code>application/xml</code>
 
#* <code>xhtml</code> ? <code>text/html</code>
 
#* <code>html</code> ? <code>text/html</code>
 
#* <code>text</code> ? <code>text/plain</code>
 
#* <code>raw</code> ? <code>application/octet-stream</code>
 
#* <code>json</code> or <code>jsonml</code> ? <code>application/json</code>
 
# The content type is overwritten in any case if a specific [[Serialization|media-type]] is chosen, again as query parameter or within the query.
 
  
The following three example requests will all return <code>&lt;a/&gt;</code> as result and use <code>application/xml</code> as content-type:
+
The following three example requests all return <code>&lt;a/&gt;</code> with <code>application/xml</code> as content-type:
  
 
:<code>http://localhost:8984/rest?query=%3Ca/%3E</code><br/><code>http://localhost:8984/rest?query=%3Ca/%3E&method=xml</code><br/><code>http://localhost:8984/rest?query=%3Ca/%3E&media-type=application/xml</code>
 
:<code>http://localhost:8984/rest?query=%3Ca/%3E</code><br/><code>http://localhost:8984/rest?query=%3Ca/%3E&method=xml</code><br/><code>http://localhost:8984/rest?query=%3Ca/%3E&media-type=application/xml</code>
Line 257: Line 271:
 
   
 
   
 
==Java==
 
==Java==
 +
 +
===Authentication===
  
 
Most programming languages offer libraries to communicate with HTTP servers.
 
Most programming languages offer libraries to communicate with HTTP servers.
Line 268: Line 284:
 
<code>org.basex.util.Base64</code> can be used for that purpose:
 
<code>org.basex.util.Base64</code> can be used for that purpose:
  
<pre class="brush:java">
+
<syntaxhighlight lang="java">
// The java URL connection to the resource.  
+
import java.net.*;
URL url = new URL("http://admin:admin@localhost:8984/rest/factbook");  
+
import org.basex.util.*;
+
 
// Establish the connection to the URL.  
+
public final class RESTExample {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
+
  public static void main(String[] args) throws Exception {
// Set as DELETE request.  
+
    // The java URL connection to the resource.  
conn.setRequestMethod("DELETE");  
+
    URL url = new URL("http://localhost:8984/rest/factbook");  
 +
     
 +
    // Establish the connection to the URL.  
 +
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
 +
    // Set as DELETE request.  
 +
    conn.setRequestMethod("DELETE");  
 +
   
 +
    // User and password.
 +
    String user = "bob";
 +
    String pw ="alice";
 +
    // Encode user name and password pair with a base64 implementation.
 +
    String encoded = Base64.encode(user + ":" + pw);
 +
    // Basic access authentication header to connection request.
 +
    conn.setRequestProperty("Authorization", "Basic " + encoded);
 +
     
 +
    // Print the HTTP response code.
 +
    System.out.println("HTTP response: " + conn.getResponseCode());
 +
     
 +
    // Close connection.
 +
    conn.disconnect();
 +
  }
 +
}
 +
</syntaxhighlight>
 +
 
 +
===Content-Types===
 +
 
 +
The content-type of the input can easily be included, just add the following property to
 +
the connection (in this example we explicitly store the input file as raw):
 +
 
 +
<syntaxhighlight lang="java">
 +
// store input as raw
 +
conn.setRequestProperty("Content-Type", "application/octet-stream");
 +
</syntaxhighlight>
  
// User and password.
+
See the [[REST#PUT Requests|PUT Requests]] section for a description of the possible content-types.
String user = "bob";
 
String pw ="alice";
 
// Encode user name and password pair with a base64 implementation.
 
String encoded = Base64.encode(user + ":" + pw);
 
// Basic access authentication header to connection request.
 
conn.setRequestProperty("Authorization", "Basic " + encoded);
 
 
// Print the HTTP response code.
 
System.out.println("HTTP response: " + conn.getResponseCode());
 
 
// Close connection.
 
conn.disconnect();
 
</pre>
 
 
   
 
   
 
Find Java examples for all methods here:
 
Find Java examples for all methods here:
Line 297: Line 332:
 
==Command Line==  
 
==Command Line==  
  
Tools such as the Linux commands [http://www.gnu.org/s/wget/ Wget] or [http://curl.haxx.se/ cURL] exist to
+
Tools such as the Linux commands [https://www.gnu.org/s/wget/ Wget] or [http://curl.haxx.se/ cURL] exist to
 
perform HTTP requests (try copy &amp; paste):
 
perform HTTP requests (try copy &amp; paste):
  
 
;GET  
 
;GET  
:<code>curl -i "admin:admin@localhost:8984/rest/factbook?query=//city/name"</code>
+
* <code><nowiki>curl -i "http://localhost:8984/rest/factbook?query=//city/name"</nowiki></code>
 
;POST
 
;POST
:<code>curl -i -X POST -H "Content-Type: application/xml" -d <br/> "&lt;query xmlns='<nowiki>http://basex.org/rest'</nowiki>&gt;&lt;text&gt;//city/name&lt;/text&gt;&lt;/query&gt;" <br/> "admin:admin@localhost:8984/rest/factbook"</code>
+
* <code><nowiki>curl -i -X POST -H "Content-Type: application/xml" -d "&lt;query xmlns='http://basex.org/rest'&gt;&lt;text&gt;//city/name&lt;/text&gt;&lt;/query&gt;" "http://localhost:8984/rest/factbook"</nowiki></code>
:<code>curl -i -X POST -H "Content-Type: application/xml" -T query.xml "admin:admin@localhost:8984/rest/factbook"</code>  
+
* <code><nowiki>curl -i -X POST -H "Content-Type: application/xml" -T query.xml "http://localhost:8984/rest/factbook"</nowiki></code>  
 
;PUT
 
;PUT
:<code>curl -i -X PUT -T "etc/xml/factbook.xml" "admin:admin@localhost:8984/rest/factbook"</code>  
+
* <code><nowiki>curl -i -X PUT -T "etc/xml/factbook.xml" "http://localhost:8984/rest/factbook"</nowiki></code>
 +
* <code><nowiki>curl -i -X PUT -H "Content-Type: application/json" -T "plain.json" "http://localhost:8984/rest/plain"</nowiki></code>
 
;DELETE
 
;DELETE
:<code>curl -i -X DELETE "admin:admin@localhost:8984/rest/factbook"</code>
+
* <code><nowiki>curl -i -X DELETE "http://admin:admin@localhost:8984/rest/factbook"</nowiki></code>
 +
 
 +
=Changelog=
 +
 
 +
;Version 9.0
 +
* Added: Support for command scripts in the [[#POST Method|POST Method]].
 +
* Updated: The REST namespace in the [[#POST Method|POST Method]] has become optional.
 +
 
 +
;Version 8.1
 +
* Added: Support for input-specific content-type parameters
 +
* Updated: The [[#GET Method|run operation]] now resolves file paths against the {{Option|RESTPATH}} option.
 +
 
 +
;Version 8.0
 +
* Removed: {{Code|wrap}} parameter
 +
 
 +
;Version 7.9
 +
* Updated: Also evaluate command scripts via the <code>[[#GET Method|run]]</code> operation.
 +
 
 +
;Version 7.2
 +
* Removed: Direct evaluation of adresses resources with <code>application/xquery</code> as content type
  
=Recent Changes=
+
;Version 7.1.1
 +
* Added: {{Code|options}} parameter for specifying database options
  
===Version 7.1.1===
+
;Version 7.1
* Added: {{Mono|options}} parameter for specifying database options
+
* Added: PUT request: automatic conversion to XML if known content type is specified
  
[[Category:Server]]
+
;Version 7.0
[[Category:REST]]
+
* REST API introduced, replacing the old JAX-RX API
[[Category:Developer]]
 

Latest revision as of 17:30, 11 October 2021

This page presents one of the Web Application services. It describes how to use the REST API of BaseX.

BaseX offers a RESTful API for accessing database resources via URLs. REST (REpresentational State Transfer) facilitates a simple and fast access to databases through HTTP. The HTTP methods GET, PUT, DELETE, and POST can be used to interact with the database.

Usage[edit]

By default, REST services are available at http://localhost:8984/rest/. If no default credentials are specified in the URL or when starting the web application, they will be requested by the client (see further).

A web browser can be used to perform simple GET-based REST requests and display the response. Some alternatives for using REST are listed in the Usage Examples.

URL Architecture[edit]

The root URL lists all available databases. The following examples assume that you have created a database instance from the factbook.xml document:

http://localhost:8984/rest
<rest:databases resources="1" xmlns:rest="http://basex.org/rest">
  <rest:database resources="1" size="1813599">factbook</rest:database>
</rest:databases>

The resources of a database can be listed by specifying the database, and potential sub directories, in the URL. In the given example, a single XML document is stored in the factbook database:

http://localhost:8984/rest/factbook
<rest:database name="factbook" resources="1" xmlns:rest="http://basex.org/rest">
  <rest:resource type="xml" content-type="application/xml" size="77192">factbook.xml</rest:resource>
</rest:database>

The contents of a database can be retrieved by directly addressing the resource:

http://localhost:8984/rest/factbook/factbook.xml

If a resource is not found, an HTTP response will be generated with 404 as status code.

Parameters[edit]

The following parameters can be applied to the operations:

  • Variables:
    External variables can be bound before a query is evaluated (see below for more).
  • Context:
    The context parameter may be used to provide an initial XML context node.
  • Options:
    Specified Options are applied before the actual operation will be performed.
  • Serialization:
    All Serialization parameters known to BaseX can be specified as query parameters. Parameters that are specified within a query will be interpreted by the REST server before the output is generated.

While Options can be specified for all operations, the remaining parameters will only make sense for Query and Run.

Request[edit]

GET Method[edit]

If the GET method is used, all query parameters are directly specified within the URL. Additionally, the following operations can be specified:

  • query: Evaluate an XQuery expression. If a database or database path is specified in the URL, it is set as query context.
  • command: Execute a single database command.
  • run: Evaluate an XQuery file or command script located on the server. The file path is resolved against the directory specified by RESTPATH (before, it was resolved against WEBPATH). Similar to query, a database or database path is set as context.
Examples

POST Method[edit]

The body of a POST request is interpreted as XML fragment, which specifies the operation to perform. The name of the root element determines how the body will be evaluated:

  • commands: Run Command Script
  • query: Execute XQuery expression
  • run: Run server-side file (query or command script)
  • command: Execute single command

The root element may be bound to the optional REST namespace. Existing command scripts can be sent to the server without any modifications:

  • Create an empty database and return database information:
<commands>
  <create-db name='db'/>
  <info-db/>
</commands>

For the other commands, the following child elements are supported:

Name Description
text Required; contains the query string, command string, or file to be run
parameter Serialization parameter (with @name and @value attributes)
option Database option (with @name and @value attributes)
variable Variable bindings
context Initial context item
Examples
  • Return the first five city names of the factbook database:
<rest:query xmlns:rest="http://basex.org/rest">
  <rest:text><![CDATA[ (//city/name)[position() <= 5] ]]></rest:text>
</rest:query>
  • Return string lengths of all text nodes that are found in the node that has been specified as initial context node:
<query>
  <text>for $i in .//text() return string-length($i)</text>
  <context>
    <xml>
      <text>Hello</text>
      <text>World</text>
    </xml>
  </context>
</query>
  • Return the registered database users encoded in ISO-8859-1:
<command>
  <text>show users</text>
  <parameter name='encoding' value='ISO-8859-1'/>
</command>
  • Create a new database from the specified input and preserve all whitespaces:
<command>
  <text>create db test http://files.basex.org/xml/xmark.xml</text>
  <option name='chop' value='false'/>
</command>
  • Bind value to the $person variable and run query find-person.xq, which must be located in the directory specified by WEBPATH:
<run>
  <variable name='person' value='Johannes Müller'/>
  <text>find-person.xq</text>
</run>

PUT Method[edit]

The PUT method is used to create new databases, or to add or update existing database resources:

  • Create Database:
    A new database is created if the URL only specifies the name of a database. If the request body contains XML, a single document is created, adopting the name of the database.
  • Store Resource:
    A resource is added to the database if the URL contains a database path. If the addressed resource already exists, it is replaced by the new input.

There are two ways to store non-XML data in BaseX:

  • Store as Raw Data:
    If application/octet-stream is chosen as content-type, the input is added as Binary Data.
  • Convert to XML:
    Incoming data is converted to XML if a parser is available for the specified content-type. The following content types are supported:
    • application/json: Stores JSON as XML.
    • text/plain: Stores plain text input as XML.
    • text/comma-separated-values: Stores CSV text input as XML.
    • text/html: Stores HTML input as XML.

Conversion can be influenced by specifying additional content-type parameters (see RESTXQ for more information).

If raw data is added and if no content type, or a wrong content, is specified, a 400 (BAD REQUEST) error will be raised.

Examples
  • A new database with the name XMark is created. If XML input is sent in the HTTP body, the resulting database resource will be called XMark.xml:
    http://localhost:8984/rest/XMark
  • A new database is created, and no whitespaces will be removed from the passed on XML input:
    http://localhost:8984/rest/XMark?chop=false
  • The contents of the HTTP body will be taken as input for the document one.xml, which will be stored in the XMark database:
    http://localhost:8984/rest/XMark/one.xml

An HTTP response with status code 201 (CREATED) is sent back if the operation was successful. Otherwise, the server will reply with 404 (if a specified database was not found) or 400 (if the operation could not be completed).

Have a look at the usage examples for more detailed examples using Java and shell tools like cURL.

DELETE Method[edit]

The DELETE method is used to delete databases or resources within a database.

Example
  • The factbook database is deleted:
    http://localhost:8984/rest/factbook
  • All resources of the XMark database are deleted that reside in the tmp path:
    http://localhost:8984/rest/XMark/tmp/

The HTTP status code 404 is returned if no database is specified. 200 (OK) will be sent in all other cases.

Assigning Variables[edit]

GET Method[edit]

All query parameters that have not been processed before will be treated as variable assignments:

Example
(: XQuery file: mult.xq :)
declare variable $a as xs:integer external;
declare variable $b as xs:integer external;
<mult>{ $a * $b }</mult>

The dollar sign can be omitted as long as the variable name does not equal a parameter keyword (e.g.: method).

POST Method[edit]

If query or run is used as operation, external variables can be specified via the <variable/> element:

<query xmlns="http://basex.org/rest">
  <text><![CDATA[
    declare variable $a as xs:integer external;
    declare variable $b as xs:integer external;
    <mult>{ $a * $b }</mult>
  ]]></text>
  <variable name="a" value="21"/>
  <variable name="b" value="2"/>
</query>

Response[edit]

Content Type[edit]

As the content type of a REST response cannot necessarily be dynamically determined, it can be enforced by the user. The final content type of a REST response is chosen as follows:

  1. If the serialization parameter media-type is supplied, it will be adopted as content-type.
  2. Otherwise, if the serialization parameter method is supplied, the content-type will be chosen according to the following mapping:
    • xml, adaptive, basexapplication/xml
    • xhtmltext/html
    • htmltext/html
    • texttext/plain
    • jsonapplication/json
  3. If no media-type or serialization method is supplied, the content type of a response depends on the chosen REST operation:
    • Query/Runapplication/xml
    • Commandtext/plain
    • Getapplication/xml, or content type of the addressed resource

Serialization parameters can either be supplied as query parameters or within the query.

The following three example requests all return <a/> with application/xml as content-type:

http://localhost:8984/rest?query=%3Ca/%3E
http://localhost:8984/rest?query=%3Ca/%3E&method=xml
http://localhost:8984/rest?query=%3Ca/%3E&media-type=application/xml

Usage Examples[edit]

Java[edit]

Authentication[edit]

Most programming languages offer libraries to communicate with HTTP servers. The following example demonstrates how easy it is to perform a DELETE request with Java.

Basic access authentication can be activated in Java by adding an authorization header to the HttpURLConnection instance. The header contains the word Basic, which specifies the authentication method, followed by the Base64-encoded USER:PASSWORD pair. As Java does not include a default conversion library for Base64 data, the internal BaseX class org.basex.util.Base64 can be used for that purpose:

import java.net.*;
import org.basex.util.*;

public final class RESTExample {
  public static void main(String[] args) throws Exception {
    // The java URL connection to the resource. 
    URL url = new URL("http://localhost:8984/rest/factbook"); 
      
    // Establish the connection to the URL. 
    HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
    // Set as DELETE request. 
    conn.setRequestMethod("DELETE"); 
     
    // User and password.
    String user = "bob";
    String pw ="alice";
    // Encode user name and password pair with a base64 implementation.
    String encoded = Base64.encode(user + ":" + pw);
    // Basic access authentication header to connection request.
    conn.setRequestProperty("Authorization", "Basic " + encoded);
      
    // Print the HTTP response code. 
    System.out.println("HTTP response: " + conn.getResponseCode()); 
      
    // Close connection. 
    conn.disconnect(); 
  }
}

Content-Types[edit]

The content-type of the input can easily be included, just add the following property to the connection (in this example we explicitly store the input file as raw):

// store input as raw
conn.setRequestProperty("Content-Type", "application/octet-stream");

See the PUT Requests section for a description of the possible content-types.

Find Java examples for all methods here: GET, POST, PUT, DELETE.

Command Line[edit]

Tools such as the Linux commands Wget or cURL exist to perform HTTP requests (try copy & paste):

GET
  • curl -i "http://localhost:8984/rest/factbook?query=//city/name"
POST
  • curl -i -X POST -H "Content-Type: application/xml" -d "<query xmlns='http://basex.org/rest'><text>//city/name</text></query>" "http://localhost:8984/rest/factbook"
  • curl -i -X POST -H "Content-Type: application/xml" -T query.xml "http://localhost:8984/rest/factbook"
PUT
  • curl -i -X PUT -T "etc/xml/factbook.xml" "http://localhost:8984/rest/factbook"
  • curl -i -X PUT -H "Content-Type: application/json" -T "plain.json" "http://localhost:8984/rest/plain"
DELETE
  • curl -i -X DELETE "http://admin:admin@localhost:8984/rest/factbook"

Changelog[edit]

Version 9.0
  • Added: Support for command scripts in the POST Method.
  • Updated: The REST namespace in the POST Method has become optional.
Version 8.1
  • Added: Support for input-specific content-type parameters
  • Updated: The run operation now resolves file paths against the RESTPATH option.
Version 8.0
  • Removed: wrap parameter
Version 7.9
  • Updated: Also evaluate command scripts via the run operation.
Version 7.2
  • Removed: Direct evaluation of adresses resources with application/xquery as content type
Version 7.1.1
  • Added: options parameter for specifying database options
Version 7.1
  • Added: PUT request: automatic conversion to XML if known content type is specified
Version 7.0
  • REST API introduced, replacing the old JAX-RX API