perlancar > Riap > Riap

Download:
Riap-1.2.2.tar.gz

Dependencies

Annotate this POD

Website

View/Report Bugs
Module Version: 1.2.2   Source  

NAME ^

Riap - Rinci access protocol

VERSION ^

This document describes version 1.2.2 of Riap (from Perl distribution Riap), released on 2014-10-30.

SYNOPSIS ^

This document specifies a simple, extensible, client/server, request/response protocol for requesting metadata and performing actions on code entities.

Examples are written in JSON (sometimes with added comments), but data structures can actually be encoded using other formats.

DESCRIPTION ^

Rinci access protocol (Riap for short), is a client/server, request/response protocol for requesting metadata and performing actions on code entities. It is modeled closely after HTTP, but is a different protocol. It can be layered on top of HTTP (as its transport protocol) but can also use other transports, including direct TCP.

The server side is viewed as being a tree of code entities, with a package entity at the root. Other entities (such as subpackages, functions, variables) are discoverable by performing list actions on package entities. Entity's metadata can be retrieved using the meta action. There are other actions defined in the specification; and the protocol can be extended by introducing more actions.

One of the main use-cases of this protocol is to provide self-descriptive, self-documenting, machine-discoverable API service, much like the goal of SOAP and WSDL. However it is much simpler and programmer-friendly than those protocols.

SPECIFICATION VERSION ^

 1.2

STATUS ^

The 1.2 series does not guarantee full backward compatibility between revisions, so caveat implementor. However, major incompatibility will bump the version to 1.3 or 2.0.

TERMINOLOGIES ^

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.

RIAP URI SCHEMES ^

To refer to code entities on the Riap server, a new URI scheme riap is defined. The URI path describes path to code entities while the URI host describes the host language. Examples:

 # refer to Text::sprintfn Perl module
 riap://perl/Text/sprintfn/

 # refer to sprintf function in Text::sprintfn Perl module
 riap://perl/Text/sprintfn/sprintfn

 # refer to PHP variable
 riap://php/$var

 # UNDECIDED: refer to class metadata
 riap://perl/My/Class/:class

 # UNDECIDED: refer to distribution metadata
 riap://perl/My/Dist/:distribution

There are some other schemes recognized.

pl. The pl hostless scheme refers to code entities in Perl. This is preferred in many Perinci modules because the riap scheme is more verbose. Examples:

 # refer to Text::sprintfn Perl module
 pl:/Text/sprintfn/

 # refer to sprintf function in Text::sprintfn Perl module
 pl:/Text/sprintfn/sprintfn

riap+tcp. This scheme is for Riap::Simple over TCP socket. The host (+port) part describes TCP host (+port), and the path part describes path to code entity. Currently there is no default port so please always specify port number. Examples:

 riap+tcp://localhost:5000/Text/sprintfn/
 riap+tcp://localhost:5000/Text/sprintfn/sprintfn

riap+unix. This scheme is for Riap::Simple over Unix socket. There is no host part (Unix socket is localhost-only). The path part describes path to the socket and path to code entity (separated by //).

 riap+unix:/path/to/unix/socket
 riap+unix:/path/to/unix/socket//Text/sprintfn/sprintfn

riap+pipe. This scheme is for Riap::Simple over pipe, to refer to starting a program and talking the protocol over the pipe. There is no host. The path part describes path to program, // separator, arguments separated by /, //separator, and path to code entity.

 # refer to accessing code entity via executing "/path/to/program"
 riap+pipe:/path/to/program////Text/sprintfn/sprintfn

 # refer to via accessing code entity via executing "/path/to/program arg1 arg2"
 riap+pipe:/path/to/program//arg1/arg2//Text/sprintfn/sprintfn

RIAP OVER HTTP/HTTPS ^

For Riap over HTTP/HTTPS as the transport layer, the standard URI scheme http/https is used. The URI path for these do not necessarily map directly to code entities like in riap or pl URIs, they may also support additional features, as each service provider can choose custom URL layout. Example:

 # access tax::id::validate_npwp function, call with arguments
 http://gudangapi.com/ga/tax.id.npwp/validate_npwp?npwp=123456

 # namespace/module can also be omitted when function name is unique. arguments
 # can also be specified by position
 http://gudangapi.com/ga/validate_npwp/123456

However, any Riap request and any code entity URI can still be requested from any http/https URL following the Riap::HTTP protocol..

THE REQUEST ^

As mentioned previously, the Riap request is a mapping of request keys and their values. Common request keys:

Additional keys might be recognized and/or required according to the action.

COMMON ACTIONS ^

Below are the actions which can be implemented by the server. Server can choose to not implement any action, or implement additional actions. But for actions mentioned below, the specification must be followed.

Action: info

Get general information and information about the code entity. This action requires no additional request keys. Upon success, the server must return a hash result with at least the following keys (remember that the result is actually enveloped with a 200 status):

 [200,"OK",
  {
   // entity's type
   "type": "function",

   // canonical URI for the entity
   "uri": "/Package/SubPkg/",
  },
  {"riap.v": 1.2}
 ]

Server may add additional information keys.

Action: actions

List available actions for code entity. The server should return a list of action names:

 [200,"OK",
  ["info","actions","meta","call","complete_arg_val"],
  {"riap.v":1.2}
 ]

Additional request key: detail (bool, optional, default false, can be set to true to make server return a list of records instead).

Under detail, server should return something like this:

 [200,"OK",
  [
   {"name":"info", "summary":"Get general information about code entity"},
   {"name":"actions","summary":"List available actions for code entity"},
   {"name":"meta","summary":"Get metadata for code entity"},
   {"name":"call","summary":"Call function"},
   {"name":"complete_arg_val","summary":"Complete function's argument value"}
  ],
  {"riap.v":1.2}
 ]

It can return additional field like keys to explain additional required/optional request keys (XXX not yet specified).

Action: meta

Return Rinci metadata for the code entity. When the entity does not have metadata, server should return 404 status or better yet 534 (metadata not found).

ACTIONS FOR package ENTITIES ^

Below are actions that must be supported by the package entities.

Action: list

List entities contained in this package. Additional request keys are: type (string, optional, to limit only listing entities of a certain type; default is undef which means list all kinds of entities), recursive (bool, optional, can be set to true to search subpackages; default is false which means only list entities in this namespace), q (string, search terms, to only return matching some search terms; default is undef which means return all entities), detail (bool, optional, whether to return just a list of code entity URIs or a detailed record for each entry, defaults to false; if true, then server must return info hash for each entry, where each info hash like that returned by the info action).

The server should return 200 status or 206 if partial list is returned. If detail is true, for each entry a hash must be returned containing at least uri and type. Server may add additional information like summary, description, etc.

Example, a list action on the top namespace / might return the following:

 [200,"OK",
  ["Math/","Utils/"],
  {"riap.v":1.2}
 ]

Another example, a list action on the pl:/Math namespace, with type set to function and q to multiply, and detail set to true:

 [200,"OK",
  [
   {"uri": "multiply2",
    "type": "function",
    "summary": "Multiply two numbers"},

   {"uri": "multmany",
    "type": "function",
    "summary": "Multiply several numbers"}
  ],
  {"riap.v":1.2}
 ]

An abs_uri can also be provided by server for each record.

Action: child_metas

Get metadata for all the children entities of the package entity.

This action can reduce the number of round-trips, as opposed to client performing list action followed by meta for each child.

Example, an child_metas action on the top namespace / might return the following:

 [200,"OK",
  {
   "Math/":  {"v":1.1, "summary":"This is metadata for Math"},
  ,"Utils/": {"v":1.1, "summary":"This is metadata for Utils"}
  },
  {"riap.v":1.2}
 ]

ACTIONS FOR function ENTITIES ^

Below are actions that are available for the function entities. At least call must be implemented by the server.

Action: call

Call a function and return its result. Additional request keys include:

Action: complete_arg_val

Complete function argument value, a la Bash tab completion where you have a semicompleted word and request possible values started by that word. Additional Riap request keys include:

The server should return a list of possible completions. Example, when completing a delete_user function for the argument username, and word is "st", the server might return:

 [200,"OK",
  ["stella","steven","stuart"],
  {"riap.v":1.2}
 ]

When there is no completion, the server should return an empty list:

 [200,"OK",
  [],
  {"riap.v":1.2}
 ]

Action: complete_arg_elem

This is just like complete_arg_val, except this tries to complete the value of an element of an array argument, instead of the value of the argument itself. This is useful for example when completing this command-line:

 % somecmd --category foo --category <tab>

where category is argument of type array and its element contain some restricted value. The command-line option --category can be specified multiple times to set the array elements.

ACTIONS FOR variable ENTITIES ^

Below are actions that are available for the variable entities.

Action: get

Get variable value.

FAQ ^

Why no actions to modify metadata/code entities?

Since the specification is extensible by adding more actions, you can implement this on your system. These actions are not specified by this specification because currently the main goal of the protocol is to provide API service and read-only access to the metadata.

Alternatively, modifying metada/code entities can be implemented using calls to functions on the server which can perform the modifications.

There are also some issues which need to be considered when adding these actions. First of all, security. Second, you need to decide whether to modify the running/in-memory copy or the actual source code/files (as the code entities are usually stored as). When modifying the in-memory copy, the server-side architecture may have multiple copies (multiple processes and machines). Do you want to modify all those copies or just one the one process?

The name?

Riap stands for Rinci access protocol, but it is also an Indonesian word meaning: to gain in size or number.

THE RESPONSE ^

Server must return an enveloped response as specified in Rinci::function specification, namely a 4-element array: <[STATUS, MESSAGE, RESULT, META]>. STATUS is an integer, MESSAGE is a string, RESULT is of any type and is the actual result, and META is a hash.

Starting from Riap 1.2, server must return META which contains at least riap.v key, containing the Riap protocol version. Client must recognize and remove all riap.* keys from the response before returning the final result to user. If there is an unknown riap.* keys or an unrecognized value, it must fail by returning 501 status to user. This is to handle/detect incompatibilities/new features in future versions.

HISTORY ^

1.2 (Oct 2014)

Version bumped to 1.2. This version addresses sending/receiving binary data over JSON. In this version, client can send base64-encoded binary data in arguments using ARGNAME:base64 key. Server can return base64-encoded binary data in result, this is hinted by the riap.result_encoding attribute in result medatata. To detect/handle incompatibilities in future versions, client now must check riap.v and all riap.* properties in result metadata, and fail if it can't recognize an attribute.

1.1 (Jan 2012)

Rename specification to Riap. Version bumped to 1.1 to various backward-incompatible adjustments to Rinci's terminologies.

1.0 (Aug 2011)

Split specification to Sub::Spec::HTTP.

May 2011

First release of Sub::Spec::HTTP::Server.

SEE ALSO ^

Rinci

JSON RPC, (version 1 at http://json-rpc.org, version 2 at http://jsonrpc.org). First developed 2005, major revision to version 2 in 2009. Similar to Riap in several aspects: 1) request and response are a single hash (JSON objects); 2) transport-independent. Differences to Riap: 1) JSON RPC has a narrower scope, it only deals with RPC/method calls and the other things like metadata access/exchange, etc; 2) JSON RPC is tied to the JSON format, while Riap is serialization-format-independent; 3) JSON RPC mandates a request ID ("id") on every request, to allow pipelining (i.e. client sends an array of requests at once, answers will come potentially out of order). This could be added later to the Riap protocol when necessary.

SPORE, https://github.com/SPORE/specifications/blob/master/spore_description.pod.

SOAP, WSDL. Popular in the early 2000's, with similar goals (easier service discovery, "simple" request/response protocol which can utilize HTTP or other transport layer). Fell out of favor along with the rise of JavaScript and REST and increased criticism against the complexity of XML. Which is ironic because SOAP was originally created to be the simpler alternative to CORBA.

CORBA.

HOMEPAGE ^

Please visit the project's homepage at https://metacpan.org/release/Riap.

SOURCE ^

Source repository is at https://github.com/perlancar/perl-Riap.

BUGS ^

Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Riap

When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.

AUTHOR ^

perlancar <perlancar@cpan.org>

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2014 by perlancar@cpan.org.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

syntax highlighting: