Ext Direct Specification
Overview
Ext Direct is a platform and language agnostic remote procedure call (RPC) protocol. Ext Direct allows for seamless communication between the client side of an Ext JS application and any server platform that conforms to the specification. Ext Direct is stateless and lightweight, supporting features like API discovery, call batching, and server to client events.
Conventions
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.
Ext Direct is partially based on JSON (see http://www.json.org or RFC 4627 ), and utilizes HTML Form-based File Uploads ( RFC 1867, RFC 2388 ).
API discovery
Server MAY support publishing its API to Clients via API discovery mechanism. If API discovery is supported the Server MUST respond to HTTP GET requests at preconfigured URI, returning a document with a correct content type for the browser to interpret this document as JavaScript code.
API declaration
The Server API declaration MUST be valid JavaScript code that results in creation of a set of nested Objects assigned to a variable that can later be passed to Ext Direct initialization code in the Client application. It is RECOMMENDED that the code also conforms to stricter rules of JSON object syntax, for the benefit of non-JavaScript implementations that might try to parse the API declarations as JSON.
An example of API declaration code:
var Ext = Ext || {};
Ext.REMOTING_API = {
"id": "provider1",
"url": "ext/direct/router",
"type": "remoting",
"actions": {
"Album": [{
"name": "getAll",
"len": 0
}, {
"name": "add",
"params": ["name", "artist"],
"strict": false
}, {
"name": "delete",
"len": 1
}]
}
};
API declaration properties
The JavaScript Object of the API declaration MUST contain the following mandatory properties:
url
- The Service URI for this API.type
- MUST be eitherremoting
for Remoting API, orpolling
for Polling API.actions
- A JavaScript Object listing all Actions and Methods available for a given Remoting API. MUST be omitted in Polling API declarations.
The API declaration MAY also contain the following OPTIONAL properties:
id
- The identifier for the Remoting API Provider. This is useful when there are more than one API in use.namespace
- The Namespace for the given Remoting API.timeout
- The number of milliseconds to use as the timeout for every Method invocation in this Remoting API.
Any other properties are OPTIONAL.
Action and Method declarations
Each Action within the actions
property of the API declaration is an Array of Objects that represent Methods. Actions do not have properties in themselves. Action names MAY be nested, i.e. an Action may contain other Actions as well as Methods.
Method declaration MUST have the following properties:
name
- The name of this Method. MUST be unique within its Action.
Each Method is fully qualified by Action and Method names concatenated with dot character (.), prefixed by optional Namespace:
[Namespace.]Foo.Bar.baz
Where Foo
is outer Action name, Bar
is inner Action name, and baz
is the Method name.
Method calling conventions
Method declaration MUST have one of the following mutually exclusive properties that describe the Method’s calling convention:
len
- The number of arguments required for Ordered Methods. This number MAY be 0 for Methods that do not accept arguments.params
- An array of parameters supported by a Named Method. This array MAY be empty.formHandler
- A JavaScript Boolean value oftrue
indicates that this Method accepts Form submits.
Ordered Methods MUST always conform to their calling convention. When Remoting Method proxy function is called for an Ordered Method, it MUST be supplied with exactly the number of arguments required, in exactly the same order as required by the Method. If less than required number of arguments is passed, the Router MAY choose to return an Exception without invoking the actual Method.
Named Methods MAY use strict
property to control how the arguments will be checked and passed to the Server when a Method is called:
- When
strict
is set totrue
, only arguments with names listed in theparams
array are sent to the Server; any other arguments are discarded. This is the default behavior. - When
strict
is set tofalse
, all arguments are passed to the Server. The Router SHOULD pass all arguments to the actual Method.
The Router MAY choose to return an Exception if some of the listed parameters are missing, and omit invoking the actual Method. If the params
Array is empty and strict
property is set to false
, the Router MUST NOT perform any argument checks and MUST pass all arguments to the invoked Method.
An example of a Named Method with all optional parameters:
"actions": {
"TestAction": [{
"name": "named_no_strict",
"params": [],
"strict": false
}]
}
Call metadata
Method declaration MAY contain the optional metadata
property that defines the type of Call Metadata accepted by the Method. If the metadata
property is not present in Method declaration, the Client MUST NOT send call metadata to the Server for any invocation of that Method.
The metadata
property, if present, MUST be a JavaScript object with the following properties:
len
- The number of arguments required for by-position Call Metadata. This number MUST be greater than 0.params
- The Array of names of the supported for by-name Call Metadata. This Array MAY be empty.strict
- JavaScript Boolean value that controls how Call Metadata arguments are checked.
When present, Call Metadata arguments MUST conform to their calling convention. Call Metadata calling convention MAY be different from the main Method arguments calling convention, e.g. an Ordered Method MAY accept by-name Call Metadata, or Named Method MAY accept by-position Call Metadata.
The argument checks are performed the same way as with main Method arguments.
Some examples of Method declarations accepting Call Metadata:
"actions": {
"TestAction": [{
"name": "meta1",
"len": 0,
"metadata": {
"len": 1
}
}, {
"name": "meta2",
"len": 1,
"metadata": {
"params": ["foo", "bar"],
"strict": false
}
}, {
"name": "meta3",
"params": [],
"strict": false,
"metadata": {
"len": 3
}
}, {
"name": "meta4",
"params": ["foo", "bar"],
"metadata": {
"params": ["baz", "qux"]
}
}]
}
Polling API declaration
Declaring Polling API is OPTIONAL. If the Server implements more than one Event Provider, it is RECOMMENDED to include Polling API declarations along with Remoting API declaration in the same JavaScript document.
An example of API declaration with one Remoting API and one Polling API:
var Ext = Ext || {};
Ext.REMOTING_API = {
"id": "provider1",
"type": "remoting",
"url": "ext/direct/router",
"actions": {
"User": [{
"name": "read",
"len": 1
}, {
"name": "create",
"params": ["id", "username"]
}]
}
};
Ext.POLLING_API = {
"id": "provider2",
"type": "polling",
"url": "ext/direct/events"
};
Remoting function calls
A remoting call is represented by sending a Request object, or multiple Request objects, to a Server. Request(s) are encoded in JSON and are sent as raw payload in a HTTP POST request to the Service URI advertised as the url
in API Declaration. There MUST not be any other data present in the HTTP POST, except valid JSON document containing one or more Requests. Among HTTP headers for the POST request, there MUST be the Content-Type header with the value of “application/json”. The Client MUST use UTF-8 character encoding for the Request document.
Remoting function call requests
A Request is an Object with the following members:
type
– MUST be a string “rpc”.tid
– The transaction id for this Request. MUST be an integer number unique among the Requests in one batch.action
– The Action that the invoked Method belongs to. MUST be specified.method
– The Remoting Method that is to be invoked. MUST be specified.data
– A set of arguments to be passed to the called Remoting Method. MUST be eithernull
for Methods that accept 0 (zero) parameters, an Array for Ordered methods, or an Object for Named methods.metadata
- OPTIONAL set of meta-arguments to be made available to the called Remoting Method, if provided by the Client. If no metadata is associated with the call, this member MUST NOT be present in the Request.
A typical JSON encoded Request Object for an Ordered Method may look like this:
{"type":"rpc","tid":1,"action":"Foo","method":"bar","data":[42,"baz"]}
A typical JSON encoded Request object for a Named Method may look like this:
{"type":"rpc","tid":2,"action":"Foo","method":"qux","data":{"foo":"bar"}}
A typical JSON encoded Request object for an Ordered Method with by-name Call Metadata may look like this:
{"type":"rpc","tid":3,"action":"Foo","method":"fred","data":[0],
"metadata":{"borgle":"throbbe"}}
Remoting Requests MAY be batched, in which case the Requests MUST be sent as an Array of Request Objects with unique tid
members:
[
{"type":"rpc","tid":3,"action":"Foo","method":"frob","data":["foo"]},
{"type":"rpc","tid":4,"action":"Foo","method":"blerg","data":["qux"]}
]
The Server MUST support Request batching, and SHOULD attempt to return call invocation Results or Exceptions in the same order.
Remoting responses
A response to a Remoting call MUST contain either a Result, or an Exception for each Request. Responses are encoded in JSON and returned to the Client as raw HTTP response payload, with Content-Type header of “application/json” and character encoding of UTF-8.
If Requests were sent as a batch the Server MUST return the corresponding Responses only after all Requests were processed by the Router, and the Responses SHOULD follow the same order as the original Requests. For each Response, the corresponding tid
member of the original Request MUST be passed back unchanged by the Server.
Remoting call Result
A Result is an Object with the following members:
type
— MUST be a string “rpc”.tid
— The transaction id for this Response. MUST be the same as in the original Request.action
— The Action to which the invoked Method belongs to. MUST be the same as in the original Request.method
— The name of the invoked Remoting Method. MUST be the same as in the original Request.result
— The data returned by the Method. MUST be present in the Response object, but MAY benull
for Methods that do not return any data.
A typical JSON encoded Array of Response objects may look like this:
[
{"type":"rpc","tid":1,"action":"Foo","method":"bar","result":0},
{"type":"rpc","tid":2,"action":"Foo","method":"baz","result":null}
]
Remoting call Exception
An Exception is an Object with the following members:
type
— MUST be a string “exception”.tid
— The transaction id for this Response. MUST be the same as in the original Request.action
— The Action to which the invoked Method belongs to. MUST be the same as in the original Request.method
— The name of the invoked Remoting Method. MUST be the same as in the original Request.message
— The error message. MUST be present.where
— OPTIONAL description of where exactly the exception was raised. MAY contain stack trace, or additional information.
A typical JSON encoded Exception may look like this:
{
"type": "exception",
"tid": 3,
"action": "Foo",
"method": "frob",
"message": "Division by zero",
"where": "... stack trace here ..."
}
Remoting form submission
A remoting form invocation is represented by submitting an HTML form with HTTP POST request. The form content MUST conform to (HTML 4.01 specification)[5]. The Server MUST support both “application/x-www-form-urlencoded” and “multipart/form-data” content types for backwards compatibility. The Client MAY choose to implement only “multipart/form-data” encoding.
There MUST be only one Method invocation per submitted form. The Client MUST use form submission for each Method with Form Handler calling convention declared in Remoting API.
Remoting form requests
The form SHALL contain the following fields:
extType
- MUST be a string “rpc”.extTID
- The transaction id for this Request. MUST be an integer number unique among the Requests in one batch.extAction
- The Action that the invoked Method belongs to. MUST be specified.extMethod
- The Remoting Method that is to be invoked. MUST be specified.extUpload
- Stringified Boolean value ("true"
or"false"
) indicating that file uploads are attached to this form submission.
The form MAY contain the metadata
field if there is Call Metadata associated with the given form submission.
The form MAY contain other fields in addition to the mandatory ones listed above. These additional fields MUST be passed to the invoked Method as Named arguments.
When the form is used to upload files, encoding type MUST be “multipart/form-data”.
Remoting form responses
The Server MUST respond to the form submission with a JSON document containing a valid Response or Exception object as described in sections 4.2.1 and 4.2.2. The document MUST have content type of “application/json” and UTF-8 character encoding.
Remoting file upload responses
When the form request contained one or more file uploads, the Server MUST return a valid HTML document with correct content type for the browser to interpret this document as HTML. The document MUST have UTF-8 character encoding.
The HTML document MUST contain a valid JSON encoded Response or Exception as described in sections 4.2.1 and 4.2.2, enclosed in HTML <textarea>
tags.
An example of a file upload response may look like this:
<!DOCTYPE html>
<html>
<head>
<title>File upload response</title>
</head>
<body>
<textarea>{JSON RESPONSE HERE}</textarea>
</body>
</html>
Event polling
The Server MAY implement OPTIONAL event polling mechanism. Event polling is performed by periodically making HTTP GET requests to the Server. There MAY be more than one Event Provider per Server; in that case each Event Provider MUST have a separate Service URI.
Event poll request
An event poll request in its basic form is an HTTP GET request to the Service URI of the polled Event Provider. The Server MUST maintain a list of active Poll Handler methods for every Event Provider, and invoke each Poll Handler method every time a poll request is made. The Server MAY support passing arguments to Poll Handler methods via HTTP GET request URI but it is not required.
Event poll response
An event poll response MUST be a valid JSON document with a correct content type for the browser to interpret this document as JSON. The document MUST use UTF-8 character encoding.
The event poll response should contain an array of Event objects. This array MAY be empty if no Events are pending for the given request. The Server MUST NOT include Exception objects in the response array.
Event object
An event object MUST contain the following properties:
type
- MUST be a string “event”.name
- Event name, MUST be a string.data
- Event data, SHOULD be any valid JSON data.
An example of a typical Event object:
{
"type": "event",
"name": "progressupdate",
"data": {
"processId": 42,
"progress": 100
}
}
Terminology
Ext Direct makes use of the following terms:
- Server — A computing system that provides functions to be executed remotely by a Client.
- Client — A computing system that remotely calls Server functions and receives Results and/or Exceptions.
- Server API — Description of Server functions exposed to the Client.
- API Declaration — JavaScript chunk that encodes Server API. API declaration is usually generated dynamically by the Server and retrieved by the Client once upon startup; API declaration can also be embedded in the Client application code.
- Remoting API — The main part of the API Declaration, it enumerates Server Actions and Methods available to the Client, as well as their calling conventions, and other parameters.
- Polling API — Optional part of the API Declaration, may be used to declare the existence of Server Event Providers and their credentials.
- API Discovery URI — A preconfigured URI on the Server that the Client should dispatch HTTP GET requests to in order to retrieve the API declaration. This URI is OPTIONAL and MAY be omitted if dynamic API discovery is not used in a particular application.
- Service URI — A preconfigured URI on the Server that the Client will use to dispatch remoting requests to a Router, or polling requests to an Event Provider. Each Router or Event Provider MUST publish a Service URI that is unique to that Router or Event Provider.
- Namespace — The global object in which the nested Action objects with corresponding Remoting Method stubs will be created. OPTIONAL; if not defined in the API declaration then the default
window
object will be used. - Action — Namespace unit; a collection of Methods. Actions MAY be nested, and MAY be placed in a global Namespace. An Action can be thought of as a class exposing Methods.
- Remoting Method — A Server function that can be called remotely by the Client. A Method always belongs to an Action, and is fully qualified by combining Namespace, Action, and Method names:
[Namespace.]Action.Method
. - Remoting Method proxy — A stub JavaScript function created by the Ext Direct Client side stack in lieu of the actual Method that only exists on the Server. A separate proxy function will be created for each Method, with the parameter signature conforming to Method’s API declaration.
- Ordered Method — A Remoting Method that accepts zero or more parameters in ordered fashion, or by position (as in a list).
- Named Method — A Remoting Method that accepts parameters by name, as in associative array (hash, Object, map).
- Form Handler Method — A Remoting Method that accepts form submits. This is a legacy mechanism that can be used to upload files in browsers not conformant with XMLHttpRequest Level 2 specification.
Implementing support for Form Handlers is OPTIONAL for a Server; if such support is not provided, the Server SHALL NOT advertise Methods as using Form Handler calling convention. - Poll Handler — A Server function that is called by an Event Provider to return the list of Events to be passed on to the Client as the result of a periodic event poll.
- Call Metadata - An OPTIONAL extra set of arguments that could be passed to the Method. Metadata is related to the main arguments but is not the same and is handled separately. A common use case is passing database information such as table name for CRUD operations.
- Router — Server component that receives remoting function call requests at its Service URI, runs the actual functions, and collects Results or Exceptions to be returned to the Client.
- Event Provider — Server component that receives periodic polling requests at its Service URI, runs Poll Handler functions registered with this Event Provider, collects Events returned by the Poll Handlers, and returns the list of Events to the Client.
- Request — A Remoting Method invocation requested by the Client, passing the arguments conformant to the Method’s calling convention.
- Response — Information about the Request completion. MUST be either a Result, or an Exception.
- Result — Any data returned by a Remoting Method upon successful or unsuccessful call completion. A Result is OPTIONAL and may be omitted if the Method is not supposed to return any data.
- Exception — A fatal error, application logic error, or other unrecoverable event in the application code.
- Event — A notification that can be generated by a Poll Handler and passed to the Client. Events are useful for application status updates, progress indicators, and other predictable conditions and events.
- Batching - Combining several Requests into one packet sent to the Server, instead of sending each Request separately.