Coursework · 2025
Biscuit
A real-time messaging web app. React front end, with a Spring Boot, RabbitMQ and MySQL back end. Ran on AWS; the deployment has since been taken down.
Spring Boot · React · RabbitMQ · MySQL · AWS
Biscuit is a messaging web application built for coursework: a React front end, a Spring Boot backend, RabbitMQ handling delivery between them, and MySQL storing accounts and conversation history.
It ran on AWS while the project was active. The deployment is down now, and the source isn’t mine to publish.
How it fits together
The front end is a single-page React app talking to the Spring Boot API over JSON, with a persistent connection open for messages arriving while you have the page open. Sending and receiving are deliberately different paths: sending is a request that returns as soon as the message is durably queued, receiving is pushed to the client whenever the queue has something for it.
That split is the point. As one round trip the sender waits on the recipient, and a chat app cannot afford that.
Why a message queue
Sending a message straight from request handler to recipient works right up until the recipient is offline or a service restarts. Putting RabbitMQ in between decouples the two sides: the sender’s request completes once the message is queued, and delivery happens independently, so a slow or absent consumer doesn’t block the producer or lose the message.
That was the interesting part. Making delivery feel instant while staying durable is a different problem from the CRUD around it.
Data model
MySQL held user accounts, messages and conversation history. The schema was shaped around the read that dominates in practice, pulling a conversation’s recent history in reverse-chronological order, not around a tidy normalization of the entities. That meant indexing on conversation and timestamp together, because the query is always “the last N messages in this conversation” and never “all messages ever, sorted.”
Running it
Deployed to AWS with the application, the database and the queue as separate managed pieces rather than one box running everything, so any of them could be resized or restarted without taking the others down.