I've spent the last year working on an e-commerce project that esclusively uses websocket for real-time updates and communication. There are some great benefits to it, but websockets also introduce a lot of technical challenges that may not be obvious when you start. Things that come to mind are:
- Persistent connections make horizontal scaling more difficult
- Web Application Firewall don't usually support payload scanning for threats over websocket messages (eg. Cloudflare)
- If you need to integrate with third parties, you may end up needing a standard REST API anyway, since it's a lot less common to integrate via websockets (especially server-side). You then end up with two APIs. Also, websockets have less standard tooling for automatic documentation purposes such as Swagger/OpenAPI
- It's harder to load test the system, difficult to estimate the breaking point of the infrastructure via websockets
- HTTP Status Codes provide a standard error mechanism to HTTP server calls, while with websockets it's entirely up to you (which can be a good and bad thing)
- You need to manage explicitly situations where the connection drops and what to do when it recovers, as you may have lost some data in the meantime
- You give up a lot of standard mature tooling for caching and rate limiting
The need to support third parties is exactly why we ended up embarking on a phased deprecation of our websocket implementation.
As it turned out barely anybody wanted to learn how to open a websocket connection and relearn all the oddities of a bespoke websocket connection (error handling, etc.) whereas with REST all these things are just more or less standardized.
Using the Actor Model provided by Akka and an event sourced architecture does not fit very well with the request-response model of HTTP. Commands are usually issued in a fire-and-forget pattern, with resulting events being pushed to the client in a completely asynchronous way.
By using websockets via SignalR, we can better accomodate this pattern on the client code as well. On top of being a better fit with our backend architecture, it also provides some benefits in the frontend such as:
- Limited availability items disappear as soon as they actually are not available anymore, without the client having to refresh
- We can integrate more easily with payment gateways where payment confirmation usually arrives via a server side webhook. We can then easily push the "payment succeeeded" event to the client as soon as we receive it, without polling.
- Even the backoffice benefits from real-time, as all backoffice users are guaranteed that when they look up a customer/orders/products, they are looking at the most up-to-date information, even if somebody else edits the same record at the same time, or the record is updated by external APIs/scheduled job.
- We can provide easily real-time dashboboards that are listening to the feed of events being persisted
- Persistent connections make horizontal scaling more difficult
- Web Application Firewall don't usually support payload scanning for threats over websocket messages (eg. Cloudflare)
- If you need to integrate with third parties, you may end up needing a standard REST API anyway, since it's a lot less common to integrate via websockets (especially server-side). You then end up with two APIs. Also, websockets have less standard tooling for automatic documentation purposes such as Swagger/OpenAPI
- It's harder to load test the system, difficult to estimate the breaking point of the infrastructure via websockets
- HTTP Status Codes provide a standard error mechanism to HTTP server calls, while with websockets it's entirely up to you (which can be a good and bad thing)
- You need to manage explicitly situations where the connection drops and what to do when it recovers, as you may have lost some data in the meantime
- You give up a lot of standard mature tooling for caching and rate limiting