A production-ready backend REST API for managing parking lots — automated slot allocation, real-time availability tracking, vehicle entry/exit workflow, duration calculation, and complete parking history.
| Layer | Technology |
|---|---|
| Runtime | Node.js |
| Framework | Express.js |
| Database | MongoDB |
| ODM | Mongoose |
| Config | dotenv |
| Dev server | nodemon |
smart-parking/
├── .env # Environment variables
├── .env.example # Template for environment setup
├── .gitignore
├── package.json
├── README.md
└── src/
├── server.js # Entry point — starts server
├── app.js # Express app, middleware, routes
├── config/
│ └── db.js # MongoDB connection
├── models/
│ ├── ParkingSlot.js # Slot schema
│ └── ParkingHistory.js # History schema
├── controllers/
│ ├── slotController.js # Slot CRUD logic
│ ├── vehicleController.js# Entry/exit logic
│ └── historyController.js# History retrieval
├── routes/
│ ├── slotRoutes.js
│ ├── vehicleRoutes.js
│ └── historyRoutes.js
├── middleware/
│ ├── logger.js # Custom request logger
│ └── errorHandler.js # 404 + global error handler
└── utils/
├── response.js # Standardized API responses
└── duration.js # Duration calculation helpers
- Node.js v18+
- MongoDB running locally or MongoDB Atlas URI
git clone https://github.com/your-username/smart-parking-api.git
cd smart-parking-apinpm installcp .env.example .envEdit .env:
PORT=3000
MONGODB_URI=mongodb://localhost:27017/smart_parking
NODE_ENV=development
# Development (auto-reload)
npm run dev
# Production
npm startServer runs at: http://localhost:3000
POST /api/slots/initialize
Body:
{ "totalSlots": 50 }Response:
{
"success": true,
"message": "Parking lot initialized with 50 slots",
"data": { "totalSlots": 50, "availableSlots": 50, "occupiedSlots": 0 }
}GET /api/slots
GET /api/slots?status=available
GET /api/slots?status=occupied
GET /api/slots/:slotNumber
DELETE /api/slots/reset
⚠️ Clears all slots AND parking history. Use for testing/demo only.
POST /api/vehicles/entry
Body:
{ "numberPlate": "MH12AB1234" }- Automatically assigns the nearest available slot (lowest slot number)
- Prevents duplicate entry
- Records entry time
Response:
{
"success": true,
"message": "Vehicle MH12AB1234 has entered. Assigned Slot #3",
"data": {
"slotNumber": 3,
"vehicleNumberPlate": "MH12AB1234",
"entryTime": "2024-06-01T10:30:00.000Z",
"recordId": "664abc..."
}
}POST /api/vehicles/exit
Body:
{ "numberPlate": "MH12AB1234" }- Releases the slot
- Calculates parking duration
- Updates history record
Response:
{
"success": true,
"message": "Vehicle MH12AB1234 has exited from Slot #3",
"data": {
"vehicleNumberPlate": "MH12AB1234",
"slotNumber": 3,
"entryTime": "2024-06-01T10:30:00.000Z",
"exitTime": "2024-06-01T12:45:00.000Z",
"durationMinutes": 135,
"durationFormatted": "2 hours 15 minutes"
}
}GET /api/vehicles
GET /api/vehicles/:numberPlate
Returns current parking status + full visit history for that vehicle.
GET /api/history
GET /api/history?status=PARKED
GET /api/history?status=EXITED
GET /api/history?plate=MH12AB1234
GET /api/history?page=1&limit=20
GET /api/history/:id
DELETE /api/history/clear
| Field | Rule |
|---|---|
totalSlots | Positive integer, max 1000 |
numberPlate | Alphanumeric + hyphens, 2–15 characters, required |
slotNumber | Positive integer, must exist in DB |
status query | Must be available or occupied |
Logs every incoming request:
[2024-06-01T10:30:00.000Z] POST /api/vehicles/entry - IP: ::1
[2024-06-01T10:30:00.000Z] POST /api/vehicles/entry → STATUS: 201
- 404 handler for undefined routes
- Global error handler with stack trace in development
{slotNumber: Number,// unique, 1-basedisOccupied: Boolean,// default: falsevehicleNumberPlate: String,// null when emptyentryTime: Date// null when empty}{vehicleNumberPlate: String,slotNumber: Number,entryTime: Date,exitTime: Date,// null until exitdurationMinutes: Number,// null until exitstatus: "PARKED"|"EXITED"}- Nearest slot allocation — always assigns lowest available slot number
- Duplicate vehicle prevention — 409 Conflict response
- Duration calculation — minutes + human-readable format
- Filter by availability —
?status=available|occupied - Search by number plate — full history + current status
- Paginated history —
?page=1&limit=20 - Standardized API responses — consistent
{ success, message, data }format - Indexed MongoDB queries — fast lookups on plate, status, entryTime
Import postman/Smart_Parking_API.postman_collection.json into Postman.
Recommended test flow:
POST /api/slots/initialize— create 10 slotsGET /api/slots— verify all availablePOST /api/vehicles/entry— park 3 vehiclesGET /api/slots?status=occupied— see occupied slotsGET /api/vehicles— view parked vehiclesPOST /api/vehicles/exit— exit one vehicleGET /api/history— view history with durationGET /api/vehicles/:plate— search by plate
- No authentication / authorization system
- No real-time sensor integration
- No automated billing/payment system
- No number plate recognition (ANPR)
- No frontend dashboard
- JWT-based Admin/User authentication
- Billing system based on parking duration
- WebSocket support for real-time slot updates
- ANPR integration for automated entry
- Live monitoring dashboard (React/Next.js)
- IoT sensor integration
MIT