specification.md 9 KB
Newer Older
Ryo33's avatar
Ryo33 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# Amorphos Protocol
Version: 0.1.0

## Introduction
Amorphos protocol is a messaging protocol for horizontally and vertically distributed web applications.
It focuses on minimum specification and higher extensibility.

## Terminology
<dl>
<dt>Host
<dd>
A <i>host</i> is a server which has unique hostname and implements Amorphos protocol.
</dd>

<dt>Service
<dd>
A <i>service</i> is a set of related functions.
They can be united on a same host and also be distributed into multiple hosts.
</dd>
</dl>

## Encoding
Amorphos uses JSON format with UTF-8 encoding.

## Host
26 27
### Amorphos Metadata
An *amorphos metadata* is a JSON data which describes an amorphos host.
Ryo33's avatar
Ryo33 committed
28 29 30 31

#### Endpoint
`https://HOSTNAME/.amorphos`

Ryo33's avatar
Ryo33 committed
32
#### JSON Format
Ryo33's avatar
Ryo33 committed
33
##### Properties
Ryo33's avatar
Ryo33 committed
34
An amorphos metadata is an object have the following properties.
Ryo33's avatar
Ryo33 committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

- **amorphos-version** semver REQUIRED 
  The version of Amorphos

- **connection-protocols** array REQUIRED
  An array of objects which have the following properties
  Same connection protocols with different versions are allowed.

  - **name** string REQUIRED
    The name of the connection protocol

  - **version** semver REQUIRED
    The version of the connection protocol

  - **parameters** object OPTIONAL
    The parameters for the connection protocol

- **service-protocols** array REQUIRED
    array of objects which have the following properties
    Same service protocols with different versions are allowed.

  - **name** string REQUIRED
    The name of the connection protocol

  - **version** semver REQUIRED
    The version of the service protocol

  - **services** array REQUIRED
    An array of services provided in the host

  - **parameters** object OPTIONAL
    The parameters for the service protocol

##### Example
```json
{
Ryo33's avatar
Ryo33 committed
71
  "amorphos-version": "1.0.0",
Ryo33's avatar
Ryo33 committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
  "connection-protocols": [
    {
      "name": "https-jwt",
      "version": "1.0.0",
      "parameters": {
        "connect-path": "/connect",
        "authenticate-path": "/authenticate"
      }
    },
    {
      "name": "phoenix-channel",
      "version": "1.0.0",
      "parameters": {
        "websocket-path": "/socket/websocket",
        "topic-template": "remotes:{{host}}"
      }
    }
  ],
  "service-protocols": [
    {
      "name": "yayaka",
      "version": "1.0.0",
      "services": ["identity", "repository", "social-graph"],
      "parameters": {
        "presentation-protocols": {
          "github-flavored-markdown": {
            "version": "1.0.0"
          }
        }
      }
    },
    {
      "name": "status",
      "version": "1.0.0",
      "services": ["monitor"]
    }
  ]
}
```

## Connection
Each host must establish a *connection* first to communicate between two different hosts and transmit packets under the connection.
Ryo33's avatar
Ryo33 committed
114
Amorphos does not specify the details of how to do that and each connection protocols do.
Ryo33's avatar
Ryo33 committed
115

Ryo33's avatar
Ryo33 committed
116
### Creating a Connection
Ryo33's avatar
Ryo33 committed
117
To create a connection between two hosts, any common connection protocol which is specified in the each host information can be used.
Ryo33's avatar
Ryo33 committed
118
Hosts can ignore connections which are not specified in their host informations.
Ryo33's avatar
Ryo33 committed
119

Ryo33's avatar
Ryo33 committed
120
### Sender Validation
Ryo33's avatar
Ryo33 committed
121 122 123 124 125 126
The connection layer MUST validate the sender property of a message by checking the host.

## Packet
A *packet* is a JSON data transferred between two different hosts under a connection.
It includes any number of messages.

Ryo33's avatar
Ryo33 committed
127
### JSON Format
Ryo33's avatar
Ryo33 committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
#### Properties
A packet is an object have the following property
and SHOULD NOT have all other properties.

- **messages** array REQUIRED
  An array of messages

- SHOULD NOT all other properties

#### Example
```json
{
  "messages": [
    {
      "id": "0123456789",
      "host": "host2.example.com",
      "protocol": "example",
      "service": "repository",
      "action": "post example",
      "payload": {
        "text": "example text"
Ryo33's avatar
Ryo33 committed
149 150 151 152
      },
      "sender-host": "host1.example.com",
      "sender-protocol": "example",
      "sender-service": "form"
Ryo33's avatar
Ryo33 committed
153 154 155 156 157 158 159
    }
  ]
}
```

## Message

Ryo33's avatar
Ryo33 committed
160
A *message* is a JSON data transferred between two services.
Ryo33's avatar
Ryo33 committed
161 162 163
It is transferred by a packet if the two services are on different hosts.


Ryo33's avatar
Ryo33 committed
164
### Types of Messages
Ryo33's avatar
Ryo33 committed
165 166 167 168 169

There are two types of messages, request messages and answer messages.
Request messages is a basic type of messages and answer messages is a type for replying to a message.


Ryo33's avatar
Ryo33 committed
170
### Layered Message Routing
Ryo33's avatar
Ryo33 committed
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

Each request messages have the properties to routing, **host**, **protocol**, **service**, and **action**.
They are sent to proper message handlers by the following procedure.

1. A connection sends a messages to the specified **host**.
2. The **host** routes the message to the specified **protocol**.
3. The **protocol** routes the message to the specified **service**.
4. The **service** routes the message to the handler to handle the specified **action**.

Each answer messages have the properties to routing, **host**, **reply_to**.
They are sent to proper message callers by the following procedure.

1. A connection sends a messages to the specified **host**.
2. The **host** routes the message to the caller of a message which has specified "id".


### Validation

Ryo33's avatar
Ryo33 committed
189
A host MUST ignore messages which have wrong sender or destination.
Ryo33's avatar
Ryo33 committed
190 191 192

### Timeout

Ryo33's avatar
Ryo33 committed
193 194
Amorphos does not specify about timeout of messages.
It is specified in a service protocol.
Ryo33's avatar
Ryo33 committed
195 196


Ryo33's avatar
Ryo33 committed
197
### Request Messages JSON Format
Ryo33's avatar
Ryo33 committed
198 199 200 201 202
#### Properties
A request message have following properties
and SHOULD NOT all other properties

- **id** string REQUIRED
Ryo33's avatar
Ryo33 committed
203
  An ID which is unique in the sender host
Ryo33's avatar
Ryo33 committed
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

- **host** string REQUIRED
  A destination host

- **protocol** string REQUIRED
  A destination protocol

- **service** string REQUIRED
  A destination service

- **action** string REQUIRED
  A destination action

- **payload** object REQUIRED
  The body of the message

Ryo33's avatar
Ryo33 committed
220

Ryo33's avatar
Ryo33 committed
221 222 223 224 225 226 227 228 229 230
#### Example
```json
{
  "id": "0123456789",
  "host": "host2.example.com",
  "protocol": "example",
  "service": "repository",
  "action": "post example",
  "payload": {
    "text": "example text"
Ryo33's avatar
Ryo33 committed
231 232 233 234
  },
  "sender-host": "host1.example.com",
  "sender-protocol": "example",
  "sender-service": "form"
Ryo33's avatar
Ryo33 committed
235 236 237 238 239 240 241 242 243 244 245 246
}
```

### Answer Messages JSON Format
#### Properties
Difference of answer messages from request messages are they have **reply-to** property.
A answer message have following properties
and SHOULD NOT all other properties

- **reply-to** string REQUIRED
  An ID of a message to reply

Ryo33's avatar
Ryo33 committed
247 248 249
- **id** string REQUIRED
  An ID which is unique in the sender host

Ryo33's avatar
Ryo33 committed
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
- **host** string REQUIRED
  A destination host

- **protocol** string REQUIRED
  A destination service protocol

- **service** string REQUIRED
  A destination service

- **action** string REQUIRED
  A destination action

- **payload** object REQUIRED
  The body of the message

Ryo33's avatar
Ryo33 committed
265 266 267 268 269 270 271 272 273
- **sender-host** string REQUIRED
  A sender host

- **sender-protocol** string REQUIRED
  A sender protocol

- **sender-service** string REQUIRED
  A sender service

Ryo33's avatar
Ryo33 committed
274 275 276 277 278 279 280 281 282 283
#### Example
```json
{
  "id": "abcdefghij",
  "reply-to": "0123456789",
  "host": "host1.example.com",
  "protocol": "example",
  "service": "form",
  "payload": {
    "status": "ok"
Ryo33's avatar
Ryo33 committed
284 285 286 287
  },
  "sender-host": "host2.example.com",
  "sender-protocol": "example",
  "sender-service": "repository"
Ryo33's avatar
Ryo33 committed
288 289 290
}
```

Ryo33's avatar
Ryo33 committed
291
## Connection Protocol
Ryo33's avatar
Ryo33 committed
292 293 294 295 296 297
*Connection protocol* specifies how to establish a connection between two different hosts with authentication.
The namespace of connection protocols' identifiers is case-insensitive.

### Specification
A specification of connection protocol contains following descriptions:

Ryo33's avatar
Ryo33 committed
298 299 300 301 302
* REQUIRED its name
* REQUIRED its identifier
* REQUIRED its version
* REQUIRED how to establish a connection and how to transmit
* OPTIONAL parameters to configure.
Ryo33's avatar
Ryo33 committed
303 304 305 306

A identifier MUST be a lowercase [a-z] string joined by '-',
and a version MUST be a semver.

Ryo33's avatar
Ryo33 committed
307
## Service Protocol
Ryo33's avatar
Ryo33 committed
308 309 310 311 312 313 314
*Service protocol* specifies its own services and messages.
The namespace of service protocols' identifiers is case-insensitive.


### Specification
A specification of service protocol contains the following descriptions:

Ryo33's avatar
Ryo33 committed
315 316 317 318 319 320 321
* REQUIRED its name
* REQUIRED its identifier
* REQUIRED its version
* REQUIRED list of services
* REQUIRED list of actions
* REQUIRED timeout and retransmission strategy
* OPTIONAL parameters.
Ryo33's avatar
Ryo33 committed
322 323 324 325 326 327 328 329

A identifier, services, and actions MUST be a lowercase [a-z] string joined by '-',
and a version MUST be a semver.

### Subprotocols
A service protocol may have subprotocols.
Subprotocols are like extension of a service protocol.
If a service protocols has subprotocols,
330
it SHOULD have parameters with `-subprotocols` postfix or just `subprotocols` parameter.
Ryo33's avatar
Ryo33 committed
331 332
in the top level of the service protocol parameters,
and a name of a subprotocol MUST be a lowercase [a-z] string joined by '-'.
Ryo33's avatar
Ryo33 committed
333 334

#### Example
Ryo33's avatar
Ryo33 committed
335
* **content-type-subprotocols** array REQUIRED
Ryo33's avatar
Ryo33 committed
336 337 338
  An array of objects which have the following properties
  Same connection protocols with different versions are allowed.

Ryo33's avatar
Ryo33 committed
339
  * **identifier** string REQUIRED
Ryo33's avatar
Ryo33 committed
340 341
    The identifier of the subprotocol

Ryo33's avatar
Ryo33 committed
342
  * **version** semver REQUIRED
Ryo33's avatar
Ryo33 committed
343 344
    The version of the subprotocol

Ryo33's avatar
Ryo33 committed
345
  * **parameters** object OPTIONAL
Ryo33's avatar
Ryo33 committed
346 347 348 349
    The parameters for the subprotocol

### Compatibility
Each service protocol SHOULD make efforts to keep the compatibility between different versions
Ryo33's avatar
Ryo33 committed
350
because messages do not have the property to specify the version of service protocol.