WS + API: A NodeJS Server
Designing a Node Server with Web Sockets and RESTful API
- Part 1: One Server To Rule Th…Most of Them
- Part 2: WS + API: Getting Started
- Part 3: WS + API: Enter the Index.ts
- Part 4: Interlude: Protocols
- Part 5: WS + API: Web Socket Handler
- Part 6: WS + API: Getting the Message
- Part 7: Interlude: Redis & Redis-OM
- Part 8: WS + API: Actions Speak Louder Than Code
- Part 9: From Node to Deno
Listen, I’m no bare-metal expert in the specifics of technology. I learn what I need to learn in order to get stuff done, and when you’re reading these posts in which I describe my code, you’re getting a pure look at the way I understand things. Some of it may be wrong, most of it is probably incomplete, but doing good by accident is still doing good.
If I explain anything in these posts that is vague or doesn’t go in-depth enough for your taste, good! These posts aren’t for those who could whip up these projects in their sleep. It’s for my future self when I forget what I did or why I did something, but it’s also for those who might be starting out, who might be missing on part of a greater whole, and especially for those who don’t want to get yelled at on Stack Exchange for asking questions about things they don’t understand.
A (VERY) Brief Overview
Normally we don’t have to think about traffic when using the Internet. We have networking drivers, routers, modems, and data centers that “just work” when we load a game, enter a URL into a browser, or send messages via Discord. Unfortunately, if we’re going to be building a server, we need to talk a little bit about traffic.
HTTP(S)
As you might have guessed, “HTTP” stands for something: HyperText Transfer Protocol. The web that we know originally started out as a means of pushing text; the earliest browsers had no way to display images and were entirely menu-driven through standard computer terminals like you see in movies from the 1970’s. Email had existed for decades before the web, so pushing text wasn’t new; what was new was the concept of the “hyperlink”, a way of linking in-line text from one document to another in a way that allows a user to request new content by simply selecting that linked text. In 2024, we all understand this at a visceral level, but back when I first read about what hypertext was back in college when I was studying biology, it was an amazingly novel concept!
Of course, there’s more to it than just hyperlinks, as the “P” in “HTTP” stands for “protocol” and a protocol is a pattern describing how something is handled. One benefit of the web is that it is stateless. When you make a request to a web server, the server receives your request, goes through it’s content via routing, parsers, and server-side application execution, and returns a response in the form of a string. Once it sends that response, though, that’s it: the connection between the browser and the server is severed until another request is initiated. This was OK back in the days when it was more important to send data in response to a request, but as we required more of our internet connectivity, stateless connections illuminated a whole lot of shortcomings that developers have had to work around.
WS
Another thing we’ve kind of taken for granted is how our internet-enabled apps have overcome the “one-and-done”-ness of stateless connections. As I sit here writing this, I know my browser is probably doing things in the background, like communicating with servers via plugins without my interaction. I have Discord and Mastodon up on the other screen. I have about two dozen apps in my system tray that are exchanging information with far away servers supposedly for my benefit, and while they probably don’t run on HTTP, the fact that we don’t even think about this always-on, bi-directional communication any more illustrates how ubiquitous constant connections are these days. Web sockets is one way we can achieve this kind of content communication.
This is one of those cases where I’m lacking in specific knowledge about the subject, but web sockets work at a much lower-level of communication than HTT does. Connections between a client and a server via web sockets is maintained which allows the client to continuously send data to the server. More importantly, it allows the server to send data to the client without a client request. The ramifications are hopefully obvious, as web sockets allow us to send messages to clients in response to actions taken by other clients (chat apps) or from processes initiated by the server itself (scheduled updates).
Joining Forces For Good
In all honesty, I don’t know how a lot of apps handle their communications. Web browsers use HTTP(S), of course, but these days there’s a lot of technology that may sit somewhere between HTT and WS in terms of functionality. It is possible to mimic open connections via web tech; we’ve been using Javascript timers to make requests
every few seconds for years and while it’s not a good practice, there was a time when it was all we had. There are also technologies like Microsoft’s “SignalR” which uses .NET on the server and Javascript in the browser — and possibly web sockets under the hood — to use web-code to create always-on connections. I also have no doubt there’s a lot of methods out there that I have no idea exist that other developers are keenly aware of.
The idea of a combined HTT and WS server seems like a no-brainer to me, if I’m going to be writing a sever anyway. Since switching over to React and REST I’ve had a lot of opportunities to develop using the stateless API endpoint design, and while that’s necessary, I felt like it was now just the threshold of what I could and maybe should be doing to go beyond basically what I’ve been working with — HTT — for the past 25 years. With the possibility of always-connected apps, I can keep users in the loop and provide functionality that wasn’t possible with HTT, or was only possible through hacks or extensive and expensive code additives.
Avoiding the Evil
I know that in my circles, the phrase “always connected” triggers some Pavlovian response in many people who start thinking about surveillance, unchecked advertisements slowing down page rendering, or being beholden to the issues of modern networking. Give someone a hammer and they’ll either build a house or smack someone in the head with it; it’s not the hammer’s fault, of course, but even with proper warnings we can’t control how someone will use a tool.
My plans are potentially unnecessary, but at least they’re in the service of the user experience — or so I believe. One goal is to allow users of the same app to communicate in real time about what they’re seeing on their screens. Another is to allow system administrators to keep users informed of server and network events. Collaborative tools are all the rage these days, so sending messages to clients as a result of server updates seems like a great addition to a developer’s toolbox.
I don’t care what people are looking at. I don’t care where people go on the Internet. I don’t want your passwords or your nudes. I sure as hell don’t want to install anything on your devices, and that’s the truth. As a developer, I want to know that when someone comes to me and asks if I can create something specific, that I can say “yes, I know how to do that”.