.. _pages/rpc_server_writer_guide#rpc_server_writer_guide: RPC Server Writer Guide *********************** Writing a new JSON-RPC server for use with qooxdoo is fairly easy. If you follow these rules, you should end up with a conformant implementation. See also the other `available qooxdoo RPC servers `__. .. _pages/rpc_server_writer_guide#json: JSON ==== With the exception of the formatting of Javascript ``Date`` objects, all communication between client and server is formated as JSON, as described and documented at http://json.org. .. _pages/rpc_server_writer_guide#date_objects: Date Objects ------------ Date objects are a problem in standard JSON encoding, because there is no "literal" syntax for a date in Javascript. In Javascript, nearly everthing can be represented in literal form: objects by ``{ ... }``; arrays by ``[ ... ]``; etc. The only native type which can not be represented as a literal is a Date. For this reason, a format for passing Dates in JSON is defined here so that all conforming servers can parse the data received from clients. Date objects are sent as the following 'tokens'. * The string ``new Date(Date.UTC(`` * The **year**, integer, e.g. ``2006`` * A comma * The **month**, 0-relative integer, e.g. ``5`` is June * A comma * The **day** of the month, integer, range: ``1-31`` * A comma * The **hour** of the day on a 24-hour clock, integer, range: ``0-23`` * A comma * The **minute** of the hour, integer, range: ``0-59`` * A comma * The **second** within the minute, integer, range: ``0-59`` * A comma * The **milliseconds** within the second, integer, range: ``0-999`` * The string ``))`` A resulting Date representation might therefore be: :: new Date(Date.UTC(2006,5,20,22,18,42,223)) .. _pages/rpc_server_writer_guide#whitespace: Whitespace ^^^^^^^^^^ * when generating these date strings, implementations SHOULD NOT add white space before/after/between any of the fields within the date string * when parsing these date strings, implementations SHOULD allow white space before/after/between any of the fields within the date string .. _pages/rpc_server_writer_guide#numbers: Numbers ^^^^^^^ * when generating these date strings, implementations MUST NOT add leading zeros to the numeric values in the date string. Doing so will cause them to be parsed as octal values. Numbers MUST be passed in decimal (base 10) notation without leading zeros. * when parsing these date strings, implementations MUST take the integer value of numeric portions of the string as base 10 values, even if leading zeros appear in the string representation of the numbers.. Within the JSON protocol and in JSON messages between peers, ``Date`` objects are always passed as UTC. .. _pages/rpc_server_writer_guide#rpc: RPC === Remote procedure calls are issued using JSON seralization. The basis for the objects used to send requests and responses are described and defined at http://json-rpc.org, specifically http://json-rpc.org/wiki/specification. This document introduces a number of differences to that specification, based on real-life implementation discoveries and needs. This portion of this document is an edited version of the JSON-RPC specification. .. _pages/rpc_server_writer_guide#request_method_invocation: request (method invocation) --------------------------- A remote method is invoked by sending a request to a remote service. The request is a single object serialized using JSON. It has four properties: * ``service`` - A String containing the name of the service. The server may use this to locate a set of related methods, all contained within the specified service. The format of the supported service strings is up to the server implementation. * ``method`` - A String containing the name of the method to be invoked. The method must exist within the specified service. The format of the method string is up to the server implementation. * ``params`` - An Array of objects to pass as arguments to the method. * ``id`` - The request id. This can be of any type. It is used to match the response with the request that it is replying to. (qooxdoo always sends an integer value for id.) .. _pages/rpc_server_writer_guide#response: response -------- When the method invocation completes, the service must reply with a response. The response is a single object serialized using JSON. It has three properties: * ``result`` - The Object that was returned by the invoked method. This must be ``null`` in case there was an error invoking the method. * ``error`` - An :ref:`Error Object ` if there was an error invoking the method. It must be ``null`` if there was no error. Note that determination of whether an error occurred is based on this property being ``null``, not on result being ``null``. It is perfectly legal for both to be ``null``, indicating a valid result with value ``null``. * ``id`` - This must be the same id as the request it is responding to. .. _pages/rpc_server_writer_guide#the_error_object: The Error Object ================ An error object contains two properties, ``origin`` and ``code``: .. _pages/rpc_server_writer_guide#origin: origin ------ ``origin`` - An error can be originated in four locations, during the process of initiating and processing a remote procedure call. Each possible origin is assigned an integer value, assigned to this property, as follows: * ``1`` = the server can return errors to the client * ``2`` = methods invoked by the server can return errors * ``3`` = Transport (e.g. HTTP) errors can occur * ``4`` = the client determined that an error occurred, e.g. timeout A conforming server implementation MUST send value ``1`` or ``2`` and MAY NOT send any other value, for origin. A client may detect Transport or locally-ascertained errors, but a server will never return those. .. _pages/rpc_server_writer_guide#code: code ---- ``code`` - An integer error code. The value of code is hierarchically linked to origin; e.g. the same code represents different errors depending on the value of origin. One of these values of code SHALL be sent if origin = ``1``, i.e. if the server detected the error. * Error code, value ``1``: Illegal Service The service name contains illegal characters or is otherwise deemed unacceptable to the JSON-RPC server. * Error code, value ``2``: Service Not Found The requested service does not exist at the JSON-RPC server. * Error code, value ``3``: Class Not Found If the JSON-RPC server divides service methods into subsets (classes), this indicates that the specified class was not found. This is slightly more detailed than "Method Not Found", but that error would always also be legal (and true) whenever this one is returned. * Error code, value ``4``: Method Not Found The method specified in the request is not found in the requested service. * Error code, value ``5``: Parameter Mismatch If a method discovers that the parameters (arguments) provided to it do not match the requisite types for the method's parameters, it should return this error code to indicate so to the caller. * Error code, value ``6``: Permission Denied A JSON-RPC service provider can require authentication, and that authentication can be implemented such the method takes authentication parameters, or such that a method or class of methods requires prior authentication. If the caller has not properly authenticated to use the requested method, this error code is returned. If origin = ``2``, i.e. the application (invoked method) detected the error, the value of the code property is entirely by agreement between the invoking client and the and invoked method. .. _pages/rpc_server_writer_guide#message: message ------- ``message`` - A free-form textual message describing the error. .. _pages/rpc_server_writer_guide#other_errors: Other Errors ============ Errors detected by the server which indicate that the received data is not a JSON-RPC request SHOULD be simple text strings returned to the invoker, describing the error. A web browser user who accidentally hits the URL of a JSON-RPC server should receive a textual, not Error Object, response, indicating that the server is expecting a JSON-RPC request. .. _pages/rpc_server_writer_guide#transport: Transport ========= There are exactly two standard transport facilities potentially used by qooxdoo's qx.io.remote.Rpc class: * XmlHTTPRequest : The parameters of the remote procedure call are passed to the server using XmlHTTPRequest. The request will be issued using the ``POST`` method with ``Content Type: application/json``. The data provided by the client will be the JSON-serialized request object. The JSON-serialized result object MUST be returned with ``Content Type: application/json``. This transport will be used unless the request is issued as cross-domain. * Script : If the client application invokes a cross-domain request, the request will be issued by URL-encoding the request object and wrapping it in a ``