Here is an informal proposal for the type of a simply-typed JSON value.
key-type := number | boolean | string | enum-type key := number-value | boolean-value | string-value | enum-value opt-key := key | optional key type := key-type | object | [type] // array | (type1, type2, ..., typen) // tuple | // associative map {opt-key1: type1, opt-key2: type2, ..., opt-keyn: typen} | nullable type
The type describes a JSON object. It can be:
- One of the primitive types "number," "boolean," or "string," or it could be simply "object" for any JSON object without more refined type description.
- The array syntax is for describing an array where all items are of the same type.
- The tuple is for describing a sequence of objects of various types, even though in JSON it would be represented as an array as well.
- The associative map is a key-value mapping from a concrete value of the key to a type. This is the refined description of a complex JSON object. The concrete key values can be a number, a boolean, or a string. The key values can be optionally prefixed by "optional" to indicate that the key could be missing.
- A type with the "nullable" qualifier which indicates that the value could be null.
An interface is a collection of function calls with the signature:
typearg -> typeretthrows type1, type2, ..., typen
where typearg is the type of the function argument, typeret is the type of the return value, and the list of types after "throws" are the exception types that could be raised by the function.
What is unique about this proposal is the unified treatment of bidirectional and streaming RPC. Typically, streaming RPC is a way for the server to send data in multiple responses, asynchronously back to the client. Client can always stream data to the server by making a call to server as many times as necessary. Here the streaming RPC is generalized to the concept of a co-interface. Whenever server needs to make a part of the response available, it would invoke one of the functions in the co-interface. A co-interface is supposed to be implemented by the client for receiving calls from the server, in order to connect to the server. Hence, the complete service description consists of a server-side interface and a client-side co-interface, which is how bidirectional RPC can be made.
Update: June 1, 2012. I've decided to get rid of exception (throw) and instead use cointerface for signaling alternative continuation.
No comments:
Post a Comment