Qworum core specification, version 1.0 Draft
Abstract
Qworum is a system of interlinked web-based services. It defines and implements the concept of multi-phase services.
Multi-phase services are RPC-style services: they receive optional call arguments, and return a result. In addition, they can interact with end-users through regular web pages. Multi-phase services can be called by web applications, multi-phase services, and RPC clients.
Qworum defines an XML-based web format that complements HTML, called the Qworum message. Qworum messages are sent by websites to user agents such as web browsers and RPC clients. Services use Qworum messages for performing nested service calls, for storing their internal state on the client, and for returning a result.
Table of contents
- Introduction
- Service composition
- Multi-phase service calls
- Special case: the World Wide Web
- Special case: RPC
- The user agent as mediator for service calls
- Messages
- Message format
- The http://qworum.net/ XML namespace
- The application/xml media type
- The .qrm file extension
- Message evaluation by the user agent
- Statements
- The call statement
- The data statement
- The fault statement
- The goto statement
- The if statement
- The nil statement
- The return statement
- The select statement
- The sequence statement
- The transform statement
- The transient statement
- The try statement
- The variable statement
- Implementations
- Appendices
1. Introduction
1.1. Purpose
The World Wide Web is a system of interlinked hypertext documents accessed via the Internet. Although its initial purpose was to provide an infrastructure for information, the World Wide Web is increasingly being used for applications, which arguably have additional infrastructure needs.
In this context, Qworum defines a standard for decomposing web applications into reusable services. The services that make up a web application do not need to reside all on one single server. With Qworum, the barriers that exist between websites are largely overcome, so that websites can provide services to each other much more easily. In particular, websites can provide interactive services that seamlessly integrate into other websites.
For service providers, the advantage of using Qworum is that services can be interactive as a regular website, or non-interactive as a remote procedure call. In fact, the same service may be interactive during one call, and non-interactive during the next one. In other words, Qworum unifies the World Wide Web and remote procedure call concepts.
Qworum makes use of a specific web message format, which offers functionality that is orthogonal to that of existing web formats such as HTML. As a result, the Qworum specification is expected to evolve independently from those standards.
The present specification provides relevant information for the following groups:
- Developers of Qworum services, and
- Developers of user agents.
1.2. Requirements
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [Keywords].
2. Service composition
Qworum is based on the concept of multi-phase services. The service composition mechanism used by Qworum is directly derived from this concept, and explains the design choices made by Qworum. This and related concepts are described below.
The term phase refers to the following three consecutive steps:
- a user agent sends a request to a server,
- the server performs an operation based on the request and produces a response,
- the user agent receives the response from the server.
According to this definition, conventional remote procedure calls (based on XML-RPC for instance) always consist of a single phase.
The term service refers to a software functionality available on a computer, and used by programs on other computers through network connections. In the context of Qworum, a service is available at a URL that has an http or https scheme, and services are identified by their URL.
2.1. Multi-phase service calls
The term multi-phase service refers to a service whose calls consist of one or more phases.
A multi-phase service call may span several servers, and terminates when the user agent receives a response containing a result message.
In order to continue the current call, a phase may return a response that does not contain a result message. In this case, the user agent will try to use the message for initiating the next phase of the current call. When the HTTP protocol is used, HTTP redirections and interaction messages such as HTML pages allow such call continuations. Another way of performing call continuations is through the use of composition messages.
2.2. Special case: the World Wide Web
The multi-phase service call concept is more general than the World Wide Web paradigm.
Indeed, a web browsing session inside a browser tab (or window) is equivalent to a multi-phase service call which never returns a result, and which never calls other services by using the proposed composition mechanism.
2.3. Special case: RPC
The multi-phase service call concept is also more general than the concept of remote procedure call: a multi-phase service call consisting of a single phase is equivalent to a conventional remote procedure call.
2.4. The user agent as mediator for service calls
According to the proposed composition mechanism, a service calls another service as follows:
- The calling service sends a composition message to the user agent.
- Based on the instructions contained in this message, the user agent then performs the service call, between two consecutive phases of the calling service.
- The service call terminates when one of its phases sends a result message to the user agent.
- The user agent then sends the received result to the calling service, at a URL specified in the composition message previously received.
Qworum does not impose any restrictions on the number of nested calls: a service may call another service, which calls another service, which calls yet another service, etc. A service may also make recursive calls to itself.
3. Messages
3.1. Message format
Qworum defines an XML [XML] message format that supports the basic service composition pattern described in the previous section.
Qworum messages are scripts, rather than human-centric documents. Each Qworum message MUST contain one Qworum statement, which MUST NOT be the data statement.
Here is a result message that might be sent back by an e-mail lookup service:
<!-- message contains a 'return' statement -->
<qrm:return xmlns:qrm='http://qworum.net/'>
<email>john.smith@email.com</email>
</qrm:return>
And here is a composition message used for calling the e-mail lookup service (goto describes the next phase of the current call, and call describes the service call to be performed by the user agent on behalf of the current call):
<qrm:goto href='receive_email_address' xmlns:qrm='http://qworum.net/'>
<qrm:call href='email_lookup'>
<name>John Smith</name> <!-- call parameter -->
</qrm:call>
</qrm:goto>
Qworum messages also enable more advanced usage patterns. Here is a message which is neither a pure result message, nor a composition message (this particular message might be described as a result message with parts provided by service calls):
<qrm:return xmlns:qrm='http://qworum.net/'>
<emails>
<qrm:call href='email_lookup'>
<name>John Smith</name>
</qrm:call>
<qrm:call href='email_lookup'>
<name>Jack Smith</name>
</qrm:call>
</emails>
</qrm:return>
3.2. The http://qworum.net/ XML namespace
Qworum defines an XML vocabulary that is used in messages. All elements of this vocabulary belong to the http://qworum.net/ namespace [XMLnamespaces]. Elements belonging to this namespace are also referred to as Qworum elements. Elements that do not belong to this namespace are also referred to as non-Qworum elements.
All statements are described by a Qworum element, except the data statement. Some Qworum elements, namely title and catch, do not describe a statement but are part of an enclosing statement.
3.3. The application/xml media type
The media type of Qworum messages is application/xml. Media types are explained in the section 3.7 of the HTTP/1.1 specification [HTTP/1.1].
User agents which implement the present version of the Qworum specification SHOULD include this media type in the Accept headers of the HTTP(S) requests they generate: For example, a web browser might generate the following request header:
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
If an HTTP(S) response contains a Qworum message, then servers MUST send this media type in the Content-Type header. Example:
Content-Type: application/xml;charset=utf-8
3.4. The .qrm file extension
Files containing a Qworum message MAY have a .qrm extension. For example, a file containing a message that calls a payment processing service might be named payment_processing_call.qrm.
3.5. Message evaluation by the user agent
When a user agent receives a response with the application/xml media type whose root element is a Qworum element, it MUST evaluate the response as a Qworum message. Otherwise, the user agent MUST NOT evaluate the response as a Qworum message.
Most statements yield a result when evaluated. For example, the call statement:
<qrm:call href='email_lookup' xmlns:qrm='http://qworum.net/'> <name>John Smith</name> </qrm:call>
yields a call result, which might be:
<email>john.smith@email.com</email>
And the data statement:
<emails xmlns:qrm='http://qworum.net/'>
<qrm:call href='email_lookup'>
<name>John Smith</name>
</qrm:call>
<qrm:call href='email_lookup'>
<name>Jack Smith</name>
</qrm:call>
</emails>
might yield:
<emails> <email>john.smith@email.com</email> <email>jack.smith@email.com</email> </emails>
The following statements disrupt the flow of evaluation, and consequently do not yield a result:
Message evaluations are interrupted during a service call; they resume when the call terminates. A message evaluation ends when:
- the next phase of the current call is initiated, or
- the current call terminates.
The next phase of the current call is initiated when a goto statement is evaluated.
The current call terminates when:
- the main statement (represented by the root XML element) yields a result, or
- a return statement is evaluated, or
- an uncaught fault is evaluated.
The user agent maintains an internal call stack for handling service calls. In the case of a web browser, each tab or window has a call stack associated with it.
Call stacks initially contain one frame, which represents the main service call. Call frames are used for storing variable values and messages whose evaluations were interrupted by service calls. The topmost call frame, corresponding to the current service call, does not contain any message.
4. Statements
4.1. The call statement
The call statement initiates a multi-phase service call. The evaluation of this statement is interrupted until the call returns a result. The evaluation then ends by yielding the call result.
call elements MAY have an href attribute which indicates the URL of the first phase of the service to be called. The value of the href attribute MUST be an absolute HTTP or HTTPS URL [URL], or a relative URL [RelativeURL]. An absent href attribute is equivalent to an href attribute whose value is the URL of the message containing the call statement, and a relative URL is resolved using the message URL. For example, a request to http://www.ahost.com/path may return any one of the following messages; they will all initiate a call by sending a GET request to http://www.ahost.com/path:
<call xmlns='http://qworum.net/' /> <call href='path' xmlns='http://qworum.net/' /> <call href='http://www.ahost.com/path' xmlns='http://qworum.net/' />
call elements MAY contain a statement called the parameter statement. If the parameter statement is present, then the user agent MUST perform the following sequence of events:
- The parameter statement is evaluated.
- The evaluation result of the parameter statement is put into a call variable named call parameter, so that all phases of the call to be performed have easy access to it.
- The call is initiated with a POST request. The request body contains the evaluation result of the parameter statement. The body content type is either application/xml or application/x-www-form-urlencoded. In the latter case, the control name qworum is used in the body (example: qworum=%3Cemail%3Ejohn.smith@email.com%3C/email%3E). It is RECOMMENDED that user agents use application/xml as the body content type.
call elements contain zero, one or more title elements which briefly describe the call. An OPTIONAL lang attribute indicates the human language that is being used. Accepted values for this attribute are described in the section 3.10 of the HTTP/1.1 [HTTP/1.1] specification. title elements MUST NOT contain any elements.
For example, the following statement:
<qrm:call href='https://www.apaymentprocessingsite.com/process_payment' xmlns:qrm='http://qworum.net/'>
<qrm:title>Calling the payment processing service ..</qrm:title>
<payment>
<description>1 x 1-year subscription for "A Business Magazine"</description>
<total>98.95</total>
<currency>USD</currency>
<merchant>payments@anecommercesite.com</merchant>
</payment>
</qrm:call>
might send an application/xml POST request to https://www.apaymentprocessingsite.com/process_payment, where the request body (as well as the call variable named call parameter) contains:
<payment> <description>1 x 1-year subscription for "A Business Magazine"</description> <total>98.95</total> <currency>USD</currency> <merchant>payments@anecommercesite.com</merchant> </payment>
The user agent MUST raise an authorization fault instead of evaluating a call statement if the evaluation would redirect the user agent from an internet site to a private or local site.
4.2. The data statement
Data statements are non-Qworum elements that MAY have other non-Qworum elements or statements as descendents. Their evaluation ends when all descendent statements have been evaluated in a depth-first manner. For example, the statement:
<emails>
<qrm:call href='email_lookup' xmlns:qrm='http://qworum.net/'>
<!-- this call is evaluated first -->
<name>John Smith</name>
</qrm:call>
<qrm:call href='email_lookup' xmlns:qrm='http://qworum.net/'>
<!-- this call is evaluated second -->
<name>Jack Smith</name>
</qrm:call>
</emails>
may yield:
<emails> <email>john.smith@email.com</email> <email>jack.smith@email.com</email> </emails>
And the following statement remains unchanged after evaluation.
<name>John Smith</name>
4.3. The fault statement
The fault statement indicates an error condition that prevents a service call from proceeding normally. Faults can be caught and handled by try statements. Fault example:
<fault xmlns='http://qworum.net/' />
Faults are classified into types which narrow down the underlying cause of an error condition, so that user agents are able to handle each type of fault separately.
Faults of type service indicate that the error condition is due to the service which is currently being called. Such faults can be explicitly raised by services. They MAY also be raised by the user agent. In the latter case, some possible causes are:
- The user agent received an invalid HTTP(S) response.
- The user agent received an HTTP(S) response that indicates another service issue (examples: 500 Internal Server Error, 404 Not Found).
Faults of type message indicate that the user agent received a Qworum message that does not conform to the present specification.
Services MAY use fault types that are not specified by the present specification. Such types MUST start with the * character and MUST NOT contain the comma (,) character. They are subtypes of the extension type, which is in turn a subtype of service. Example:
<fault type='* parameter is not a name' xmlns='http://qworum.net/' />
Faults of type network indicate that the user agent is unable to execute a call phase, either because it cannot find and connect to the server, or because it was disconnected before it could receive a complete HTTP(S) response. In this situation, the user agent MAY act as if it has received a Qworum message that contains a single network fault.
Faults of type user agent indicate that a user agent issue prevents the current call to proceed normally. The user agent MUST raise a user agent fault if it is unable to evaluate a valid Qworum statement, for example because of an internal error. The user agent MAY also raise a user agent fault if it receives an HTTP(S) response that indicates a client-side issue (such as a 400 Bad Request or 408 Request Timeout response).
The user agent fault type has authorization and user subtypes:
- The user agent MUST raise an authorization fault if a statement could not be evaluated because of authorization issues (see call, goto, [DRM/1.0], [Enterprise/1.0]).
- The user agent MAY raise a user fault if it receives an HTTP(S) response that requires interacting with the end-user in order to continue the current call, and if said user is not available. For example, an RPC client (which calls a Qworum service directly) may internally raise a user fault when it receives a 200 OK HTTP(S) response whose content is not a Qworum message.
fault elements contain zero, one or more title elements which briefly describe the fault. An OPTIONAL lang attribute indicates the human language that is being used. Accepted values for this attribute are described in the section 3.10 of the HTTP/1.1 [HTTP/1.1] specification. title elements MUST NOT contain any elements. Example:
<fault xmlns='http://qworum.net/'> <title lang='de'>Unbekannte Aktie<title> <title lang='fr'>Code inconnu<title> <title>Unknown ticker symbol<title> </fault>
The default fault type is service, so that the following statements are equivalent:
<fault type='service' xmlns='http://qworum.net/' /> <fault xmlns='http://qworum.net/' />
4.4. The goto statement
The goto statement initiates the next phase of a multi-phase service call.
goto elements MAY have an href attribute which indicates the URL of the next phase. The value of the href attribute MUST be an absolute HTTP or HTTPS URL [URL], or a relative URL [RelativeURL]. An absent href attribute is equivalent to an href attribute whose value is the URL of the message containing the goto statement, and a relative URL is resolved using the message URL. For example, a request to http://www.ahost.com/path might return any one of the following messages; they will all initiate the next phase of the current call by sending a GET request to http://www.ahost.com/path:
<goto xmlns='http://qworum.net/' /> <goto href='path' xmlns='http://qworum.net/' /> <goto href='http://www.ahost.com/path' xmlns='http://qworum.net/' />
goto elements MAY contain a statement called the parameter statement. If the parameter statement is present, then the user agent MUST perform the following sequence of events:
- The parameter statement is evaluated.
- The phase is initiated with a POST request. The request body contains the evaluation result of the parameter statement. The body content type is either application/xml or application/x-www-form-urlencoded. In the latter case, the control name qworum is used in the body (example: qworum=%3Cemail%3Ejohn.smith@email.com%3C/email%3E). It is RECOMMENDED that user agents use application/xml as the body content type.
goto elements contain zero, one or more title elements which briefly describe the next phase. An OPTIONAL lang attribute indicates the human language that is being used. Accepted values for this attribute are described in the section 3.10 of the HTTP/1.1 [HTTP/1.1] specification. title elements do not contain any elements.
For example, the following statement:
<qrm:goto href='http://www.anecommercesite.com/process_payment' xmlns:qrm='http://qworum.net/'>
<qrm:title>Start processing the payment ..</qrm:title>
<payment>
<description>1 x 1-year subscription for "A Business Magazine"</description>
<total>98.95</total>
<currency>USD</currency>
<merchant>payments@anecommercesite.com</merchant>
</payment>
</qrm:goto>
might send an application/xml POST request to http://www.anecommercesite.com/process_payment, and the request body contains:
<payment> <description>1 x 1-year subscription for "A Business Magazine"</description> <total>98.95</total> <currency>USD</currency> <merchant>payments@anecommercesite.com</merchant> </payment>
The user agent MUST raise an authorization fault instead of evaluating a goto statement if the evaluation would redirect the user agent from an internet site to a private or local site.
4.5. The if statement
if is a conditional statement. It MUST contain a condition statement, followed by a "then" statement, followed by an OPTIONAL "else" statement. The default value of the "else" statement is nil.
The condition statement is evaluated first. If it yields nil, then the "else" statement is evaluated, and the if statement yields that value. Otherwise, the "then" statement is evaluated, and the if statement yields that value.
For example, the following statement:
<qrm:if xmlns:qrm='http://qworum.net/'> <qrm:nil /> <text>Positive</text> <text>Negative</text> </qrm:if>
yields:
<text>Negative</text>
4.6. The nil statement
The nil statement represents data that does not carry any information. It remains unchanged after evaluation. Example:
<nil xmlns='http://qworum.net/' />
The nil element MUST NOT have any attributes, and it MUST NOT contain any elements.
4.7. The return statement
The return statement terminates the current call by returning a result. It MUST NOT contain more than one statement. For example, the statement:
<parent>
<qrm:return xmlns:qrm='http://qworum.net/'>
<email>john.smith@email.com</email>
</qrm:return>
</parent>
returns the result:
<email>john.smith@email.com</email>
And the following statement returns nil:
<return xmlns='http://qworum.net/' />
The return element MUST NOT have any attributes.
4.8. The select statement
The select statement is used for selecting an element from the value yielded by the statement it MUST contain. The select element MUST have an xpath attribute whose value is an expression that conforms to the XPath 1.0 specification [XPath/1.0], and it has an OPTIONAL namespaces attribute which defines the namespace prefixes used in the XPath expression.
This statement MUST raise a message fault if the XPath expression is not valid. Otherwise, this statement MUST yield the element that is matched by the XPath expression. If several elements match the XPath expression, then this statement MUST yield the first matched element. It MUST yield nil if the XPath expression:
- points to a node that is not an element (such as an attribute or a text node),
- returns a character string, a number or a boolean value,
- returns an empty node set.
For example, the following statement:
<qrm:select xpath='/bookshelf/book' xmlns:qrm='http://qworum.net/'>
<bookshelf>
<book>
<title>The XPath Book</title>
</book>
<book>
<title>The XML Book</title>
</book>
</bookshelf>
</qrm:select>
yields:
<book> <title>The XPath Book</title> </book>
And the following statement:
<qrm:select xpath='book/d:title'
namespaces='d http://purl.org/dc/elements/1.1/ m http://mycompany.com/ns'
xmlns:qrm='http://qworum.net/'>
<bookshelf xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:my='http://mycompany.com/ns'>
<book>
<dc:title>The XPath Book</dc:title>
<my:inventory>22</my:inventory>
</book>
<book>
<dc:title>The XML Book</dc:title>
<my:inventory>44</my:inventory>
</book>
</bookshelf>
</qrm:select>
yields:
<dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">The XPath Book</dc:title>
4.9. The sequence statement
The sequence statement contains zero, one or more statements, each of which is evaluated in turn. The evaluation of this statement yields the result that is yielded by the last statement it contains. For example, the statement:
<qrm:sequence xmlns:qrm='http://qworum.net/'>
<qrm:call href='email_lookup'>
<name>John Smith</name>
</qrm:call>
<email>jack.smith@email.com</email>
</qrm:sequence>
yields (if the service call did not terminate with a fault):
<email>jack.smith@email.com</email>
And the following empty statement returns nil:
<sequence xmlns='http://qworum.net/' />
The sequence element MUST NOT have any attributes.
4.10. The transform statement
The transform statement transforms the value yielded by a statement. It MUST contain an XSL stylesheet that conforms to the XSLT syntax [XSLT], followed by the statement whose value is to be transformed. User agents MUST ignore xsl:output elements in the XSL stylesheet.
If the XSL stylesheet is not valid, then the user agent MUST raise a message fault. If the transformation does not yield any value, then the transform statement MUST yield nil.
For example, the following statement:
<qrm:transform xmlns:qrm='http://qworum.net/'>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match="/">
<books type='nearly out of stock'>
<xsl:for-each select='*/book[inventory<5]'>
<book><xsl:value-of select='title' /></book>
</xsl:for-each>
</books>
</xsl:template>
<xsl:output method='text' /> <!-- ignored by the user agent -->
</xsl:stylesheet>
<bookstore>
<book>
<title>The XSLT Book</title>
<inventory>1</inventory>
</book>
<book>
<title>The XML Book</title>
<inventory>44</inventory>
</book>
</bookstore>
</qrm:transform>
will yield:
<books type='nearly out of stock'> <book>The XSLT Book</book> </books>
4.11. The transient statement
The transient statement is used for handling message variables, which exist only during the evaluation of a given message. The transient element MUST have a name attribute which identifies the message variable being handled.
When setting the value of a message variable, the transient element contains one statement which yields the value. The transient statement in turn yields that same value. For example, the statement:
<qrm:transient name='John's e-mail' xmlns:qrm='http://qworum.net/'>
<qrm:call href='email_lookup'>
<name>John Smith</name>
</qrm:call>
</qrm:transient>
might yield:
<email>john.smith@email.com</email>
When getting the value of a message variable, the transient element does not contain any element, and the statement yields the value of the message variable. For example, the statement:
<transient name='John's e-mail' xmlns='http://qworum.net/' />
might yield:
<email>john.smith@email.com</email>
The following statement uses transient in order to avoid code duplication:
<qrm:try xmlns:qrm='http://qworum.net/'> <!-- Look for user in first database --> <qrm:call href='http://first.user-database/email_lookup'> <qrm:transient name='User'> <name>John Smith</name> </qrm:transient> </qrm:call> <qrm:catch> <!-- User not found in first database --> <qrm:try> <!-- Look for user in second database --> <qrm:call href='http://second.user-database/email_lookup'> <qrm:transient name='User' /> </qrm:call> <qrm:catch> <!-- User not found in second database --> </qrm:catch> </qrm:try> </qrm:catch> </qrm:try>
The default value of a message variable is nil.
4.12. The try statement
The try statement allows user agents to handle a fault in order to prevent it from terminating the current call. try statements MUST contain one statement (the tried statement) followed by one or more catch elements.
Each catch element contains zero, one or more statements that are evaluated when a fault is caught by this element. A catch element that does not contain any statement is equivalent to one that contains a nil statement.
catch elements MAY have a types attribute whose value is a comma-separated list of caught fault types. If the types attribute is absent, than the catch element catches all faults.
The evaluation of try starts with the evaluation of the tried statement. If the tried statement is successful, then try yields the result of that statement. For example:
<qrm:try xmlns:qrm='http://qworum.net/'>
<text>succeeds</text>
<qrm:catch>
<text>will never be evaluated</text>
</qrm:catch>
</qrm:try>
yields:
<text>succeeds</text>
If the tried statement fails because of a fault, then statements in the first catch that matches the fault type are evaluated, and try yields the result of the last statement. For example, the statement:
<qrm:try xmlns:qrm='http://qworum.net/'>
<qrm:fault />
<qrm:catch types='message, user agent'>
<text>fault is of type message or user agent</text>
<text>0</text>
</qrm:catch>
<qrm:catch types='service'>
<text>fault is of type service</text>
<text>1</text>
</qrm:catch>
<qrm:catch types='service'>
<text>fault is of type service</text>
<text>2</text>
</qrm:catch>
<qrm:catch>
<text>fault is of an undetermined type</text>
<text>3</text>
</qrm:catch>
</qrm:try>
yields:
<text>1</text>
In the following example, try is unable to handle the failed tried statement. The current call will terminate with a fault, unless an enclosing try statement in the same message handles the fault:
<try xmlns='http://qworum.net/'> <fault /> <catch types='message, user agent' /> </try>
4.13. The variable statement
An issue that quickly arises when developing Qworum services is that of representing call state. Conventional RPC services do not need a mechanism for storing call state, as calls to RPC services always consist of a single phase. In this regard Qworum services are similar to web applications (or websites) whose execution may span several phases, which creates a need for representing a state that is shared between phases.
Qworum addresses the call state representation issue through the concept of call variables. Call variables are stored on the user agent, and they exist throughout the duration of the service call in which they are defined. Call variables are manipulated through the variable statement which has an attribute named name that identifies the variable.
When setting the value of a call variable, the variable element contains one statement which yields the value. The variable statement in turn yields that same value. For example, the statement:
<qrm:variable name='John's e-mail' xmlns:qrm='http://qworum.net/'>
<qrm:call href='email_lookup'>
<name>John Smith</name>
</qrm:call>
</qrm:variable>
might yield:
<email>john.smith@email.com</email>
When getting the value of a call variable, the variable element does not contain any element, and the statement yields the value of the call variable. For example, the statement:
<variable name='John's e-mail' xmlns='http://qworum.net/' />
might yield:
<email>john.smith@email.com</email>
The following statement sets the value of a call variable and initiates the next phase:
<qrm:sequence xmlns:qrm='http://qworum.net/'>
<qrm:variable name='Username'>
<username>john.smith</username>
</qrm:variable>
<qrm:goto href='call_variable_is_set' />
</qrm:sequence>
The default value of a call variable is nil.
5. Implementations
User agents which implement the present version of the Qworum core specification MUST also implement the following specifications:
- Version 1.0 of the Qworum Digital Rights Management specification [DRM/1.0],
- Version 1.0 of the Qworum Enterprise specification [Enterprise/1.0].
In order to prevent call stacks from going out of sync with the web pages that end-users manipulate, it is RECOMMENDED that web browsers clear the URL history of tabs up to, and including, the URL of the latest received Qworum message.
It is RECOMMENDED that user agents do not allow end-users to choose the target frame of a link during service calls.
In addition, it is RECOMMENDED that user agents send correct Referer headers when evaluting call or goto statements. For example, if the user agent receives the message below from http://www.example.com/msg, then the Referer header of the HTTP request it generates when evaluting the goto statement MAY contain http://www.example.com/msg (e.g. rather than the URL of the last phase of the service call http://www.example.com/email_lookup, which would be incorrect):
<qrm:goto href='receive_email_address' xmlns:qrm='http://qworum.net/'>
<qrm:call href='email_lookup'>
<name>John Smith</name>
</qrm:call>
</qrm:goto>
It is further RECOMMENDED that user agents do not allow end-users to bookmark pages during service calls.
6. Appendices
6.1. References
| [HTTP/1.1] | Berners-Lee, T., Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., and Leach, P., Hypertext Transfer Protocol -- HTTP/1.1, RFC 2616 |
| [HTTP/1.0] | Berners-Lee, T., Fielding, R. and Frystyk, H., Hypertext Transfer Protocol -- HTTP/1.0, RFC 1945 |
| [HTTPS] | Rescorla, E., HTTP Over TLS, RFC 2818 |
| [URL] | Berners-Lee, T., Masinter, L., and McCahill, M., Uniform Resource Locators (URL), RFC 1738 |
| [RelativeURL] | Fielding, R., Relative Uniform Resource Locators, RFC 1808 |
| [XML] | Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, François Yergeau, Extensible Markup Language (XML), W3C Recommendation |
| [XMLnamespaces] | Tim Bray, Dave Hollander, Andrew Layman, Richard Tobin, Namespaces in XML 1.0, W3C Recommendation |
| [XPath/1.0] | James Clark, Steve DeRose, XML Path Language (XPath), Version 1.0, W3C Recommendation |
| [XSLT] | James Clark, XSL Transformations (XSLT), Version 1.0, W3C Recommendation |
| [TLD] | Top-level domain |
| [IPaddress] | IP address |
| [Loopback] | Loopback IP address |
| [Keywords] | Bradner, B., Key words for use in RFCs to Indicate Requirement Levels, RFC 2119 |
| [DRM/1.0] | Doğa Armangil, Qworum Digital Rights Management (DRM) specification, version 1.0 |
| [Enterpise/1.0] | Doğa Armangil, Qworum Enterprise specification, version 1.0 |
6.2. Revision history
| 2012.01.10 | Fixed typo in section 4.10. |
| 2011.11.02 | Added recommendations in section 5. |
| 2011.10.18 | Abstract updated. |
| 2011.09.11 | Add user fault type. |
| 2010.11.22 | Changed the media type of Qworum messages to application/xml; application/x-www-form-urlencoded is now allowed (though not recommended) as the request body content type. |
| 2010.06.10 | Added the transform statement. |
| 2010.06.04 | Added the if and select statements. |
| 2010.04.05 | Initial release of 1.0 draft. |
| 2007.09.06 | First draft. |
6.3. Copyright and disclaimer
© Copyright 2007-2010 Doğa Armangil. All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and these paragraphs are included on all such copies and derivative works. This document may not be modified in any way, such as by removing the copyright notice or references to Doğa Armangil or other organizations.
Any party may, for commercial or non-commercial purposes, send Qworum messages from web servers to user agents, without royalty or license fee to Doğa Armangil.
In addition, any party may, without royalty or license fee to Doğa Armangil, implement client-side software which conform to the present specification, allowing web browsers and other user agents to handle Qworum messages.
THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN IS PROVIDED "AS IS", AND DOĞA ARMANGIL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. FURTHER, DOĞA ARMANGIL WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THIS DOCUMENT.