Protocol Overview
POSTAL is a message based protocol with structured messages encoded using
transit+json
serialization format.
Warning
|
this document is under design and is considered in pre-alpha state. |
Rationale
The tipical web application usually follows the REST API architecture, but the main problem of that is that is bound directly to the HTTP semantics that are not always coherent or not always clear how to use.
The main goal of this protocol is to put aside the REST API semantics and build own ones on top of the HTTP protocol. Allowing to build rich and powerful API’s without any restrictions of the the REST API’s.
The general idea is borrowed from Facebook Relay.
So it is an ideal protocol for building declarative data-fetching apps and using this
transport protocol for client-server
communication.
Messages
A postal message consists of a structured data serialized using transit+json
.
This is how a message looks like:
{:type :query
:dest :users
:data {:some :data}}
The previus message looks like this when it is encoded using transit+json
serialization format:
"[\"^ \",\"~:type\",\"~:query\",\"~:dest\",\"~:users\",\"~:data\",[\"^ \",\"~:some\",\"^4\"]]"
postal comes with a set of predefined types of messages with specified semantics but that doesn’t limit the user to define their own messages on top of the protocol.
Common Messages
:response
This is a generic message that represents a server response to some kind of request.
This is how a :response
message looks like:
{:type :response
:data {:id 1, :firstname "Yennefer"}}
:error
It’s a generic message that represents an error situation. This kind of messages can be sent by a server when something goes wrong.
This how an :error
message looks like:
{:type :error
:data {:message "Does not exists"}}
:message
This is a generic message that represents a server push notification and its
aspect is almost identical to the :response
but has very different semantics.
This message type can be sent by server in some kind of subscriptions using long polling HTTP requests. The transport layer for this kind of messages is explicitly undefined.
This is how this message looks like:
{:type :message
:data {:id 1, :firstname "Yennefer"}}
REQ/REP
This section will explain messages defined for request/reply pattern.
:query
This is a message that should be used for requesting data from a specified resource. It is analogous to the HTTP GET.
This is how a :query
message looks like:
{:type :query
:dest :users
:data {:id 2}}
After sending a :query
message we should expect an :response
message to be
sent back or :error
if an error has ocurred. The :dest
property is mandatory.
:novelty
This is a message that is used to submit data to be processed by a specified resource. It is analogous to the HTTP POST/PUT.
This how a :novelty
message looks like:
{:type :novelty
:dest :users
:data [[:db/add 857582744 :username "foobar"]
[:db/add 857582744 :password "secret"]]}
After sending a :novelty
message we should expect a :response
message to be
sent back or :error
if an error has ocurred. The :dest
property is mandatory.
PUSH/PULL
This section will explain messages defined for push/pull pattern. In other words it allows to implement a queue like communication.
PUT
This is a message that should be used for puting the data to the server.
This is how a :put
message looks like:
{:type :put
:dest :some-queue
:data {:id 2}}
After sending a :put
message we should expect a :response
message to be
sent back or :error
if an error has ocurred. The :dest
property is mandatory.
Note
|
the server behavior is specifically not defined. It can just not block and return a response or block the HTTP connection (without clossing it) until the message is accepted. |
TAKE
This is a message that should be used for geting the data from server.
This is how a :take
message looks like:
{:type :take
:dest :some-queue}
After sending a :take
message we should expect a :response
message to be
sent back or :error
if an error has ocurred. The :dest
property is mandatory.
Note
|
the server behavior is specifically not defined. It can just not block and return a response or block the HTTP connection (not clossing it) until the message is available. |
PUB/SUB
This section will explain messages defined for publish/subscribe pattern.
:subscribe
This is a message that should be used for notifying the server that a client wants to subscribe to a specific topic.
{:type :subscribe
:dest :user/notification
:data {:id 2}}
The behavior of the backend and the transport layer is explicitly undefined. The most basic approach is to just do a long-polling or using server sent events.
:publish
This is a message that should be used for publishing a message to a specified topic. If a client is subscribed to the topic, it will receive the published message.
{:type :publish
:dest :user/notification
:data {:foo "bar"}}
After sending a :publish
message we should expect a :response
message to be
sent back or :error
if an error has ocurred. The :dest
property is mandatory.
Recommendations
Start using HTTP2/SPDY
As this protocol is designed to work on top of HTTP, is highly recommended to deploy your application using HTTP2 or SPDY. It is not necesary that you application server supports it, most of the HTTP proxies such as Nginx aready have support for SPDY and/or HTTP2.
HTTP2/SPDY offers connection multiplexing, allowing to use a unique persistent connection to handle all required context, completly eliminating the overhead of creating and destroyng connections. With that you can make multiple and repeated HTTP connections without performance issues.
License
This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <http://unlicense.org/>