“Websocket” communication specification. Alternative (non-REST) way to communicate #523

Open
artem-korolev opened this Issue Dec 11, 2015 · 29 comments

Comments

Projects
None yet

Hi everybody,

I want share with you my own (and my friends and collegues) vision on websocket feature.

WebSocket itself is not replacement for REST of course. It's different technology. We saw already existing modules and plugins, which implement REST on top of WebSocket. But it's all about stateless (REST) communications and it is not what we are thinking of and not what we really need for specific tasks.

So the question I guess is not only about websocket, but about something that can be "alternative" for REST. Maybe "alternative" is not correct word. But something new, that can be used a little bit different. Another/additional way to communicate.

What I want to see in specification is support for stateless communications.
How it will look like in test API environment (IMHO and will be great to discuss it together to understand if its true or not):

Specify endpoint. Path is optional. It can be simple IP-address, or even existing websocket connection pool (whatever). But to simplify for the first, we can use the same like URI. You need to think of it like it happens not only in browser. It can be mobile or even something else if it exists.
When websocket connection is opened, we can send and receive messages now
Sending and receiving messages happens asynchronous and a bit different from REST. For example, in REST, when client sends GET request, then he waits for response from server for this GET request. If connection if timed out, for example, and client does not get response from the server, then client needs to resend this GET request again. But it is not true for "websocket". In websocket it can happen like that: when connection is dropped (timed out), client reopens websocket connection and receive response from the server, because server is already knows that client didn't received this response yet. It is the one of possible scenarios. Everything depends on the specific task.
So the next rule is: client can receive messages even without sending any requests. It can be some status messages, chat messages, or whatever you want.
This is full duplex connection. So it’s two way communication. Client can send messages and receive response for it. Can send messages and not wait for response (unbelievable situation, but why not). Client can wait for messages from server and not send any request to server. When it receive message from server, then it can send back to server response message.
Websocket connection is alive for the whole runtime lifecycle of the application. This is the main goal in most scenarios
We have new keyword - "message". It is not request or response. It is message. And we need also mechanism to answer with messages to some messages, if we need it, in any direction.
Next step can be examples of API source JSON/WHATEVER FORMAT. I will prepare it and share with you also.

This is how I see this new feature. Will be great to discuss it and find the way to implement it.
I am 100% ready to work on it. So my own human/developer resources are shared with you.

With best regards,
Artem

this is good article to understand the difference
https://blogs.oracle.com/PavelBucek/entry/websocket_vs_rest1

and understand that it is not really replacement of REST, but simply another technology to communicate

this is very good presentation also - https://www.youtube.com/watch?v=B-ElrhYxPQU1 - on 25 min they talk about SOAP on websocket. very interesting to investigate

Contributor

casualjim commented Dec 11, 2015

You can kind of represent it like this:
swagger-api#396

Okay. But what it gives to represent it in swagger, but without tooling? more interesting is to extend swagger specs and then extend tools. I'm 100% ready to do it. Just want to ask for help from community to show me some starting point or whatever.

Contributor

casualjim commented Dec 15, 2015

Ok but it starts with somebody making a proposal, this is my shot at that proposal. If people like it, we can agree on it being a worthwhile extension and add it to tooling.

@artem-korolev artem-korolev referenced this issue in swagger-api/swagger.io Jan 21, 2016

Closed

Wanna use swagger for websocket without REST #63

Contributor

fehguy commented Mar 1, 2016

Parent issue #586

@webron webron added the Sub Issue label Mar 1, 2016

Somebi commented Jul 4, 2016

Agree, should be added as the specification part.

+1 anyone is working on this?

Somebi commented Aug 29, 2016

Too bad that there is no news about it. Will have to write it manually like a simple html doc or something like that...

Member

darrelmiller commented Aug 29, 2016

@gioppoluca @Somebi To my knowledge, no. There are lots of other HTTP specific issues that we are working on first.

To be honest, I don't really understand why someone would want to take a specification designed for describing a HTTP API and then try and use it to describe a non-HTTP API. The existing HTTP constructs are just going to get in the way of describing the websocket payload and if extensions were made to support websocket description it would just add complexity for those people trying to describe HTTP APIs.

It would seem to make more sense, to create a new spec for websockets. Perhaps someone could fork the existing spec and create a variant designed specifically for websockets.

Contributor

casualjim commented Aug 30, 2016

why is http different from websockets?
Isn't swagger just a way to describe a contract for an API that just happens to default to the http transport?
the message is

method, path, version
headers
body

sent over tcp

I can do that with many different transports. This message format is almost a 1:1 match amqp for example.

Member

darrelmiller commented Aug 31, 2016

@casualjim HTTP isn't a transport, it is an application protocol. The HTTP methods have semantic meaning, as do the status codes and the HTTP headers. Sure, if you want to re-implement HTTP message semantics over web sockets, then you can use Open API to describe it. But then what is the point of using Web Sockets. If you try and reuse HTTP messaging then every time you try and take advantage of the benefits of Web Sockets you are going to run into unspecified areas of HTTP. Web Sockets exists in part to enable bi-directional communication which isn't supported in HTTP. Web sockets is effectively a transport and requires you to build an application protocol that will take advantage of the capabilities it enables.

WSDL was a way to describe a contract for an API that was independent of transport. OpenAPI isn't.

Contributor

casualjim commented Aug 31, 2016

Interesting, because I thought that webhooks etc all serve as the bi-di side. So squinting a bit you can get the bi-di communication flow using various http supported additions, as we can see in a number of other issues.

#770
#716
#396

Member

darrelmiller commented Aug 31, 2016

Webhooks require an explicit step where a call back URL is registered and the return call is standard request/response. It is publish/subscribe convention that has been layered on top of the HTTP semantics.

HTTP/2 push is not bi-directional, it is simply a server initiated prediction of a future request and piggybacking one response on another. Again in that issue I argued against any native Open API description of it.

SSE is very much a new application protocol that can be squeezed into HTTP using long polling.

Personally, I don't believe SSE payloads should be natively described by OpenAPI. This is consistent with the fact that in the callbacks PR there is no specification of payloads for event identification and subscription formats. I think standardization of WebHooks would be a great thing, I just think that standardization effort should be independent of the OpenAPI spec.

These are just my opinions, I'm not making any claims about OpenAPI will do in the future. I'm just saying what I think is best for the long term success of OpenAPI.

I realize that there are lots of valuable features that could be added to OpenAPI, but scope creep can be a real problem in spec design.

pouyanh commented Sep 24, 2016

+1

rberger commented Nov 18, 2016

We have a service that combines REST and Websockets. They work together and are part of a single application.

For us, if there was just a way to add a new operation, like message we could use OpenAPI to describe the main aspects of our web socket interface. It would get us at least 90% of the way there as we could describe the body of the message, its use, etc.

Member

darrelmiller commented Nov 18, 2016

@rberger What kind of information would you like to describe in an operation that you currently cannot do?

Somebi commented Dec 7, 2016

@darrelmiller Isn't websocket built on top of http? Handshake is implemented on http level if i'm not mistaken.

Contributor

fehguy commented Dec 7, 2016

Only the negotiation

Somebi commented Dec 7, 2016

We cannot create one json document where http and websocket will be described. Have to generate http spec separately and then modify and fill it already at UI/docs stage... Would be nice if docs generate one spec for http and websocket.

Agree with @Somebi, it would be useful feature. My projects on Spring framework, usually, have two endpoints for the same action: one with ReqeustMapping (http) and one with MessageMapping (websockets). It would be very nice if I had both together in generated docs.

EronWright commented Oct 4, 2017

May I suggest a limited goal of supporting the WebSocket handshake interaction, which is HTTP. I'd like to specify that a certain operation initiates a websocket connection. The initial handshake can be understood as a normal REST request with additional request headers, resulting in 101 Switching Protocols. It would be nice to articulate that at a high-level way rather than in a literal way.

I see a few open issues that mention websockets, but all seem to relate to post-handshake communication.

Until someone comes up with a way to describe a bi-directional socket (STOMP, MQTT, etc., over WebSockets might not be too bad, but gets messy with custom transports and protocols) a way of permitting and handing off well formed Upgrade requests would IMO satisfy most use-cases. Message validation on the socket would just have to fall to the app level. Gateways such as Tyk and Barracuda just hand-off WebSocket connections post checking of the Upgrade so could OpenAPI do the same?

There are callbacks that were introduced in swagger spec. 3.0.

"A typical example of a callback is a subscription functionality – users subscribe to certain events of your service and receive notification when this or that event occurs."

May be that will help to describe STOMP or other endpoints.....

'callbacks' appear to be to get events on the occurrence of an API call, not a Messaging Protocol working over Socket transport.

If 'callbacks' we're a mechanism to invoke another service to validate the shape of the traffic, we'd be halfway there, but they do not appear to be. Plus they'd also ruin the performance of a socket connection by adding in request/responses.

Yes, I agree with you, callbacks were not designed to describe web socket endpoints, but with callback can be described any async call from api, (that is what STOMP does, your app subscribe on endpoint and then receive message or app sends directly messages to different endpoints). That it seems to be little bit better then nothing, doesn't it?

I need low latency, so I need WebSockets; ReST is not suitable.

Member

darrelmiller commented Jan 8, 2018

@dansiviter Have you looked at https://www.asyncapi.com/ ?

@darrelmiller That's a great shout. Some link/merge between the two would be ideal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment