Routes files needed:
categories.js
orders.js
customers.js
reviews.js
products.js (was already in the lab book)
The code for the categories.js route file.
This file will contain the CRUD operations for the Category model.
Category Routes for Men's Wear E-Commerce Emporium
This code provides a complete set of CRUD operations for the Category model. Here's a breakdown of what each route does:
POST '/': Creates a new category GET '/': Retrieves all categories GET '/:id': Retrieves a single category by its ID PATCH '/:id': Updates a category DELETE '/:id': Deletes a category There's also a middleware function getCategory that fetches a category by ID. This is used in the GET, PATCH, and DELETE routes for individual categories.
To use this in your main application:
Save this code in a file named categories.js in your routes directory. In your server.js file, make sure you have these lines: javascript
Copy
const categoryRoutes = require('./routes/categories');
// ... other requires ...
app.use('/api/categories', categoryRoutes);
This will make the category routes available under the /api/categories endpoint.
For example:
To create a new category: POST to /api/categories To get all categories: GET from /api/categories To get a specific category: GET from /api/categories/:id To update a category: PATCH to /api/categories/:id To delete a category: DELETE to /api/categories/:id Remember to replace :id with the actual ID of the category when making requests.
routes / categories.js
const express = require('express');
const router = express.Router();
const Category = require('../models/category');
// Create a new category
router.post('/', async (req, res) => {
try {
const category = new Category(req.body);
await category.save();
res.status(201).json(category);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Get all categories
router.get('/', async (req, res) => {
try {
const categories = await Category.find();
res.json(categories);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Get a single category
router.get('/:id', getCategory, (req, res) => {
res.json(res.category);
});
// Update a category
router.patch('/:id', getCategory, async (req, res) => {
if (req.body.name != null) {
res.category.name = req.body.name;
}
if (req.body.description != null) {
res.category.description = req.body.description;
}
if (req.body.parentCategory != null) {
res.category.parentCategory = req.body.parentCategory;
}
try {
const updatedCategory = await res.category.save();
res.json(updatedCategory);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Delete a category
router.delete('/:id', getCategory, async (req, res) => {
try {
await res.category.remove();
res.json({ message: 'Category deleted' });
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Middleware function to get category by ID
async function getCategory(req, res, next) {
let category;
try {
category = await Category.findById(req.params.id);
if (category == null) {
return res.status(404).json({ message: 'Cannot find category' });
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
res.category = category;
next();
}
module.exports = router;
orders.js route file
This code provides a complete set of CRUD operations for the Order model, with some additional logic specific to handling orders. Here's a breakdown of what each route does:
POST '/': Creates a new order Validates that all products in the order exist Calculates the total amount and compares it with the provided total GET '/': Retrieves all orders, populating customer information GET '/:id': Retrieves a single order by its ID, populating customer and product information PATCH '/:id': Updates an order (in this case, only the status can be updated) DELETE '/:id': Deletes an order The getOrder middleware function fetches an order by ID and populates the customer and product information. This is used in the GET, PATCH, and DELETE routes for individual orders.
To use this in your main application:
Save this code in a file named orders.js in your routes directory. In your server.js file, make sure you have these lines: javascript
Copy
const orderRoutes = require('./routes/orders');
// ... other requires ...
app.use('/api/orders', orderRoutes);
This will make the order routes available under the /api/orders endpoint.
For example:
To create a new order: POST to /api/orders To get all orders: GET from /api/orders To get a specific order: GET from /api/orders/:id To update an order's status: PATCH to /api/orders/:id To delete an order: DELETE to /api/orders/:id Remember to replace :id with the actual ID of the order when making requests.
Key points to note:
The create order route includes validation to ensure all products exist and the total amount is correct. The get routes use populate() to include customer and product details, which is useful for displaying order information. The update route is currently set up to only update the order status, but you can expand this as needed. const express = require('express');
const router = express.Router();
const Order = require('../models/order');
const Product = require('../models/product');
// Create a new order
router.post('/', async (req, res) => {
try {
const order = new Order({
customer: req.body.customerId,
products: req.body.products,
totalAmount: req.body.totalAmount,
shippingAddress: req.body.shippingAddress
});
// Validate products and calculate total
let calculatedTotal = 0;
for (let item of order.products) {
const product = await Product.findById(item.product);
if (!product) {
return res.status(404).json({ message: `Product ${item.product} not found` });
}
calculatedTotal += product.price * item.quantity;
}
// Ensure the calculated total matches the provided total
if (calculatedTotal !== order.totalAmount) {
return res.status(400).json({ message: 'Total amount does not match product prices' });
}
const newOrder = await order.save();
res.status(201).json(newOrder);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Get all orders
router.get('/', async (req, res) => {
try {
const orders = await Order.find().populate('customer', 'firstName lastName email');
res.json(orders);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Get a single order
router.get('/:id', getOrder, (req, res) => {
res.json(res.order);
});
// Update an order (e.g., change status)
router.patch('/:id', getOrder, async (req, res) => {
if (req.body.status != null) {
res.order.status = req.body.status;
}
// Add other fields that can be updated here
try {
const updatedOrder = await res.order.save();
res.json(updatedOrder);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Delete an order
router.delete('/:id', getOrder, async (req, res) => {
try {
await res.order.remove();
res.json({ message: 'Order deleted' });
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Middleware function to get order by ID
async function getOrder(req, res, next) {
let order;
try {
order = await Order.findById(req.params.id).populate('customer', 'firstName lastName email').populate('products.product');
if (order == null) {
return res.status(404).json({ message: 'Cannot find order' });
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
res.order = order;
next();
}
module.exports = router;
customers.js router file
The code for the customers.js route file, which will handle CRUD operations for the Customer model in our Men's Wear E-Commerce Emporium.
Customer Routes for Men's Wear E-Commerce EmporiumClick to open code
This code provides a complete set of CRUD operations for the Customer model. Here's a breakdown of what each route does:
POST '/': Creates a new customer GET '/': Retrieves all customers (excluding their passwords) GET '/:id': Retrieves a single customer by their ID (excluding password) PATCH '/:id': Updates a customer's information DELETE '/:id': Deletes a customer The getCustomer middleware function fetches a customer by ID, excluding the password field. This is used in the GET, PATCH, and DELETE routes for individual customers.
To use this in your main application:
Save this code in a file named customers.js in your routes directory. In your server.js file, make sure you have these lines: const customerRoutes = require('./routes/customers'); // ... other requires ... app.use('/api/customers', customerRoutes); This will make the customer routes available under the /api/customers endpoint.
For example:
To create a new customer: POST to /api/customers To get all customers: GET from /api/customers To get a specific customer: GET from /api/customers/:id To update a customer: PATCH to /api/customers/:id To delete a customer: DELETE to /api/customers/:id Remember to replace :id with the actual ID of the customer when making requests.
Key points to note:
The password field is excluded when retrieving customer information to enhance security. In a real-world application, you would need to implement proper password hashing before storing it in the database. The update route allows updating various fields of the customer information. Error handling is implemented to provide meaningful responses in case of issues. const express = require('express');
const router = express.Router();
const Customer = require('../models/customer');
// Create a new customer
router.post('/', async (req, res) => {
try {
const customer = new Customer({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password, // Note: In a real application, ensure this is hashed
address: req.body.address
});
const newCustomer = await customer.save();
res.status(201).json(newCustomer);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Get all customers
router.get('/', async (req, res) => {
try {
const customers = await Customer.find().select('-password'); // Exclude password from the response
res.json(customers);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Get a single customer
router.get('/:id', getCustomer, (req, res) => {
res.json(res.customer);
});
// Update a customer
router.patch('/:id', getCustomer, async (req, res) => {
if (req.body.firstName != null) {
res.customer.firstName = req.body.firstName;
}
if (req.body.lastName != null) {
res.customer.lastName = req.body.lastName;
}
if (req.body.email != null) {
res.customer.email = req.body.email;
}
if (req.body.address != null) {
res.customer.address = req.body.address;
}
// Note: Updating password should involve hashing the new password
try {
const updatedCustomer = await res.customer.save();
res.json(updatedCustomer);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Delete a customer
router.delete('/:id', getCustomer, async (req, res) => {
try {
await res.customer.remove();
res.json({ message: 'Customer deleted' });
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Middleware function to get customer by ID
async function getCustomer(req, res, next) {
let customer;
try {
customer = await Customer.findById(req.params.id).select('-password');
if (customer == null) {
return res.status(404).json({ message: 'Cannot find customer' });
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
res.customer = customer;
next();
}
module.exports = router;
routes/reviews.js The `reviews.js` route file, which will handle CRUD operations for the Review model in our Men's Wear E-Commerce Emporium.
```javascript
const express = require('express');
const router = express.Router();
const Review = require('../models/review');
const Product = require('../models/product');
// Create a new review
router.post('/', async (req, res) => {
try {
// Check if the product exists
const product = await Product.findById(req.body.product);
if (!product) {
return res.status(404).json({ message: 'Product not found' });
}
const review = new Review({
product: req.body.product,
customer: req.body.customer,
rating: req.body.rating,
comment: req.body.comment
});
const newReview = await review.save();
res.status(201).json(newReview);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Get all reviews
router.get('/', async (req, res) => {
try {
const reviews = await Review.find()
.populate('product', 'name')
.populate('customer', 'firstName lastName');
res.json(reviews);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Get reviews for a specific product
router.get('/product/:productId', async (req, res) => {
try {
const reviews = await Review.find({ product: req.params.productId })
.populate('customer', 'firstName lastName');
res.json(reviews);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Get a single review
router.get('/:id', getReview, (req, res) => {
res.json(res.review);
});
// Update a review
router.patch('/:id', getReview, async (req, res) => {
if (req.body.rating != null) {
res.review.rating = req.body.rating;
}
if (req.body.comment != null) {
res.review.comment = req.body.comment;
}
try {
const updatedReview = await res.review.save();
res.json(updatedReview);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Delete a review
router.delete('/:id', getReview, async (req, res) => {
try {
await res.review.remove();
res.json({ message: 'Review deleted' });
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Middleware function to get review by ID
async function getReview(req, res, next) {
let review;
try {
review = await Review.findById(req.params.id)
.populate('product', 'name')
.populate('customer', 'firstName lastName');
if (review == null) {
return res.status(404).json({ message: 'Cannot find review' });
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
res.review = review;
next();
}
module.exports = router;
```
This code provides a complete set of CRUD operations for the Review model, along with an additional route to get reviews for a specific product. Here's a breakdown of what each route does:
1. POST '/': Creates a new review
- Checks if the product exists before creating the review
2. GET '/': Retrieves all reviews, populating product name and customer name
3. GET '/product/:productId': Retrieves all reviews for a specific product
4. GET '/:id': Retrieves a single review by its ID
5. PATCH '/:id': Updates a review's rating or comment
6. DELETE '/:id': Deletes a review
The `getReview` middleware function fetches a review by ID, populating the product name and customer name. This is used in the GET, PATCH, and DELETE routes for individual reviews.
To use this in your main application:
1. Save this code in a file named `reviews.js` in your `routes` directory.
2. In your `server.js` file, make sure you have these lines:
```javascript
const reviewRoutes = require('./routes/reviews');
// ... other requires ...
app.use('/api/reviews', reviewRoutes);
```
This will make the review routes available under the `/api/reviews` endpoint.
For example:
- To create a new review: POST to `/api/reviews`
- To get all reviews: GET from `/api/reviews`
- To get reviews for a specific product: GET from `/api/reviews/product/:productId`
- To get a specific review: GET from `/api/reviews/:id`
- To update a review: PATCH to `/api/reviews/:id`
- To delete a review: DELETE to `/api/reviews/:id`
Remember to replace `:id` and `:productId` with the actual IDs when making requests.
Key points to note:
1. The create review route checks if the product exists before creating a review.
2. The get all reviews route populates product and customer information for easier display.
3. There's a special route to get all reviews for a specific product, which can be useful for product detail pages.
4. The update route allows changing the rating and comment of a review.