The following service supporting a busy online reservation system using NodeJS, Redis and Docker. Locking has been implemented for concurrent attempts to hold seats due to this busyness. Events have been modeled as collections of seats and are decoupled from these locks should a move to a database (SQL or noSQL) more suitable be required.
The following routes all require an x-user-id to be sent along with the requests. In practise, some authorisation & authentication controls would be needed here.
Accepts a JSON body, NUM_SEATS must be an integer between 10 & 1000.
curl --location 'localhost:3000/events' \
--header 'x-user-id: <USER_ID>' \
--header 'Content-Type: application/json' \
--data '{
"numSeats": <NUM_SEATS>
}'
For a given event list free seats, not held or reserved.
curl --location 'localhost:3000/events/8f1cbe5c-9e21-42f4-979a-ac3692b608c1/seats' \
--header 'x-user-id: <USER_ID>'
Hold a seat prior to reservation for a configurable duration.
If the seat is already held by that user, it will refresh.
The maximum number of seats a user can hold is configurable, defaulting to 3. This includes held seats that are then reserved.
curl --location --request PATCH 'localhost:3000/events/<EVENT_ID>/seats/<SEAT_ID>/hold' \
--header 'x-user-id: foo'
reserve a seat that the user currently holds
curl --location --request PATCH 'localhost:3000/events/<EVENT_ID>/seats/<SEAT_ID>/reserve' \
--header 'x-user-id: foo'
npm i && npm run build && docker compose build
docker compose up
npm t
npm run lint
npm run lint -- --fix
all can be set in docker-compose.yml
with defaults in src/config.ts
port the service will listen on
address at which redis can be reached
time window in which unresolved locks on multiple users attempting to hold the same seat will clear. Will only be relevant if the app is killed during an attempt to hold a seat
maximum duration between a user holding a seat and finalising the reservation
maximum number of seats assignable to a user. Includes holds and reservations