I built ChatAppGo for one simple reason:
to learn Go by building something that wouldn’t let me fake understanding.
REST APIs are forgiving.
Real-time systems are not.
This project was intentionally designed to combine Go + REST APIs + Socket.IO, knowing full well that things would break — and they did, repeatedly.
Why a Chat App Was the Wrong (and Right) Choice
A chat app looks simple until you actually build one.
Suddenly you’re dealing with:
REST being stateless
sockets being stateful
users connecting, disconnecting, reconnecting
messages arriving out of order
events reaching the wrong client
logic that works locally but fails under real timing conditions
That friction was exactly what I wanted.
Problems That Forced Real Learning
🔐 JWT + Socket.IO Authentication
JWT is trivial with REST.
Sockets don’t have headers in the same way.
Getting authentication right during the Socket.IO handshake was one of the first wake-up calls.
A small mistake meant:
unauthenticated users staying connected
valid users getting dropped
security assumptions silently failing
This forced me to actually understand how Socket.IO establishes connections — not just use it.
🔄 Event Ordering & Message Sequencing
One of the most painful lessons:
Sending events in order does not guarantee clients receive them in order.
I ran into issues where:
announcement events arrived after game or chat actions
certain users received later events before earlier ones
concurrency made bugs non-deterministic
This wasn’t a bug in Go or Socket.IO — it was a design mistake.
Ordering has to be enforced explicitly.
That realization alone changed how I think about real-time systems.
🧵 Concurrency Isn’t Magic
Go makes concurrency easy — maybe too easy.
Goroutines handled multiple socket events beautifully, until shared state started behaving strangely.
Race conditions didn’t show up consistently. They showed up occasionally, which is worse.
This forced me to slow down and ask:
Who owns this data at this moment?
That question matters far beyond this project.
🗄️ Multiple Databases, Multiple Headaches
Using MongoDB for users and MySQL for messages was intentional — and educational.
It exposed:
consistency challenges
debugging across systems
assumptions about data shape
subtle bugs caused by mismatched schemas and timing
Nothing breaks confidence like “the data exists… just not where you expected it.”
What This Project Actually Taught Me
Real-time systems amplify small design mistakes
Logs are not optional — they’re survival tools
Go rewards clarity and punishes assumptions
If you don’t control event flow, it will control you
Learning happens fastest where things feel uncomfortable
Final Thought
ChatAppGo isn’t polished.
It isn’t production-ready.
And that’s exactly why it worked as a learning project.
It forced me to confront real problems instead of tutorial-safe ones.
If you’re learning Go — don’t stop at syntax.
Build something that breaks in confusing ways.
That’s where the real learning begins.
