It is unclear yet whether this document will be submitted to the W3C, either to the XQuery WG or as Community Group. For the time being it lives under the EXQuery project.
Whilst XQuery [[!XQUERY]] was originally envisaged and designed as a query language for XML, it has been adopted by many as a language for application development. This specification describes a set of XQuery 3.0 Annotations [[!XQUERY-30]] and a small set of functions to enable XQuery to provide RESTful services, thus enabling Web Application development in XQuery.

Introduction

XQuery processors are now frequently provided as part of complete data application processing platforms, which typically incorporate amongst others, XML Data storage and Web serving capabilities.

XQuery has long been recognised as a good language for producing XHTML and HTML from complex data queries, however XQuery is almost completely ignorant of the Web. XQuery provides no native capabilties for either making Web requests or operating as a server-side scripting language and processing Web requests.

As of XQuery 3.0 there is still no standard way to create Web Applications in XQuery. Many vendors provide extensions to their XQuery implementations which allow users to serve web requests using XQuery processing. Whilst vendors have borrowed ideas from each other, there is no standard for Web capabilities in XQuery, as such developers have to use proprietary extensions, which limits the portability of their XQuery code, ultimately fragmenting the XQuery community, limiting re-use and reducing peer-learning.

RESTXQ attempts to resolve these problem of interoperablility. RESTXQ defines a standard set of vendor agnostic XQuery Annotations and functions for XQuery 3.0. When implemented by vendors, these annotations provide a standard W3C XQuery 3.0 compliant approach to delivering RESTful Web Services from XQuery, whilst the functions provide user convenience for interacting with implementations of RESTXQ.

Goals

The guiding goals for the RESTXQ specification are:

Interoperability
Only features that are already present in XQuery 3.0 MUST be applied to create RESTXQ. Any XQuery code that makes use of RESTXQ instead of vendor extensions, is valid XQuery 3.0 code, and therefore portable. Note, RESTXQ support is required in the XQuery processor to execute resource functions in a Web context.
Simplicity for XQuery developers
XQuery developers MUST NOT have to maintain external or complex code for wiring RESTful services to XQuery functions. Developers should just write standard XQuery.
Vendor Agnostic
RESTXQ MUST NOT assume anything about an implementation above what is defined in XQuery 3.0. RESTXQ MUST be equally implementable by any vendor.
Technical improvement
RESTXQ MUST improve on the current approaches, a comprehensive review was undertaken here.

Audience

This specification is intended for both vendors and developers looking to implement RESTXQ in their products, XQuery developers looking to use the RESTXQ features defined in this specification, and individuals wishing to establish the correctness of implementations with respect to the requirements of this specification.

This document assumes that readers already have at least a basic understanding of XQuery 3.0, and an understanding of Web technologies and server side scripting.

Namespaces and Prefixes

The annotations and functions discussed in this document are contained in one of two namespaces (see [[!XML-NAMES]]) and referenced using an xs:QName. The namespace prefix used in this document for annotations and functions that are solely related to RESTXQ is rest. Serialization annotations and functions are named with the prefix output.

This document uses the prefix rerr to represent the namespace URI http://exquery.org/ns/restxq/error, which is the namespace for all RESTXQ error codes and messages. This namespace prefix is not predeclared and its use in this document is not normative.

The namespace prefix used for the functions, datatypes and errors can vary, as long as the prefix is bound to the correct URI.

The URIs of the namespaces and the default prefixes associated with them are:

The namespace URI associated with the rerr prefix is not expected to change from one version of this document to another. The contents of this namespace may be extended to allow additional errors to be returned.

Annotations

Background

XQuery 3.0 Annotations

Whilst XQuery 3.0 introduces many new features, an understanding of Annotations in XQuery 3.0 is fundamental to this specification. Annotations declare properties of functions or variables, zero or more annotations may be added to a function or variable declaration. Annotations start with the '%' character and consist of an expanded qualified name and an optional value, the value being a sequence of literals.

        xquery version "3.0";
        
        declare namespace java = "http://java";
        
        declare
        %java:method("java.lang.Math.sin")
        function local:calculate-sin($a as xs:double) as xs:double external
        
        <sin>{
          local:calculate-sin(1.4)
        }</sin>
          

Apart from the %private and %public annotations, no other annotations are defined by the XQuery 3.0 specification. However, the specification states, "Implementations MAY define further annotations, whose behaviour is implementation-defined". It is this property which this specification exploits to define a standard set of RESTful Annotations for XQuery 3.0.

Approach

RESTXQ is heavily influenced by that of JAX-RS [[!JAX-RS]]. However, we simplify and deviate from JAX-RS predominantly due to the language structure differences between Java and XQuery. Where JAX-RS describes Resource Classes and Resources Methods for Java, in XQuery we simply use the term Resource Function; for mapping HTTP calls to XQuery invocation, our unit of granularity is the XQuery function.

Through the use of annotations on functions in XQuery, we declaratively mark-up the HTTP capabilities of a function. To minimise refactoring by developers when adding annotations to existing code, two measures must be respected by implementations:

  1. Implementations of RESTXQ MUST support annotated functions which have additional function parameters which are not annotation mapped, providing the cardinality type of those un-mapped parameters accepts an empty sequence.
  2. Implementors MUST not enforce the order of function parameters. Whether mapped by annotations or not is unimportant, as annotations explicitly name the parameters to which they are mapped.

Resource Functions

A Resource Function is an XQuery function which has been marked up with RESTXQ annotations. These annotations indicate to a processor that when presented with a RESTful web service request, that matches the constraints indicated by the annotations, that the function SHOULD be invoked and the result SHOULD be returned as the result of the service request.

There are two types of Resource Function Annotations described in RESTXQ:

Templates

Some of the RESTXQ Annotations make use of Templates, which allow for the substitution of parameters from the request into the query. The syntax of these templates is very simple and is designed to be familiar to existing XQuery developers, it is expressed in .

The Template appears inside a string literal within the annotation, but the meaning is that the value of the templated substitution MUST be used as the parameter to the named argument of the annotated function.

            {$number-of-cats}
          

In the example above, a parameter given from the template substitution MUST be set for the function argument called number-of-cats on the annotated function.

Resource Function Constraints

Constraints restrict the service requests that a Resource Function MAY process.

Path Annotation

A Path Annotation maps the URI of a RESTful web service to a Resource Function and provides for path templates.

A Resource Function MUST contain a single path annotation. Additional annotations MAY also be used to constrain or parameterize the Resource Function.

The path annotation is named %rest:path and takes a single mandatory literal string, which describes the URI path for this service. The URI path is considered relative to a base URI () which is implementation defined.

The URI path itself MAY contain zero or more URI templates which denote path segments that MUST map to named function parameters. Parameters addressed by templates in the URI path, MUST meet the following constraints:

  1. Cardinality that MUST allow for an atomic value, otherwise an error should be raised by the implementation. i.e. ONE or ONE_OR_MORE.
  2. Type that MUST inherit from xs:anyAtomicType, otherwise, an error should be raised by the implementation. In addition, conversion from the URI segment string to the required type should be performed at run-time, and an error raised if conversion is impossible.
              declare
                %rest:path("/stock/widget/{$id}")
              function local:widget($id as xs:int) {
            
                (: get the widget :)
                fn:collection("/db/widgets")/widget[@id eq $id]
              };
            

In the above example, a HTTP GET on the following URI, would cause the Widget with the id of '1981' to be retrieved: http://www.widget-factory.com/stock/widget/{$id}.

When many Resource Functions are defined, there can be many Path Annotations, as such conflicts may occur, the resolution of such conflicts MUST be processed as described in .
Method Annotation

Resource Function Parameters

HTTP Mechanics

Base URI

The base URI of a Resource Function is implementation defined. That is to say that an implementation is free to define either statically or dynamically the URI part that appears before the relative URI of any Path Annotation.()

EXPath Package Considerations

HTTP Request Matching

It is often the case that there is one or more Resource Functions that could service an incoming HTTP Request. To avoid conflicts, the most specific Resource Function MUST be applied to an incoming request. This chapter defines the specificity of Resource Functions against HTTP requests.

The specificity of a Resource Function is governed by three rules which MUST be applied in order:

Resource Function Constraint Preference

Resource Functions that impose the most specific constraints MUST first be selected as candidates to process the HTTP Request.

Most specific constraints first:

  1. Path, Method, Media-Type
  2. Path, Method
  3. Path, Media Type
  4. Path
  5. Method, Media Type
  6. Method
  7. Media Type
The following Resource Function:            
            
declare function
  %rest:GET
  %rest:path("/a/b/c")
  %rest:consumes("application/xml")
local:function-1() {
  1
};

is more specific than:

declare function
  %rest:GET
  %rest:path("/a/b/c")
local:function-2() {
  2
};
          

Path Preference

More than one Path from a Resource Function Path Annotations MAY appear to satisfy a request, however often these can be disambiguated by specificity of application to the HTTP Request URI. The most specific paths MUST be selected as candidates to process the HTTP Request.

The rules determining Path specifity to a request are:

  1. Path Segment Length
  2. Path X is more specific than path Y if it has more segments.

                  /a/b is more specific than /a.
                
  3. Path Selection
  4. If more than one Path has the same number of segments, the segments of the paths are compared from left to right.

    Path X is more specific than Path Y if the current segment of Y is a template, while the respective segment of X is not.

                  /a/b is more specific than /a/{$x}.
                  
                  /a/{$x} is more specific than /{$x}/y.
                
              For five possible paths, when listed most specific first, we would see:
              
              /person/elisabeth
              /person/{$name}
              /{$type}/elisabeth
              /{$type}/{$name}
              /person
              /{$type}
          

Media Type Preference

More than one Media Type from Resource Function Consumes or Produces Annotations MAY appear to satisfy a request, however often these can be disambiguated by specificity. The most specific media types MUST be selected as candidates to process the HTTP Request.

The rules determining Media Type specifity are:

  1. Absolute before Wildcard
  2. Absolute Media Types are considered more specific than Media Types with wildcard subtypes

                  application/xml is more specific than application/*.
                

RESTXQ Function Module

RESTXQ offers a few simple functions to assist with the construction of RESTful Web Services.

Registry Functions

Functions to assist in managing the RESTXQ Registry.

rest:resource-functions()

rest:resource-functions() as document-node(element(rest:resource-functions))

Summary: This function returns an XML document describing the Resource Functions registered with the RESTXQ Registry.

The XML document root element rest:resource-functions structure:

<rest:resource-functions>
  rest:resource-function*
</rest:resource-functions>

The rest:resource XML element has the following structure:

<rest:resource-function
  xquery-uri = xs:anyURI>
  <rest:identity
    namespace = xs:anyURI
    local-name = xs:NCName
    arity = xs:int/>
</rest:resource-function>

URI Functions

URI functions assist in the construction and selection of URIs.

rest:base-uri()

rest:base-uri() as xs:anyURI

Summary: This function returns the implementation defined base URI () of the Resource Function.

rest:uri()

rest:uri() as xs:anyURI

Summary: This function is returns the complete URI that addresses the Resource Function. Typically this is the rest:base-uri() appended with the path from the Path Annotation (if present) of the Resource Function.

Resources for Implementers

If you plan to implement RESTXQ, there is already a set of common abstraction libraries written in Java which should significantly reduce the ammount of effort involved and avoid re-inventing more wheels. You need just implement a few interfaces and adapters. For more information see the EXQuery GitHub page.

Annotation Template Grammar

The grammar used for RESTXQ Templates is expressed in EBNF and re-uses the EQName from the XQuery 3.0 grammar

[1] Template ::= "{" "$" EQName "}"

Acknowledgements

Many thanks to: