Here's a complete CRUD REST API implementation using Node.js, Express, MongoDB, and JWT authentication: ```javascript // server.js const express = require('express'); const mongoose = require('mongoose'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const cors = require('cors'); const app = express(); const PORT = process.env.PORT || 5000; // Middleware app.use(cors()); app.use(express.json()); // MongoDB connection mongoose.connect('mongodb://localhost:27017/crudapi', { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => console.log('Connected to MongoDB')) .catch((err) => console.error('MongoDB connection error:', err)); // User Schema const userSchema = new mongoose.Schema({ username: { type: String, required: true, unique: true }, email: { type: String, required: true, unique: true }, password: { type: String, required: true }, }, { timestamps: true }); const User = mongoose.model('User', userSchema); // Product Schema const productSchema = new mongoose.Schema({ name: { type: String, required: true }, description: { type: String }, price: { type: Number, required: true }, category: { type: String }, }, { timestamps: true }); const Product = mongoose.model('Product', productSchema); // JWT secret const JWT_SECRET = 'your_jwt_secret_key'; // Authentication middleware const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json({ message: 'Access token required' }); } jwt.verify(token, JWT_SECRET, (err, user) => { if (err) { return res.status(403).json({ message: 'Invalid or expired token' }); } req.user = user; next(); }); }; // Register endpoint app.post('/api/register', async (req, res) => { try { const { username, email, password } = req.body; // Check if user already exists const existingUser = await User.findOne({ $or: [{ email }, { username }] }); if (existingUser) { return res.status(400).json({ message: 'User already exists' }); } // Hash password const hashedPassword = await bcrypt.hash(password, 12); // Create user const user = new User({ username, email, password: hashedPassword, }); await user.save(); res.status(201).json({ message: 'User created successfully', user: { id: user._id, username: user.username, email: user.email } }); } catch (error) { res.status(500).json({ message: 'Server error', error: error.message }); } }); // Login endpoint app.post('/api/login', async (req, res) => { try { const { email, password } = req.body; // Find user const user = await User.findOne({ email }); if (!user) { return res.status(400).json({ message: 'Invalid credentials' }); } // Check password const isPasswordValid = await bcrypt.compare(password, user.password); if (!isPasswordValid) { return res.status(400).json({ message: 'Invalid credentials' }); } // Generate JWT token const token = jwt.sign( { id: user._id, username: user.username }, JWT_SECRET, { expiresIn: '24h' } ); res.json({ message: 'Login successful', token, user: { id: user._id, username: user.username, email: user.email } }); } catch (error) { res.status(500).json({ message: 'Server error', error: error.message }); } }); // CRUD endpoints for products // Create product app.post('/api/products', authenticateToken, async (req, res) => { try { const { name, description, price, category } = req.body; const product = new Product({ name, description, price, category, }); await product.save(); res.status(201).json(product); } catch (error) { res.status(400).json({ message: 'Error creating product', error: error.message }); } }); // Get all products app.get('/api/products', authenticateToken, async (req, res) => { try { const products = await Product.find(); res.json(products); } catch (error) { res.status(500).json({ message: 'Error fetching products', error: error.message }); } }); // Get product by ID app.get('/api/products/:id', authenticateToken, async (req, res) => { try { const product = await Product.findById(req.params.id); if (!product) { return res.status(404).json({ message: 'Product not found' }); } res.json(product); } catch (error) { res.status(500).json({ message: 'Error fetching product', error: error.message }); } }); // Update product app.put('/api/products/:id', authenticateToken, async (req, res) => { try { const { name, description, price, category } = req.body; const product = await Product.findByIdAndUpdate( req.params.id, { name, description, price, category }, { new: true, runValidators: true } ); if (!product) { return res.status(404).json({ message: 'Product not found' }); } res.json(product); } catch (error) { res.status(400).json({ message: 'Error updating product', error: error.message }); } }); // Delete product app.delete('/api/products/:id', authenticateToken, async (req, res) => { try { const product = await Product.findByIdAndDelete(req.params.id); if (!product) { return res.status(404).json({ message: 'Product not found' }); } res.json({ message: 'Product deleted successfully' }); } catch (error) { res.status(500).json({ message: 'Error deleting product', error: error.message }); } }); // Start server app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); ``` ### Dependencies to Install: ```bash npm install express mongoose bcryptjs jsonwebtoken cors ``` ### API Endpoints: #### Authentication: 1. **Register** - `POST /api/register` ```json { "username": "john_doe", "email": "john@example.com", "password": "securepassword" } ``` 2. **Login** - `POST /api/login` ```json { "email": "john@example.com", "password": "securepassword" } ``` #### Product CRUD Operations: 3. **Create Product** - `POST /api/products` ``` Authorization: Bearer ``` 4. **Get All Products** - `GET /api/products` ``` Authorization: Bearer ``` 5. **Get Product by ID** - `GET /api/products/:id` ``` Authorization: Bearer ``` 6. **Update Product** - `PUT /api/products/:id` ``` Authorization: Bearer ``` 7. **Delete Product** - `DELETE /api/products/:id` ``` Authorization: Bearer ``` ### Features Implemented: 1. **User Authentication** with JWT tokens 2. **Password Hashing** using bcrypt 3. **CRUD Operations** for products 4. **Input Validation** and error handling 5. **MongoDB Integration** with Mongoose 6. **CORS Support** 7. **Authentication Middleware** protecting routes ### Usage Example: 1. Register a user: `POST /api/register` 2. Login to get token: `POST /api/login` 3. Use the returned JWT token in subsequent requests as: ``` Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### Security Considerations: - Passwords are hashed with bcrypt - JWT tokens have expiration time - All routes require authentication - Input validation and error handling - MongoDB connection security This implementation provides a solid foundation for a REST API with user authentication and CRUD functionality. You can extend it by adding more validation, pagination, logging, or additional features as needed.