In addition to defining and issuing requests at the physical level, requests may be declared at the logical level using the standard declarative request syntax and issued by a variety of tools and services.
The standard declarative request is an XML fragment which can be included within XML documents used by tools and service configurations. It must have a root element which is usually request (alternates include setup and teardown in XUnit) and it must have an identifier child element.
The request identifier element may be either a resource identifier:
or, with the meta: prefix, a logical endpoint identifier:
If a logical endpoint identifier is used then a request with the META verb is issued to retrieve the grammar of the logical endpoint. That grammar then guides the construction of a resource identifier to be used in the request.
The identifier may contain Argument Subsitutions.
The optional verb child element must have the text value SOURCE, SINK, NEW, EXISTS, DELETE, META or TRANSREPT. If the verb child element it is omitted, the request uses the SOURCE verb. For example, the following request specifies the SINK verb:
The optional representation child element specifies the required representation type (Java class or interface) of the returned representation. For example, the following request specifies that the returned representation must be a object of the type java.lang.String:
Request arguments are included by using the argument child element which must have a name attribute specifying the name of the argument.
Argument elements may contain one of three types of content:
pass by reference string literal - this string is used as the argument value and is substituted into the constructed identifier. These string literals may contain Argument Subsitutions. For example, the following defines a request for the toUpper service with the named argument operand specifying the resource to be converted to upper case:
pass by value literal - when the argument element contains a child literal element a representation is constructed and is added as a pass-by-value argument. For more details see the literals section. For example:
request - (advanced) when the argument element contains a child request element a request is constructed and is added as a pass-by-request argument. For example:
By default the way an argument is added to the request is dependent upon how that argument is specified, i.e. whether it is specified as a string literal, pass-by-value literal or a request. However it is possible to override this default behaviour using a method attribute on the argument element. When an argument is specified as a request it is not possible to specify a method. When an argument is specified as a literal the only valid method is "data-uri".
|value||The string literal is treated as a resource identifier and SOURCEd before being added as a pass-by-value argument.|
|data-uri||The argument's representation is converted into a data URI and passed by reference. If the argument is specified as an identifier it is first SOURCEd.|
|as-string||This method is useful for converting an incoming pass-by-reference arguments to pass-by-value. Incoming
arguments are the arguments that are received by the endpoint which is constructing the declarative request.
The string value of the argument is converted to a string representation and added as a pass-by-value argument to the request.
It is only meaningful to use this method with arg: identifiers, for example if we have an incoming request with the following identifier:
res:/customer/1234and our grammar is:
<grammar>res:/customer/then this declarative request:
<regex type="number" />
<request>will parse the string "1234" from the incoming request and add it as a pass-by-value argument on the call to groovy.
<argument name="customerId" method="as-string">arg:customerId</argument>
|from-string||This method is the inverse of as-string and as such it is useful for converting an incoming pass-by-value argument into a pass-by-reference argument. The argument is treated as an identifier reference and SOURCEd as a string. This string is then passed-by-reference on the constructed requests identifier.|
By default any runtime errors whilst trying to add an argument will cause the declarative request to fail. These errors are usually caused by failing to SOURCE an identifier when method="value" or method="data-uri". Or referencing arguments that don't exist. By specifying a tolerant attribute with a value of "true" on an argument can cause any errors to be tolerated, e.g.
The varargs element is used to add any arguments from inbound request the context (context.getThisRequest()) on to the constructed request. It will attempt to add all arguments that haven't otherwise been specified with explicit argument tags. It will be tolerant of an errors adding arguments in a similar way to the tolerant attribute on argument tags.
The string literal identifier used in declarative request argument or identifier may be composed using arguments obtained from arguments from the incoming request. For example, this argument uses part of a REST path parsed by a grammar:
and this example uses the resource name parsed by a grammar:
An argument can be specified to be the primary argument of a request (for a TRANSREPT or SINK request) by using the reserved argument name "primary". When an identifier is used with the primary argument, its representation is retrieved with a separate request using the SOURCE verb and the returned representation is then used as a pass-by-value argument:
An arguments value maybe a literal. This is specified inline and when processed the literal value is passed-by-value with the request. Optionally the method="data-uri" attribute may be specified with a literal argument.
In addition to string , all the Java primitive types plus others are supported by the declarative request:
|xml||In-line XML document fragment (DOM is generated)|
|hds||In-line HDS document fragment|
|string||String object set to the specified value|
|boolean||Boolean object set to the specified value|
|char||Character object set to the specified value|
|integer||Integer object set to the specified value|
|byte||Byte object set to the specified value|
|long||Long object set to the specified value|
|float||Float object set to the specified value|
|double||Double object set to the specified value|
|Java class||Creates an instance of the specified class with optional constructor arguments declared by nested literals|
XML literals can be specified, they are created as a DOM representation:
HDS literals with one or more root nodes can be specified:
If the type is not one of the above specified values the type is assumed to be the class of a representation and an instance of this representation will be constructed. Argument to the constructed representation may be specified with additional nested literals. Construction arguments are passed to the constructor in the order they are declared and they must match a valid public constructor for that representations class.
One or more optional header elements may be added to the request to specify Request headers. A name attribute must be specified and an optional sticky attribute will determine if the header is created sticky or not. Headers support both literal text which will create a java.lang.String value or a literal sub-element which has the same capabilities as literals inside arguments.