Skip to content
This repository has been archived by the owner on Oct 30, 2019. It is now read-only.

SwaggerSocket Protocol

Abimaran Kugathasan edited this page Aug 3, 2017 · 7 revisions

The SwaggerSocket protocol is a JSON based protocol that runs preferably on top of the WebSocket protocol, but can also be implemented using HTTP's long-polling Comet technique. The protocol workflow consists of:

1. The client sends a handshake request 
2. If the server doesn't accept the handshake, an error message will be sent back to 
   the client explaining the handshake failure.
3. If accepted, a success message will be returned containing a unique identity.
4. After a successful handshake response, the client is allowed to send requests 
   by passing back its identity augmented with N requests.

The server will asynchronously process all the requests and return responses as soon as they are available. There is no guarantee the responses will be returned in the same order as the requests were received.

The connection between the client and the server can be, at any time, closed. In that scenario, the client might re-handshake using the same 'identity', and resend its original list of requests or a subset of it. The server may decide to reprocess all requests or get the available cached responses. The client is always guaranteed to receive a response to its requests. The client may decide to drop its requests. In that case, the server must not cache previous responses but must discard them automatically.

SwaggerSocket Protocol Workflow

Initially, the client must send a handshake request. The client identity is represented by the 'identity' field. The identity field must be 0 and will be uniquely assigned by the server if the handshake succeeds. The client must reuse that identity for all subsequent requests to the server. All requests will be rejected if the server cannot validate the identity of the client.

The client is allowed to handshake and invoke a resources root path at the same time as the handshake, but it is not allowed to receive any response's body. It is recommended to only attach a request if a resource needs some initialization logic. If the handshake succeeds, the request will be delivered to the resource which maps to the 'path' value, with the headers and query string.

    {
        "handshake" : {
            "protocolVersion" : "1.0",
            "protocolName" : "SwaggerSocket",
            "identity" : "0",
            "path" : "/any_url",
            "headers" : [
                {
                    "name" : "name",
                    "value" : "value"
                }
            ],
            "queryStrings" : [
                {
                    "name" : "name",
                    "value" : "value"
                }
            ],
        }
    }

If the server accepts the handshake, a message will be returned to the client using the unique identity value. The client must cache that identity for further re-use:

    {
        "identity" : "some_unique_uuid_generated_by_the_server",
        "status" : {
            "statusCode" : "code",
            "reasonPhrase" : "phrase"
        }
    }

If the server doesn't accept the handshake, the following message will be returned (status code will be higher than 400):

On a successful handshake, the client is now allowed to send requests using its identity, augmented with an array of requests. Requests will be rooted/mapped to their associated resource using the 'path' field and the correct operation is determined using this path and other properties:

    {
        "identity" : "some_unique_uuid_generated_by_the_server",
        "requests" : [
            {
                "uuid" : 0,
                "method" : "POST",
                "path" : "/any_url/",
                "headers" : [
                    {
                        "name" : "Content-Type",
                        "value" : "text/plain"
                    }
                ],
                "queryStrings" : [
                    {
                        "name" : "foo2",
                        "value" : "bar2"
                    }
                ],
                "messageBody" : "Swagger Socket Protocol is cool"
            }
        ]
    }

In the above POST request, the content-type is set in the headers property. Alternatively, it can be directly set in the dataFormat property as in

    {
        "identity" : "some_unique_uuid_generated_by_the_server",
        "requests" : [
            {
                "uuid" : "0",
                "method" : "POST",
                "path" : "/any_url/",
                "dataFormat" : "text/plain",
                "messageBody" : "Swagger Socket Protocol is cool"
            }
        ]
    }

The server will process the set of requests and may send responses as they come, or wait for all responses to be available before sending back the final, aggregated set of responses, in the form of:

    {
        "identity" : "some_unique_uuid_generated_by_the_server",
        "responses" : [
            {
                "uuid" : "0",
                "statusCode" : "code",
                "reasonPhrase" : "phrase",
                "path" : "path",
                "headers" : [
                    {
                        "name" : "name",
                        "value" : "value"
                    }
                ],
                "messageBody" : "messageBody"
            }
        ]
    }

If the server is unable to process the request(s), and error message must be sent back to cancel the current transaction:

    "responses" : [
        {
            "uuid" : "some_unique_uuid_generated_by_the_server",
            "statusCode" : 500,
            "reasonPhrase" : "Server Error",
            "path" : "path",
            "headers" : []
        }
    ]

The client can send multiple requests and correlate the response using the request/response identity value.

Clone this wiki locally