Last active 1754317692

qwen3-coder:30b.md Raw

Here's a complete CRUD REST API implementation using Node.js, Express, MongoDB, and JWT authentication:

// 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:

npm install express mongoose bcryptjs jsonwebtoken cors

API Endpoints:

Authentication:

  1. Register - POST /api/register

    {
      "username": "john_doe",
      "email": "[email protected]",
      "password": "securepassword"
    }
    
  2. Login - POST /api/login

    {
      "email": "[email protected]",
      "password": "securepassword"
    }
    

Product CRUD Operations:

  1. Create Product - POST /api/products

    Authorization: Bearer <your-jwt-token>
    
  2. Get All Products - GET /api/products

    Authorization: Bearer <your-jwt-token>
    
  3. Get Product by ID - GET /api/products/:id

    Authorization: Bearer <your-jwt-token>
    
  4. Update Product - PUT /api/products/:id

    Authorization: Bearer <your-jwt-token>
    
  5. Delete Product - DELETE /api/products/:id

    Authorization: Bearer <your-jwt-token>
    

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.