Skip to content

Services

Ignacio del Valle Alles edited this page Mar 1, 2016 · 10 revisions

The framework allows to create JSON-RPC 2.0 services over two different transports: HTTP and Websockets.

HTTP transport offers many features, like caching, safety, idempotence and binary payloads, at the cost of increasing the message sizes, and (usually) opening a new socket to the server per request.

Websocket transport, uses a single plain connection to the server per session, where only the JSON-RPC message bytes are written, making it the preferred choice for scenarios where small messages are interchanged at high frecuencies.

Actions

The following concepts are used throughout the rest of the documentation, and must be defined for a better understanding:

  • Action: An action is a class extending RpcAction. Sometimes it is used to refer to a concrete instance.
  • Service: A service is an exposed action instance (published by the framework), bound (also "mapped") to a unique identifier id;

Base classes

Business is coded in action classes extending the following framework base classes, and using JSON serializable classes as actual type arguments for the input/output type parameters (<I,O>).

Life-cycle

Services handle all requests using a single action instance (see thread-safety issues) whose life-cycle is as follows:

  1. init(): Called once on initialization. The service mappings are loaded from the configuration file, and for each mapping, an instance of the action is created and bound to the service id. Once all the services are created, each service action is initialized via this method.
  2. execute(I input): Potentially called multiple and synchronous times to serve client requests.
  3. void destroy() Called once on undeployment. The web container calls destroy() on the framework listener and this forward the notification to all the service actions, in order to allow them to release their resources, if any.

Threading issues

The framework creates a single action instance per service to serve all requests, that is, actions will run on a multi-threaded environment, so be aware that they must handle concurrent requests and be careful to synchronize access to shared resources.

Testing

Actions can be tested without additional configuration:

public static void main(String[] args) throws Exception {
    ...
    Server.test(actionInstance);
}

but need to be registered in order to be deployed as services in the application.

Dynamic input schemas

Dynamic schemas are JSON schemas with a dependsOn property.

They represent subschemas that can change depending on the value of other parts of the data and allow the creation of interactive dynamic forms and wizards depending on business rules controlled by the server.

This framework supports actions having dynamic input schemas, and provides built-in services (rpc.http.schema-provider and rpc.wskt.schema-provider) to resolves the actual schema (given an input data) of other services.

The two building blocks for creating actions with dynamic schemas are:

  • @DependentProperty annotation, used in the action input to represent that a property schema depends on the value of other properties.
  • DynamicSchemaProvider interface, to be implemented by the action input, and responsible of resolving the actual schemas of their dependent properties.

Click here to see a live example of a service using dynamic schemas.

Service registration

Services are registered by declaring Spring beans with:

  • id: Service id.
  • class: Service action class.

See component registration section for more details.

Error codes

Services can return any of the following JSON-RPC 2.0-compliant errors:

Code Meaning Description
-32700 Parse error Invalid JSON was received by the server. An error occurred on the server while parsing the JSON input
-32600 Invalid request The JSON sent is not a valid JSON-RPC request object
-32601 Method not found The method (service) does not exist / is not available
-32602 Invalid params Invalid method parameter(s). Returned when received input does not meet schema restrictions and when action execute(..) method throws an IllegalArgumentException
-32603 Internal error In an internal error occurs or action method execute(..) throws an error or unhandled unchecked exception.
-32000 Security error In case of a SecurityException thrown by action method execute(..)
-32001 Application error Error contemplated by the application logic. In case of a checked exception thrown by action method execute(..)
-32002 HTTP invalid method The request method is not allowed by target resource. In case of a GET request to an unsafe action.
-32003 Connection error Disconnected from the peer. To be used by client proxies, like the Javascript API

JEE objects

Actions can access JEE objects, (request, response, session, application) by using HttpActionContext.getInstance() or WebsocketActionContext.getInstance() as appropriate.