OVERVIEW
This guide will show how to expose a Swagger API over WebSockets.This feature is EXPERIMENTAL and is subject to change.
See <https://github.com/jhthorsen/swagger2/blob/master/examples/websocket.pl> for a working example.
DISCLAIMER
This way of exposing Swagger over WebSockets is in no way compatible with <https://github.com/swagger-api/swagger-socket>.SYNOPSIS
Application
package MyApp;
use Mojo::Base "Mojolicious";
sub startup {
my $app = shift;
my $ws = $app->routes->websocket("/ws")->to("events#ws");
$app->plugin(Swagger2 => {
url => app->home->rel_file("api.yaml"),
ws => $ws,
});
}
In the example application class above, we create a custom route object for handling the WebSocket request. The route object $ws is then passed on to the plugin and set up with a default route variable swagger.
The reason why we create a custom websocket route is so it can be used bi-directional, instead of just dispatching to Swagger actions.
Controller
package MyApp::Controller::Events;
sub ws {
my $c = shift;
$c->on(json => sub {
my ($c, $data) = @_;
return if $c->dispatch_to_swagger($data);
});
}
In the example controller above we listen to a json event which can dispatch_to_swagger.
This method will return boolean true if the input looks like a Swagger request.
Request
The input data to the WebSocket need to be JSON and look like this:
{
"id": "some unique string",
"op": "operationId",
"params": {
"paramerName": "value"
}
}
The ``id'' is used to map the response to a unique request. This means that the ``id'' need to be generated on the client side. The uniqueness requirement is only for this WebSocket connection.
``op'' need to match an operationId in the Swagger specification.
``params'' must be an object where the keys match the parameters in the Swagger specification.
Response
{
"id": "some unique string",
"code": 200,
"body": {"any":"thing"}
}
The response contains the input ``id'', the HTTP status ``code'' and the response from the Swagger action inside ``body''.
JavaScript example
Here is an example JavaScript which can communicate over the socket:
var ws = new WebSocket("ws://example.com/ws");
ws.onopen = function () {
ws.send(JSON.stringify({
id: "42",
op: "listPets",
args: {limit: 60}
});
};
ws.onmessage = function (e) {
var data = JSON.parse(e.data);
if (data.id == "42") {
// Response from the request above, because of matching "id"
console.log(data.code, data.body);
}
};
CAVEATS
- ``x-mojo-around-action'' is ignored when issuing WebSocket requests. This may be changed in future version.
- Sharing a WebSocket route object between multiple Swagger plugins is unsupported. (The outcome is unknown)
- The protocol and implementation is subject for change. feedback <https://github.com/jhthorsen/swagger2/issues> is highly appreciated.

