Restaurant Ordering System

Spring Boot REST API · team of 5, 2023

Overview

For my university capstone, five of us built a full restaurant wait-management system, the kind of thing you'd actually use at a table. Customers browse the menu, place and customize orders and track their status; kitchen staff see a live queue of what to cook; wait staff get pinged when food's ready to serve, handle assistance requests and process payments; and managers edit the menu, reorder categories and read their ratings.

Under the hood it's a three-layer setup: a React + TypeScript front end built with Material UI, a Spring Boot REST API in Java 11, and an SQLite database over JDBC. I worked on the backend, with the schema designed for extensibility across orders, logins and menu items. Orders move through an explicit status lifecycle (Preparing → Ready to be Served → Served) driven by the kitchen and wait staff endpoints, with payment (online or cash) closing the order out.

Design decisions

Polling over WebSockets for notifications. Wait staff need to know when a customer wants help or an order's ready to serve. We weighed WebSockets against plain old polling and went with polling. These notifications don't need to be instant, and a 3–5 second delay is fine for the use case. The kitchen's order queue polls every 5 seconds; realistically, no restaurant is getting orders faster than that. A notified flag on each assistance request makes sure it only fires one notification.

Simplifying item customizations. Our first design stored customizations in their own table, linked to menu items and then to ordered items. Very proper, very relational, and it made adding new customizations a pain for managers. We threw it out for a free-text customization string on each ordered item. Less control, way more flexible, and honestly closer to how kitchens actually read order tickets anyway.

Cheap queries over convenient ones. The customer menu endpoint returns every item grouped into its category using a single SQL query, because it turned out opening connections and firing repeated queries was the expensive part of each request.

Estimating queue wait times. The virtual queue quotes customers a wait estimate using fallbacks in decreasing priority: the wait time of the most recent party of the same size; otherwise the most recent party of any size; otherwise a cold-start formula (2 min + 1.5 min per party ahead). Once the first real party is seated, estimates are grounded in observed waits instead of the formula. Table-ready notifications go out as HTML emails templated with Thymeleaf.

What I'd build differently now

Honestly? I wouldn't use Java. Looking back, the backend was essentially a microservice with minimal logic, mostly running SQL queries and shipping the results to the front end, and Java with Spring Boot was overkill for that. All the ceremony bought us complexity we never cashed in on. For a system shaped like this one, Python (or really any lighter-weight language) would have been the better call: easier to maintain, more flexible, and a lot less code between an HTTP request and the query it exists to run.

← Back to all projects