This repository is a simple Node.js/Express application that provides a RESTful API
for managing products stored in a MongoDB database. It demonstrates the use of
modern JavaScript features (ES modules), mongoose for data modeling, and basic
pagination and CRUD operations.
index.js # Application entry point
config/db.js # MongoDB connection helper
controllers/
product.controller.js # Route handlers for products
models/
product.model.js # Mongoose schema for products
routes/
product.routes.js # Express router defining API endpoints
- index.js: bootstraps the server, loads environment variables, applies
middleware (CORS and JSON body parsing), and registers the
/productsrouter. - config/db.js: connects to the database using the
MONGO_URIfrom environment. - product.model.js: defines
Productwith embeddedvariantsandreviewssub‑documents, plus virtuals and indexes for performance. - product.controller.js: contains all business logic for listing, creating, updating, deleting products, adding reviews, and updating stock.
- product.routes.js: wires controller functions to REST endpoints.
-
Install dependencies:
pnpm install
-
Create a
.envfile in the root with:PORT=3000 MONGO_URI=mongodb://localhost:27017/mydb
-
Run the server:
pnpm start # or: node index.js -
The API will be available at
http://localhost:3000.
| Method | Path | Description |
|---|---|---|
| GET | /products |
List products (paginated) |
| POST | /products |
Create a new product |
| GET | /products/:id |
Retrieve a single product by ID |
| PUT | /products/:id |
Update a product |
| DELETE | /products/:id |
Delete a product |
| POST | /products/:id/reviews |
Add a review to a product |
| PATCH | /products/:id/stock |
Update stock for a specific SKU |
POST /productsandPUT /products/:idcan includename,category,variants, andreviews.POST /products/:id/reviewsexpects a single review object in request body:{ "userId": "<ObjectId>", "rating": 1-5, "comment": "optional" }.PATCH /products/:id/stockexpects:{ "sku": "<variant_sku>", "delta": <number> }.
GET /products supports page and limit query parameters. The response
includes a pagination object with totals and current page info.
- Node.js (ES modules)
- Express.js
- MongoDB & Mongoose
- CORS & dotenv
product.model.jsdefines a virtual propertyavgRatingcalculated from embedded reviews.- Indexes on
{ category, name }and onvariants.sku(unique, sparse) help with query performance and SKU uniqueness. - Error handling in controllers returns appropriate HTTP status codes and messages.
Feel free to extend the codebase with authentication, validation, or a front‑end client!
This async helper reads MONGO_URI from the environment and uses
mongoose.connect() to establish the connection. In case the variable is
missing or the connection fails, it logs an error but does not terminate the
process. Successful connection is confirmed by a console message.
- Variant Schema: Embedded subdocument without its own
_id, containing SKU, color, price, and stock. Stock is non-negative and defaults to0. - Review Schema: Also embedded and _id-less; stores a reference to the user
(
userId), a rating between 1 and 5, and an optional comment. Timestamps are enabled so each review hascreatedAt/updatedAt. - Product Schema: Top-level document with
name,category, and arrays of variants and reviews. Timestamps are on the product level as well. - Virtuals:
avgRatingcomputes the average review score at read time and is included when converting documents to JSON/Object. - Indexes: Compound index on category+name to speed up filtered searches and
a sparse unique index on
variants.skuto enforce SKU uniqueness only when variants exist.
Each exported function corresponds to an API action:
- getProducts
- Reads
page/limitfrom query string, appliesskip/limiton theProduct.find()result sorted by creation date (newest first). - Returns both the matching documents and pagination metadata (
totalProducts,totalPages, etc.).
- Reads
- createProduct
- Constructs a new
Productfromreq.bodyand saves it. Responds with201 Createdon success.
- Constructs a new
- getProductById
- Fetches a product by its Mongo
_id; 404 if not found.
- Fetches a product by its Mongo
- updateProduct
- Uses
findByIdAndUpdatewithrunValidatorsso schema rules apply to updates. Returns the updated document.
- Uses
- deleteProduct
- Removes the document and returns confirmation plus the deleted object.
- addReview
- Pushes a new review into
reviewsarray using$push; returns the updated product with status201.
- Pushes a new review into
- updateStock
- Atomically increments (
$inc) thestockfield of a specific variant identified by SKU. Handles the case where either product or SKU is missing.
- Atomically increments (
Error handling generally catches exceptions and responds with a 500 or 400
as appropriate, including the error message for debugging.
Express router maps HTTP methods and paths to controller functions for listing, creating, reading, updating, deleting, review creation, and stock update. All routes use path parameters or JSON body payloads as required.
Loads environment variables (dotenv), creates the Express app, and configures
CORS and JSON parsing middleware. Calls connectDB() before setting up routes to
ensure the database is available. Finally, it defines a simple root endpoint and
starts listening on the PORT from the environment (default 3000).
With these details in place, the README now gives readers both high-level context and low-level understanding of how each piece works together.