Some sites provide access to remote services, rather than performing local computation. In particular, a site could provide access to a Web service. The Orc library provides sites which perform basic HTTP requests and manipulate JSON and XML data representations; these capabilities are sufficient to interact with many simple web services, especially RESTful services.
The HTTP
site provides a simple mechanism to send GET and POST requests to a URL.
HTTP(
U
)
, where U
is a java.net.URL
, publishes a site which accepts HTTP requests on the URL U
.
HTTP(
S
)
parses the string S
as an absolute URL U
, and then behaves as HTTP(
U
)
.
HTTP(
S
,
Q
)
maps the record Q
to a URL query string QS
by translating each record binding to a query pair, escaping characters
if necessary. The call then behaves as HTTP(
S
+QS
)
.
The HTTP
site publishes a site (call it H
) with methods get
and post
:
H
.get()
performs a GET
request on the URL used to create H
.
H
.post(
P
,
T
)
performs a POST
request with payload P
on the URL used to create H
.
The request's Content-Type
header is set to T
.
If the request is successful, the response is published as a single string, which may be translated to a more useful representation by other library sites.
Web services often expect inputs or provide outputs in a particular format, such as XML or JSON. The Orc library provides sites which convert between string representations of these data formats and structured representations which Orc can manipulate.
JSON (JavaScript Object Notation) is a lightweight data format often used by Web services, especially by services with simple interfaces. The structure of JSON values maps onto Orc values, using nested lists and records.
The library sites ReadJSON
and WriteJSON
convert between string representations of JSON
values and Orc representations of those values. ReadJSON
parses a string representation of JSON
and creates an Orc value, where each JSON array becomes an Orc list,
each JSON object becomes an Orc record, and literal values map to their
Orc counterparts. WriteJSON
performs the inverse operation, taking a structured value of this form
and producing a string representation of an equivalent JSON value. If j
is an Orc
representation of a JSON value, then ReadJSON(WriteJSON(
j
))
is
equal to j
.
XML (Extensible Markup Language) is a structured data format used in many contexts, including Web services.
The library sites ReadXML
and WriteXML
convert between string representations of XML
values and Orc representations of those values. ReadXML
parses a string representation of XML
and creates an Orc representation, which can be manipulated by Orc's XML library sites. WriteXML
performs the inverse operation, taking an Orc representation of XML and serializing it to a string.
If x
is an Orc representation of an XML fragment,
then ReadXML(WriteXML(
x
))
is equal to x
.
Unlike JSON, the structure of XML does not map directly to Orc's structured values. Instead, Orc provides a set of library sites and functions which manipulate XML in a manner similar to Orc's datatypes. Orc's XML manipulation capabilities are currently incomplete; in particular, it does not handle namespaces. All constructed elements have the default namespace, element and attribute tags have no prefixes, and element matching discards namespace and prefix information. For more comprehensive XML manipulation, use of underlying platform capabilities (such as Scala or Java libraries) is recommended.
There are three library sites that construct XML nodes directly. Each of these sites may also be used in a call pattern to match the corresponding constructed value.
XMLElement(
tag
,
attr
,
children
)
creates a new XML element with the tag given by string tag
,
the set of attributes specified by the record attr
,
and the sequence of child elements given by the list children
.
Each value mapped by attr
is converted to a string in the XML representation.
attr
may be an empty record.
Each element of children
must be an XML node.
children
may be an empty list.
XMLText(
txt
)
creates a new XML text node
whose content is the string txt
. Characters in txt
which are not permitted in XML text will be encoded.
XMLCData(
txt
)
creates a new XML CDATA node
whose content is the string txt
. Characters in txt
are not encoded.
The library site IsXML
verifies that its argument is an XML node of some type.
IsXML(
x
)
publishes x
if x
is an XML node;
otherwise it halts silently.
The library provides two records, xml
and xattr
, to manipulate XML
nodes more conveniently than by using the primitive XML sites. Each
record has two members, apply
and unapply
,
that are both functions. The apply function builds XML values,
and the unapply function is used in pattern matching.
xml
is convenient when working only with the tree structure
of XML, and not with the attributes of the element nodes.
Note that xml
's apply and unapply members are not inverses of each other.
xml(
t
,
cs
)
returns a new XML
element with the tag t
, the list of children cs
, and no attributes. If any element
of cs
is not an XML node, it is converted to a string and enclosed in a text node.
The pattern xml(
ptag
,
pchild
)
matches an XML element.
The pattern ptag
is matched against the element tag.
The pattern pchild
is matched against each child of the element;
it is a multimatch, so it may succeed multiple times and produces a result on each success. Additionally, when pchild
matches a text or CDATA node rather than an element node, it is bound to the string contents of the node, rather than the node itself.
xattr
is convenient when working only with the attributes
of XML element nodes, and not with the overall tree structure.
xattr(
x
,
attr
)
returns a new XML element which is the same as x
except that all bindings in the record attr
have been added to the attributes of the element.
If attr
binds any attribute names already bound in x
,
attr
takes precedence and overwrites those bindings.
The pattern xattr(
pe
,
pa
)
matches an XML element.
The pattern pe
is matched against a copy of the element with no attributes.
The pattern pa
is matched against a record containing the attributes of the element.
Though Orc does not provide direct bindings to SOAP web services, it is possible to access such services through Java bindings. Frameworks such as JAX-WS map SOAP web service functionality to Java classes; these classes can then be used as sites in Orc.
{- Make a request to the Fourmilab HotBits service to produce a sequence of 4 random bytes in hex. -} {- Returns a string of n random hexadecimal bytes -} def randombytes(n) = val query = {. nbytes = n, fmt = "xml" .} val location = "https://www.fourmilab.ch/cgi-bin/Hotbits" val response = HTTP(location, query).get() val xml("hotbits", xml("random-data", data)) = ReadXML(response) data.trim() randombytes(4)
Related Reference Topics