JSON-RPC Introspection Extension

This extension adds introspection to your server. The implementation follows closely the XMLRPC introspection feature, but a few things differ, among other things due to the much less type-strict nature of JSON-RPC.

In contrast to the XMLRPC standard, the methods listMethods, methodSignature and methodHelp are not methods of a virtual service system, but are made available as parts of the service class itself.

The Methods

(The following text has been adapted from http://xmlrpc-c.sourceforge.net/introspection.html).

Introspection consists of 3 methods. For a server to provide Introspection service this means it has the methods listMethods, methodSignature and methodHelp.

A server might have Introspection service and yet keep some or all of its methods secret. I.e. Introspection does not require a server to report on its methods; only that for the ones that it does, it reports in a certain way.

listMethods

This method returns a list of the methods the server has, by name. There are no parameters.

The result is an array of strings. The value of each element is the name of a method that the service implements. The introspection methods are not excluded. Each element is unique (the same name doesn't appear twice in the list).

It is not required that the list be a complete list of the methods the service implements; i.e. the service may choose to keep some secret. But it is required that any method in the list actually exist in the service – the server may not fail an RPC with a "no such method" error if its name appears in this list.

Example result for calling qooxdoo.test.listMethods:

["echo","sink","sleep","getInteger","getFloat","getString","getBadString","getArrayInteger","getArrayString","getObject","getTrue","getFalse","getNull","isInteger","isFloat","isString","isBoolean","isArray","isObject","isNull","getParams","getParam","getCurrentTimestamp","getError","listServices","listMethods","methodSignature","methodHelp"]   

methodSignature

This method returns a description of the argument format a particular method expects. The method takes one parameter, a string. Its value is the name of the method about which information is being requested.

The result is an array, with each element representing one method signature. The array is a list of the signatures of the method. There are no duplicate signatures. The list does not necessarily contain all possible signatures (it would not be realistic to expect it to do so, because some methods are so flexible that they have an infinite set of signatures). We refer to the signatures that the server is willing to report as the signatures that the introspection machinery "knows."

A signature is a description of parameter and result types for a call to a method. A method can have multiple signatures; for example a method might take either a host name and port number or just a host name (and default the port number).

The array entry that represents a signature is an array of strings, with at least one element. The first element tells the type of the method's result. The rest tells the types of the method's parameters, in order. If there is no information on the return value or the parameters part of the signature, the server returns a "null" value for the return type, or the parameters, respectively. Thus the minimum response on a method that the server doesn't know anything about will be [null,null].

Each of these strings identifies a type by the javascript type that for it that would be returned by the javascript "typeof" keyword, with the exception of the "Array" type, which has a typeof "object" in javascript, but returns the string "array".

The RPC fails if the server does not have a method by the indicated name, or does not want to admit that it does. But if the method name appears in the response to listMethods, the RPC does not fail this way.

Example result for calling qooxdoo.test.methodSignature('methodSignature'):

[ [docs:array_string] ]

methodHelp

This method returns a text description of a particular method. The method takes one parameter, an string. Its value is the name of the method about which information is being requested.

The result is a string. The value of that string is a text description, for human use, of the method in question.

The server may give as much or as little detail as it wants, including an empty string.

The string may alternatively contain HTML markup (i.e. not be precisely text). A client is not required to recognize it as such; i.e. it can leave the HTML markup for human interpretation like the rest of the string's value.

The RPC fails if the server does not have a method by the indicated name, or does not want to admit that it does. But if the method name appears in the response to system.listMethods, the RPC does not fail this way.

Example result for qooxdoo.test.methodHelp('methodHelp'):

"\n This method returns a text description of a particular method.\n The method takes one parameter, a string. Its value is the name of\n the jsonrpc method about which information is being requested.\n The result is a string. The value of that string is a text description,\n for human use, of the method in question.\n @param string $method The name of the method\n @return string The documentation text of the method.\n"

Implementations

RpcPhp

In the RpcPhp server (>=1.1.0), introspection is added to a service class by extending the ServiceIntrospection class (which is automatically included by the server):

class class_test extends ServiceIntrospection
{
  ..
}

Alternatively, if subclassing ServiceIntrospection is not an option, you can achieve the same result by implementing methods that forward to the API methods like so:

function method_methodSignature( $method ) 
{ 
   $s = new ServiceIntrospection( $this );
   return $s->method_methodSignature( $method ); 
} 

Thus, you have full control over whether to allow introspection or not.

API documentation for methodSignature

In order for the methodSignature to return anything useful, you must document your code according to the PhpDoc "standard".

A known problem with PHP is that you cannot easily differentiate associative arrays (i.e. Maps/Objects in Javascript) from 'normal' arrays. This means that a type "array" in the methodSignature response does not really tell you much about whether an object or an array is supposed to be sent/returned. You need to see the additional API documentation using the methodHelp method.

RpcPython

In Python you simply extend your service class from the qxjsonrpc.server.ServiceIntrospection class in order to have introspection available.

from qxjsonrpc import public, fail
from qxjsonrpc.server import JsonRpcService, ServiceIntrospection
 
class Test(JsonRpcService,ServiceIntrospection):
   ...

API documentation for methodSignature

The following specification has not yet been implmenented in RpcPython, but will be soon.

In order for the methodSignature to return anything useful, you must document your code according to the Pythondoc standard. See the information on Module Documentation Techniques in the qooxdoo wiki.