NAME
Riap::HTTP - Riap over HTTP
VERSION
version 1.1.3
DESCRIPTION
Riap::HTTP is designed to be implemented by API service providers. It allows custom URL layout and some additional features like logging, while utilizing various features already in HTTP (authentication, encryption using HTTPS, etc.)
Server listens to HTTP requests, parses them into Riap requests, executes the Riap requests, and sends the results to clients.
Additional Riap request keys
ofmt => STR
Specify result ("output") format. Defaults to
json
, which the server MUST accept. Server can accept additional result formats if it wants to, likeyaml
,xml
, orphps
(PHP serialization format).Server should give response in
json
if requested result format is not supported.
Additional information keys must returned by server
These are keys in the information hash returned by the info
action.
ifmts => ARRAY OF STR
Supported input formats in HTTP request body.
ofmts => ARRAY OF STR
Supported output formats.
Parsing Riap request from HTTP request
Server can provide defaults for some/all Riap request keys, so client does not need to explicitly set a Riap request key. But server MUST provide a way for client to set any Riap request key.
First, server MUST parse Riap request keys from HTTP X-Riap-*
request headers, e.g. X-Riap-Action
header for setting the action
request key. In addition, the server MUST parse the X-Riap-*-j-
headers for JSON-encoded value (notice the ending -
), e.g.
X-Riap-Args-j-: {"arg1":"val1","arg2":[1,2,3]}
This allows the server to have its own URL scheme, while allowing a way for common access mechanism.
The server MUST also accept args
from HTTP request body. The server MUST accept at least body of type application/json
. It can accept additional types if it wants, e.g. text/yaml
or application/vnd.php.serialized
.
The server can also accept Rinci request keys or function arguments using other means, for example, Serabi, a Perl server implementation, allows parsing uri
from URI path, and function arguments (as well as other Riap request keys, using -riap-*
syntax) from request variables. For example:
http://HOST/api/PKG/SUBPKG/FUN?a1=1&a2:j=[1,%202]
might result in the following Riap request:
{
"uri": 'pm:/My/App/PKG/SUBPKG/FUN',
"action": 'call',
"args": {"a1":1, "a2":[1,2]},
}
Another example:
http://HOST/api/PKG/FUN?-riap-action=complete&-riap-arg=a1&-riap-word=x
will result in the following Rinci request:
{
"uri": 'pm:/PKG/FUN',
"action": 'complete',
"arg": 'a1',
"word": 'x',
}
SPECIFICATION VERSION
1.1
ABSTRACT
This document specifies using HTTP/HTTPS as the transport layer for Riap, or Riap::HTTP for short.
LOGGING
Riap over HTTP also allows a mechanism to pass logging messages during function calls by using HTTP chunked response.
Two additional Riap request keys are recognized for this:
loglevel
An integer number with value either 0 (for none, the default), 1 (for sending fatal messages), 2 (error), 3 (warn), 4 (info), 5 (debug), and 6 (trace). When a value larger than 0 specified, server must return chunked HTTP response and each log message should be sent as a separate chunk, and the result as the last chunk.
marklog
A bool, default to 0. When set to true, server will prepend each log message with "L" (and the result with "R"). Only useful/relevant when turning on loglevel, so clients can parse/separate log message from result.
EXAMPLES
Below are some examples of what is sent and received on the wire. For these examples, the server has the following URL scheme http://example.org/api/v1/<URI>. It detects desired output format from the Accept
HTTP request header.
Call a function, passing function arguments via query parameter, unsuccessfully because of missing argument:
--- Request ---
GET /api/v1/Math/multiply2?a=2 HTTP/1.0
Accept: application/json
--- Response ---
HTTP/1.0 200 OK
Date: Sat, 14 Jan 2012 17:11:40 GMT
Server: Serabi/1.0
Content-Type: application/json
[400,"Missing required argument: b"]
Call the same function, successfully this time. As a variation we pass function arguments through the X-Riap-Args HTTP header:
--- Request ---
GET /api/v1/Math/multiply2 HTTP/1.0
X-Riap-Args-j-: {"a":2,"b":3}
Accept: application/json
--- Response ---
HTTP/1.0 200 OK
Date: Sat, 14 Jan 2012 17:11:50 GMT
Server: Serabi/1.0
Content-Type: application/json
[200,"OK",6]
FAQ
Why not directly return status from enveloped result as HTTP response status?
Since enveloped result is modeled somewhat closely after HTTP message, especially the status code, it might make sense to use the status code directly as HTTP status. But this means losing the ability to differentiate between the two. We want the client to be able to differentiate whether the 500 (Internal server error) or 404 (Not found) code it is getting is from the HTTP or from the enveloped result.
SEE ALSO
AUTHOR
Steven Haryanto <stevenharyanto@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Steven Haryanto.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
2 POD Errors
The following errors were encountered while parsing the POD:
- Around line 31:
'=item' outside of any '=over'
- Around line 40:
You forgot a '=back' before '=head2'