HTTP and Websockets: Understanding the capabilities of today’s web communication technologies
Deciding what to choose for your next web API design
There are so many classifications for APIs. But when it comes to web communication, we can identify two significant API types — Web Service APIs (e.g. SOAP, JSON-RPC, XML-RPC, REST) and Websocket APIs. But, what do these really mean? Let’s dive into the world of web communication protocols and discuss how to choose the best API mechanisms at the end.
HTTP is the underlying communication protocol of World Wide Web. HTTP functions as a request–response protocol in the client–server computing model. HTTP/1.1 is the most common version of HTTP used in modern web browsers and servers. In comparison to early versions of HTTP, this version could implement critical performance optimizations and feature enhancements such as persistent and pipelined connections, chunked transfers, new header fields in request/response body etc. Among them, the following two headers are very notable, because most of the modern improvements to HTTP rely on these two headers.
Keep-Aliveheader to set policies for long-lived communications between hosts (timeout period and maximum request count to handle per connection)
Upgradeheader to switch the connection to an enhanced protocol mode such as HTTP/2.0 (
h2c) or Websockets (
If you are interested in knowing what these really do, I have documented all important information for you in the below article.
Understanding how HTTP works in the real worldmedium.com
The architectural style, REST (REpresentational State Transfer) is by far the most standardized way of structuring the web APIs for requests. REST is purely an architectural style based on several principles. The APIs adhering to REST principles are called RESTful APIs. REST APIs use a request/response model where every message from the server is the response to a message from the client. In general, RESTful APIs uses HTTP as its transport protocol. For such cases, lookups should use
DELETErequests should be used for mutation, creation, and deletion respectively(avoid using
GET requests for updating information).
In HTTP Polling, the client polls the server requesting new information by adhering to one of the below mechanism. Polling is used by the vast majority of applications today and most of the times goes with RESTful practices. In practice, HTTP Short Polling is very rarely used and HTTP Long Polling or Periodic Polling is always the choice.
- HTTP Short Polling: Simpler approach. A lot of requests are processed as they come to server, creating a lot of traffic (uses resources, but frees them as soon as response is sent back). Since each connection is only open for a short period of time, many connections can be time-multiplexed.
00:00:00 C-> Is the cake ready?
00:00:01 S-> No, wait.
00:00:01 C-> Is the cake ready?
00:00:02 S-> No, wait.
00:00:02 C-> Is the cake ready?
00:00:03 S-> Yeah. Have some lad.
00:00:03 C-> Is the other cake ready?
- HTTP Long Polling: One request goes to server and client is waiting for the response to come. The server holds the request open until new data is available (it’s unresolved and resources are blocked). You are notified with no delay when the server event happens. More complex and more server resources used.
12:00 00:00:00 C-> Is the cake ready?
12:00 00:00:03 S-> Yeah. Have some lad.
12:00 00:00:03 C-> Is the other cake ready?
- HTTP Periodic Polling: There’s a predefined time gap between two requests. This is an improved/managed version of polling. You can reduce server consumption by increasing time gap between two requests. But if you need to be notified with no delay when the server event happens, this is not a good option.
00:00:00 C-> Is the cake ready?
00:00:01 S-> No, wait.
00:00:03 C-> Is the cake ready?
00:00:04 S-> Yeah. Have some lad.
00:00:06 C-> Is the other cake ready?
Client makes an HTTP request, and the server trickles out a response of indefinite length (it’s like polling infinitely).HTTP streaming is performant, easy to consume and can be an alternative to websockets.
- Issue: Intermediaries can interrupt the connection (e.g. timeout, intermediaries serving other requests in round-robin manner). In such cases, it cannot guarantee the complete realtimeness.
SSE (Server Sent Events / EventSource)
- SSE connections can only push data to the browser. (communication is carried out from server to browser only, browsers can only subscribe to data updates originated by server, but cannot send any data to the server)
- Sample applications: Twitter updates, stock quotes, cricket scores, notifications to browser
- Issue #1: Some browsers don’t support SSE.
- Issue #2: Maximum number of open connections is limited to 6.
HTTP/2 Server Push
- A mechanism for a server to proactively push assets (stylesheets, scripts, media) to the client cache in advance
- Sample applications: Social media feeds, single page apps
- Issue #1: Intermediaries (proxies, routers, hosts) can choose not to properly push information to client as intended by the origin server.
- Issue #2: Connections aren’t kept open indefinitely. A connection can be closed anytime even when the content pushing process happens. Once closed and opened again, these connection cannot continue from where it left.
- Issue #3: Some browsers/intermediaries don’t support Server Push.
WebSockets allow both the server and the client to push messages at any time without any relation to a previous request. One notable advantage in using websockets is, almost every browser support websockets.
WebSocket solves a few issues with HTTP:
- Bi-directional protocol — either client/server can send a message to the other party (In HTTP, the request is always initiated by client and the response is processed by server — making HTTP a uni-directional protocol)
- Full-duplex communication — client and server can talk to each other independently at the same time
- Single TCP connection — After upgrading the HTTP connection in the beginning, client and server communicate over that same TCP connection throughout the lifecycle of Websocket connection
Sample applications: IM/Chat apps, Games, Admin frontends
Although websockets are said to be supported every browser, there can be exceptions in intermediaries too:
- Unexpected behaviors in intermediaries: If your websocket connections go through proxies/firewalls, you may have noticed that such connections fail all the times. Always use Secured Websockets (WSS) to drastically reduce such failures. This case is nicely explained here: How HTML5 Web Sockets Interact With Proxy Servers and here too: WebSockets, caution required!. So take the caution and get ready to handle them by using WSS and falling back to a supportive protocol.
- Intermediaries that don’t support websockets: If for some reason the WebSocket protocol is unavailable, make sure your connection automatically fallback to a suitable long-polling option.
REST vs Websockets — Perf Test
If you do a performance test for REST and Websockets, you may find that Websockets do better when high loads are present. This does not necessarily mean that REST is inefficient. My personal opinion is, comparing REST with Websockets is like comparing apples to oranges. These two features solves two different problems and cannot be compared with a simple perf test like this:
However, you should now understand that websockets are a great choice for handling long-lived bidirectional data streaming in near real-time manner, whereas REST is great for occasional communications. Using websockets is a considerable investment, hence it is an overkill for occasional connections.
What to use for your next API?
Which technique to use depends on what makes more sense in the context of your application. Sure, you can use some tricks to simulate the behavior of one technology with the other, but it is usually preferable to use the one which fits your communication model better when used by-the-book.
✅ HTTP/1.1 vs HTTP/2: These are transport protocols. Mutiplexing capability in HTTP/2 is great, but not supported everywhere yet. In such cases, make sure falling back from HTTP/2 and HTTP/1.1 won’t create any mess in your application. For transferring data, HTTP/1.1 is still a great choice.
✅ RESTful APIs: So far, RESTful APIs are okay for web applications. But there are discussions happening on exploring better ways. An example is this concept — “Replace RESTful APIs with JSON-Pure”. I like the idea, in fact, JSON is developer-friendly and you can do wonders with it. But you know, these are developing concepts.
✅ JSON vs XML: Use JSON. It’s the trend, and so convenient to deal with too.
✅ HTTP Polling: This is old, but still a great choice for dealing with APIs. If your data is changing frequently or in real time, don’t use Short Polling, just use websockets, the better technology for real time. Always use Long and Periodic Polling appropriately (with REST principles).
✅ HTTP Streaming: This is good for applications like news/social media feeds, stock/score boards, tweets etc. But in practice, people use websockets than HTTP Streaming.
⚠ HTTP/2 Server Push is great for sending resources to client in more managed way. But all intermediaries and browsers will not support this. Make sure you gracefully handle such fallbacks.
⚠ Server-sent events are a rather new technology which isn’t yet supported by all major browsers, so it is not yet an option for a serious enterprise level web application (Yes, I agree that you can trick this technology to work).
✅ WebSockets provide a richer protocol to perform bi-directional, full-duplex communication. Having a two-way channel is more attractive for things like games, messaging apps, collaboration tools, interactive experiences (inc. micro-interactions), and for cases where you need real-time updates in both directions.
☝ Proxies and intermediaries are crazy. They will eat up your packets or timeout unexpectedly. Be aware of that, and handle it gracefully.
☝ Use secured transport protocols (HTTPS or WSS) to handle your communication. Then, intermediaries will have less impact on your connections. And it’s secure, you know.
☝ You really need not to embrace the latest technology always, especially when you create enterprise level applications. Make sure all the infrastructure is supporting the technology you use. And if the infrastructure does not support your technology/architecture, make sure it falls back to a technology that just works everywhere and everything works gracefully with reduced capabilities.