Skip to content

jojoee/parking-lot-api

Repository files navigation

parking-lot-api

Travis GitHub issues GitHub license

Parking lot API problem design, an API document example is available here

Getting started

Install Docker + Docker Compose then run docker-compose up

If you want to run test, so open the new terminal then

docker exec -it ctn_parking_lot_api_alpha sh
> NODE_ENV=test npx sequelize db:create
> NODE_ENV=test npx sequelize db:migrate
> npm run validate

To access production ready container, then

docker exec -it ctn_parking_lot_api sh

Assumption

Scenario

- Scenario: free public parking
- Database: MySQL (DBMS)
- Parking lot: support multiple parking lots
  (must be ordered with `rank` property to find *nearest slot*)
- Parking lot: not support multi-level
- Parking lot: only 1 entry point for each parking lot
- Concurrent processes: support by using database transaction feature to handle processes
  (park the vehicle in the same time with different entry point)
- Size:
  - 3 vehicle sizes => small, medium, large
  - 3 slot sizes => small, medium, large
- Ticket and provided slot:
  - Customer nice enough to park in the provided/assigned slot
  - Vehicle must park at the same slot size only
    (e.g. small vehicle park at small slot, medium vehicle park at the medium slot)
  - The ticket system will find the *nearest slot*
    (slot "rank" of each parking lot must be ordered by the distance between
    slot itself and parking lot entry point)
- Pricing strategy: free
- Priority slot: none
- Goal: *fast parking* so searching nearest slot must fast

Algorithm

We create *n* stacks for caching available slot ids
(n = number of parking lot * number of slot size)

When we park a car then
1. get stacks
2. check if each stack for specific slot size has available slot ids 
3. if there is available slot then remove the first slot from the stack

When we exit a parking lot
1. get the stack that related to our slot
2. concat *our slot* with *available stack slots* then sort it
3. update the stack with available-sorted-slots from 2)

Model

ERD

API

  • POST /parking_lot to create parking lot entity
  • POST /vehicle/park to park a vehicle
  • POST /vehicle/exit to release a vehicle slot (vehicle leave the parking slot)
  • GET /parking_lot/status to get available slots of all parking slots
  • GET /ticket?slot_size_id=1 to get ticket by slot size (which contains registration plate numbers / slot numbers)

Future improvement

  • Test: unit test
  • Test: E2E test
  • Docker: Dockerfile for development
  • Security concerns e.g. not expose id field directly from database
  • Hide 5xx error
  • Encoding e.g. encode ticket id
  • Archive strategy on ticket table that continually increase
  • Load Balancer
  • Kong API Gateway for authentication, rate-limit, etc.
  • API: pagination support
  • CI: E2E test
  • CI: deploy coverage report to the service e.g. https://codecov.io/
  • Create example of Kubernetes deployment
  • Create example of Kubernetes service
  • Distributed storage, incase the data is too big
  • Limitation: where the limit of caching table
  • Database: add index to optimize fast search
  • Example code of client side with multi-stage builds

CMD

npx sequelize db:create
npx sequelize migration:generate --name create-slot_size-table
npx sequelize migration:generate --name add-index-into-slot_size-table
npx sequelize migration:generate --name create-slot-table
npx sequelize db:seed:all
npx sequelize db:seed:undo:all
npx sequelize db:migrate
npx sequelize db:migrate:undo:all

NODE_ENV=test npx sequelize db:create
NODE_ENV=test npx sequelize db:migrate

docker build --tag parking-lot-api:1.0.0 .
docker build -f ./Dockerfile --tag parking-lot-api:1.0.0 .
docker run --name ctn_parking_lot_api parking-lot-api:1.0.0
docker exec -it ctn_parking_lot_api sh
docker exec -it ctn_mysql sh
  mysql -u root -p

docker rm ctn_parking_lot_api
docker rm ctn_mysql
docker rm -f $(docker ps -qa)
docker rmi parking-lot-api:1.0.0
docker images "parking-lot-api*" --no-trunc --format "{{.ID}}"
docker rmi $(docker images "parking-lot-api*" --no-trunc --format "{{.ID}}")
docker image prune

docker-compose up
docker-compose up --build -d

cd ./example
docker build -f ./Dockerfile --tag parking-lot-api-client:1.0.0 .
docker run -p 5008:5007 --name ctn_parking_lot_api_client parking-lot-api-client:1.0.0

curl localhost:5005
curl localhost:5006
curl localhost:5007

Reference