What are the pitfalls of using Websockets in place of RESTful HTTP?
Asked Answered
N

3

98

I am currently working on a project that requires the client requesting a big job and sending it to the server. Then the server divides up the job and responds with an array of urls for the client to make a GET call on and stream back the data. I am the greenhorn on the project and I am currently using Spring websockets to improve efficiency. Instead of the clients constantly pinging the server to see if it has results ready to stream back, the websocket will now just directly contact the client hooray!

Would it be a bad idea to have websockets manage the whole process from end to end? I am using STOMP with Spring websockets, will there still be major issues with ditching REST?

Nashbar answered 28/4, 2015 at 17:21 Comment(0)
A
167

With RESTful HTTP you have a stateless request/response system where the client sends request and server returns the response.

With webSockets you have a stateful (or potentially stateful) message passing system where messages can be sent either way and sending a message has a lower overhead than with a RESTful HTTP request/response.

The two are fairly different structures with different strengths.

The primary advantages of a connected webSocket are:

  1. Two way communication. So, the server can notify the client of anything at any time. So, instead of polling a server on some regular interval to see if there is something new, a client can establish a webSocket and just listen for any messages coming from the server. From the server's point of view, when an event of interest for a client occurs, the server simply sends a message to the client. The server cannot do this with plain HTTP.

  2. Lower overhead per message. If you anticipate a lot of traffic flowing between client and server, then there's a lower overhead per message with a webSocket. This is because the TCP connection is already established and you just have to send a message on an already open socket. With an HTTP REST request, you have to first establish a TCP connection which is several back and forths between client and server. Then, you send HTTP request, receive the response and close the TCP connection. The HTTP request will necessarily include some overhead such as all cookies that are aligned with that server even if those are not relevant to the particular request. HTTP/2 (newest HTTP spec) allows for some additional efficiency in this regard if it is being used by both client and server because a single TCP connection can be used for more than just a single request/response. If you charted all the requests/responses going on at the TCP level just to make an https REST request/response, you'd be surpised how much is going on compared to just sending a message over an already established webSocket.

  3. Higher Scale in some circumstances. With lower overhead per message and no client polling to find out if something is new, this can lead to added scalability (higher number of clients a given server can serve). There are downsides to the webSocket scalability too (see below).

  4. Stateful connections. Without resorting to cookies and session IDs, you can directly store state in your program for a given connection. While a lot of development has been done with stateless connections to solve most problems, sometimes it's just simpler with stateful connections.

The primary advantages of a RESTful HTTP request/response are:

  1. Universal support. It's hard to get more universally supported than HTTP. While webSockets enjoy relatively good support now, there are still some circumstances where webSocket support isn't regularly available.

  2. Compatible with more server environments. There are server environments that don't allow long running server processes (some shared hosting situations). These environments can support HTTP request, but can't support long running webSocket connections.

  3. Higher Scale in some circumstances. The webSocket requirement for a continuously connected TCP socket adds some new scale requirements to the server infrastructure that HTTP requests don't demand. So, this ends up being a tradeoff space. If the advantages of webSockets aren't really needed or being used in a significant way, then HTTP requests might actually scale better. It definitely depends upon the specific usage profile.

  4. For a one-off request/response, a single HTTP request is more efficient than establishing a webSocket, using it and then closing it. This is because opening a webSocket starts with an HTTP request/response and then after both sides have agreed to upgrade to a webSocket connection, the actual webSocket message can be sent.

  5. Stateless. If your job is not made more complicated by having a stateless infrastruture, then a stateless world can make scaling or fail-over much easier (just add or remove server processes behind a load balancer).

  6. Automatically Cacheable. With the right server settings, http responses can be cached by browser or by proxies. There is no such built-in mechanism for requests sent via webSockets.


So, to address the way you asked the question:

What are the pitfalls of using websockets in place of RESTful HTTP?

  1. At large scale (hundreds of thousands of clients), you may have to do some special server work in order to support large numbers of simultaneously connected webSockets.

  2. All possible clients or toolsets don't support webSockets or requests made over them to the same level they support HTTP requests.

  3. Some of the less expensive server environments don't support the long running server processes required to support webSockets.

If it's important to your application to get progress notifications back to the client, you could either use a long running http connection with continuing progress being sent down or you can use a webSocket. The webSocket is likely easier. If you really only need the webSocket for the relatively short duration of this particular activity, then you may find the best overall set of tradeoffs comes by using a webSocket only for the duration of time when you need the ability to push data to the client and then using http requests for the normal request/response activities.

Asphalt answered 29/4, 2015 at 2:46 Comment(8)
Thanks for the detailed answer. I am still waiting for that magical framework that makes websockets the de facto way to build web applications. I really like what Spring is doing with Websockets. Maybe it will evolve into something big down the road.Nashbar
Why nobody mentions that REST responses are cacheable and there is no easy/automatic way to cache Websocket's result?Fradin
@metamaker - That is a reasonable point and I will add it. But webSocket connections are not usually used for request/response type of activity where caching is relevant and, in fact, http is usually the recommended choice for pure request/response.Asphalt
@Asphalt Exactly, but this is definite use case there REST shines in comparison to WebSockets.Fradin
On the support side, we are nearly at 100% for browsers: caniuse.com/#feat=websocketsCollected
Having a stateful server-side component negatively affects availability because you can't simply do load balancing to direct requests to any replica.Czar
With persistent http connections being available in http/1.1, and even doable in http/1.0 with keep alives, there is not actually an additional overhead for REST calls. If you are making repeated calls to a server and creating a new connection for each call you are doing it wrong. Current browsers all use persistent connections.Freefloating
@PatrickFarry - Yes, and it depends a lot on the frequency of your REST calls and the connection timeout for the HTTP 1.1 server and client. For example, versions of Apache http server may time out the "persistent" connection in 5-15 seconds. Browsers may timeout the connection in 1-2 minutes. So, you'd have to be doing pretty regular requests to take advantage of the persistent connections. It appears its design was more optimized for browsers that are going to be making a series of requests one after another from the same host as part of loading a web page than for long term connections.Asphalt
F
5

It really depends on your requirements. REST services can be much more transparent and easier to pick up by developer compared to Websockets.

Using Websockets, you remove most of the advantages that RESTful webservices offer, such as the ability to reference a resource via a URI. Really what you should be doing is to figure out what the advantages are of REST and hypermedia, and based on that decide whether those advantages are important to you.

It's of course entirely possible to create a RESTful webservice, and augment it with a a websocket-based API for real-time responses.

But if you are creating a service that only you are going to consume in a controlled environment, the only disadvantage might be that not every client supports websockets, while pretty much any type of environment can do a simple http call.

Filing answered 28/4, 2015 at 21:42 Comment(1)
With Spring-websockets and Spring-messaging I am able to do a /@MessageMapping to have URIs. I am also able to do a Spring-mvc /@RequestMapping call too! It seems like Spring-websockets can allow for RESTful like abstractions? This is where I get lost, probably because I am naive, but it make websocket development seem really attractive, but I don't hear much buzz about it.Nashbar
K
1

After reading the other answers, I came up with the following summary or guide:

  1. If you want to send data to the server fast, that is with little latency, like you would want in real-time messaging, then use WebSocket

  2. If the resource requested is likely to contain a change if the user requests it again a few seconds later, but you want him to be aware of that without having to manually refresh, then use WebSocket

  3. In any other case, use HTTP

Kaleb answered 5/4, 2023 at 4:47 Comment(2)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Richardricharda
I pretty much came up with the same summary, with an additional clarification being, if you need say a 500-1,000 json records, that would be something to request with REST, a websocket would be good with one record at a time. You could do the 500-1,000 with the socket but, not fun and cumbersome.Faires

© 2022 - 2024 — McMap. All rights reserved.