The course follows a simple and structured approach, going through a few principles, one by one.
Each principle is represented by a video, that begins narrating some story (related to the concept being explained), then, the principle is re-introduced, and then a few recommendations for when to use that principle or not.
… so this is that post for modularizing apps that rely largely on socket.io events.
This is for the ones that believe on the single-reponsibility principle and don’t find an example for this when trying to fit socket.io in an app that starts demanding some structure.
tl;dr You can create socket.io middleware functions and export them from separate js files like you would export Express middleware.
Do I need structure at all ?
Something that kept happening to me over and over: I have the latest idea on a realtime feature for an app… I start by including socket.io as a module for my NodeJS app and as a library for my client side code (The usual /socket.io/socket.io.js).
…I create the functionality and when I finish implementing the new realtime feature… BAM! …I find myself inside unexplainable spaghetti code due to my own anxiety about socket.io’s simplicity and easiness of implementation.
The usual way for creating the first socket.io’s event handlers on the server one may find on every socket.io example around there makes use of the io.on(‘connection’) structure. Something like:
It works, so…. What’s wrong?
The issue I see now with examples that still show this approach on the server side is that the examples themselves don’t enforce any modular approach on the reader. And I mean, modular approaches that the NodeJS world is already used to.
What’s the issue again?
What if I’d like to have several files, defining each one a specific set of socket.io events handlers that do not depend on the main file or each other?
What if I’d also like no to clutter the main app/server file with lots of `require()` that are used on some specific event handlers and not on others?
What if I’d like to write unit tests for each file module that run independently of other tests?
Yes, BUT this approach lets us think in modularization the way Express users have come to think about. With time, patterns of file structure evolved for modularizing route handling on an Express based app.
Exported middleware structure
In this pattern, modules export a middleware function. A function that I can use() on a socket.io server instance.
Exported high-order function structure
In this kind of file structure, the app specific modules export a function that return a middleware function. This returned function is what I can use() on the socket.io server instance.
This is useful for being able to pass the module specific data from the main file. Data that will need to be evaludated by the returns middleware function.
What can be done from the bottom up to organize code?
Find a usual directory/file structure followed i.e. by other nodejs package mantainers.
Use and abuse socket.io’s middleware capabilities provided by socket.io 1.x.
Decide if you want your modules to export plain middleware or high order functions that return middlewares.
Example directory structure
This example structure is just here because I started writing this post with a patronizing tone and then evolved the other way around.
I’m happy today because I was nominated yesterday as an OSGeo chart member by mmiranda and Jeff McKenna. Two great open source geo developers and advocates from the OSGeo Foundation. I’m glad to be part of the supporting community for this foundation.
The nomination per-se is not a big deal. I won’t have too much reponsibilities, but voting chart members is one of them. And making the OSGeo community grow is a true big deal for the open source community.