Last active 1754317692

MisterFixx revised this gist 1754317692. Go to revision

1 file changed, 296 insertions

qwen3-coder:30b.md(file created)

@@ -0,0 +1,296 @@
1 + Here's a complete CRUD REST API implementation using Node.js, Express, MongoDB, and JWT authentication:
2 +
3 + ```javascript
4 + // server.js
5 + const express = require('express');
6 + const mongoose = require('mongoose');
7 + const bcrypt = require('bcryptjs');
8 + const jwt = require('jsonwebtoken');
9 + const cors = require('cors');
10 +
11 + const app = express();
12 + const PORT = process.env.PORT || 5000;
13 +
14 + // Middleware
15 + app.use(cors());
16 + app.use(express.json());
17 +
18 + // MongoDB connection
19 + mongoose.connect('mongodb://localhost:27017/crudapi', {
20 + useNewUrlParser: true,
21 + useUnifiedTopology: true,
22 + })
23 + .then(() => console.log('Connected to MongoDB'))
24 + .catch((err) => console.error('MongoDB connection error:', err));
25 +
26 + // User Schema
27 + const userSchema = new mongoose.Schema({
28 + username: { type: String, required: true, unique: true },
29 + email: { type: String, required: true, unique: true },
30 + password: { type: String, required: true },
31 + }, { timestamps: true });
32 +
33 + const User = mongoose.model('User', userSchema);
34 +
35 + // Product Schema
36 + const productSchema = new mongoose.Schema({
37 + name: { type: String, required: true },
38 + description: { type: String },
39 + price: { type: Number, required: true },
40 + category: { type: String },
41 + }, { timestamps: true });
42 +
43 + const Product = mongoose.model('Product', productSchema);
44 +
45 + // JWT secret
46 + const JWT_SECRET = 'your_jwt_secret_key';
47 +
48 + // Authentication middleware
49 + const authenticateToken = (req, res, next) => {
50 + const authHeader = req.headers['authorization'];
51 + const token = authHeader && authHeader.split(' ')[1];
52 +
53 + if (!token) {
54 + return res.status(401).json({ message: 'Access token required' });
55 + }
56 +
57 + jwt.verify(token, JWT_SECRET, (err, user) => {
58 + if (err) {
59 + return res.status(403).json({ message: 'Invalid or expired token' });
60 + }
61 + req.user = user;
62 + next();
63 + });
64 + };
65 +
66 + // Register endpoint
67 + app.post('/api/register', async (req, res) => {
68 + try {
69 + const { username, email, password } = req.body;
70 +
71 + // Check if user already exists
72 + const existingUser = await User.findOne({
73 + $or: [{ email }, { username }]
74 + });
75 +
76 + if (existingUser) {
77 + return res.status(400).json({ message: 'User already exists' });
78 + }
79 +
80 + // Hash password
81 + const hashedPassword = await bcrypt.hash(password, 12);
82 +
83 + // Create user
84 + const user = new User({
85 + username,
86 + email,
87 + password: hashedPassword,
88 + });
89 +
90 + await user.save();
91 +
92 + res.status(201).json({
93 + message: 'User created successfully',
94 + user: { id: user._id, username: user.username, email: user.email }
95 + });
96 + } catch (error) {
97 + res.status(500).json({ message: 'Server error', error: error.message });
98 + }
99 + });
100 +
101 + // Login endpoint
102 + app.post('/api/login', async (req, res) => {
103 + try {
104 + const { email, password } = req.body;
105 +
106 + // Find user
107 + const user = await User.findOne({ email });
108 + if (!user) {
109 + return res.status(400).json({ message: 'Invalid credentials' });
110 + }
111 +
112 + // Check password
113 + const isPasswordValid = await bcrypt.compare(password, user.password);
114 + if (!isPasswordValid) {
115 + return res.status(400).json({ message: 'Invalid credentials' });
116 + }
117 +
118 + // Generate JWT token
119 + const token = jwt.sign(
120 + { id: user._id, username: user.username },
121 + JWT_SECRET,
122 + { expiresIn: '24h' }
123 + );
124 +
125 + res.json({
126 + message: 'Login successful',
127 + token,
128 + user: { id: user._id, username: user.username, email: user.email }
129 + });
130 + } catch (error) {
131 + res.status(500).json({ message: 'Server error', error: error.message });
132 + }
133 + });
134 +
135 + // CRUD endpoints for products
136 +
137 + // Create product
138 + app.post('/api/products', authenticateToken, async (req, res) => {
139 + try {
140 + const { name, description, price, category } = req.body;
141 +
142 + const product = new Product({
143 + name,
144 + description,
145 + price,
146 + category,
147 + });
148 +
149 + await product.save();
150 + res.status(201).json(product);
151 + } catch (error) {
152 + res.status(400).json({ message: 'Error creating product', error: error.message });
153 + }
154 + });
155 +
156 + // Get all products
157 + app.get('/api/products', authenticateToken, async (req, res) => {
158 + try {
159 + const products = await Product.find();
160 + res.json(products);
161 + } catch (error) {
162 + res.status(500).json({ message: 'Error fetching products', error: error.message });
163 + }
164 + });
165 +
166 + // Get product by ID
167 + app.get('/api/products/:id', authenticateToken, async (req, res) => {
168 + try {
169 + const product = await Product.findById(req.params.id);
170 + if (!product) {
171 + return res.status(404).json({ message: 'Product not found' });
172 + }
173 + res.json(product);
174 + } catch (error) {
175 + res.status(500).json({ message: 'Error fetching product', error: error.message });
176 + }
177 + });
178 +
179 + // Update product
180 + app.put('/api/products/:id', authenticateToken, async (req, res) => {
181 + try {
182 + const { name, description, price, category } = req.body;
183 +
184 + const product = await Product.findByIdAndUpdate(
185 + req.params.id,
186 + { name, description, price, category },
187 + { new: true, runValidators: true }
188 + );
189 +
190 + if (!product) {
191 + return res.status(404).json({ message: 'Product not found' });
192 + }
193 +
194 + res.json(product);
195 + } catch (error) {
196 + res.status(400).json({ message: 'Error updating product', error: error.message });
197 + }
198 + });
199 +
200 + // Delete product
201 + app.delete('/api/products/:id', authenticateToken, async (req, res) => {
202 + try {
203 + const product = await Product.findByIdAndDelete(req.params.id);
204 +
205 + if (!product) {
206 + return res.status(404).json({ message: 'Product not found' });
207 + }
208 +
209 + res.json({ message: 'Product deleted successfully' });
210 + } catch (error) {
211 + res.status(500).json({ message: 'Error deleting product', error: error.message });
212 + }
213 + });
214 +
215 + // Start server
216 + app.listen(PORT, () => {
217 + console.log(`Server running on port ${PORT}`);
218 + });
219 + ```
220 +
221 + ### Dependencies to Install:
222 + ```bash
223 + npm install express mongoose bcryptjs jsonwebtoken cors
224 + ```
225 +
226 + ### API Endpoints:
227 +
228 + #### Authentication:
229 + 1. **Register** - `POST /api/register`
230 + ```json
231 + {
232 + "username": "john_doe",
233 + "email": "[email protected]",
234 + "password": "securepassword"
235 + }
236 + ```
237 +
238 + 2. **Login** - `POST /api/login`
239 + ```json
240 + {
241 + "email": "[email protected]",
242 + "password": "securepassword"
243 + }
244 + ```
245 +
246 + #### Product CRUD Operations:
247 + 3. **Create Product** - `POST /api/products`
248 + ```
249 + Authorization: Bearer <your-jwt-token>
250 + ```
251 +
252 + 4. **Get All Products** - `GET /api/products`
253 + ```
254 + Authorization: Bearer <your-jwt-token>
255 + ```
256 +
257 + 5. **Get Product by ID** - `GET /api/products/:id`
258 + ```
259 + Authorization: Bearer <your-jwt-token>
260 + ```
261 +
262 + 6. **Update Product** - `PUT /api/products/:id`
263 + ```
264 + Authorization: Bearer <your-jwt-token>
265 + ```
266 +
267 + 7. **Delete Product** - `DELETE /api/products/:id`
268 + ```
269 + Authorization: Bearer <your-jwt-token>
270 + ```
271 +
272 + ### Features Implemented:
273 + 1. **User Authentication** with JWT tokens
274 + 2. **Password Hashing** using bcrypt
275 + 3. **CRUD Operations** for products
276 + 4. **Input Validation** and error handling
277 + 5. **MongoDB Integration** with Mongoose
278 + 6. **CORS Support**
279 + 7. **Authentication Middleware** protecting routes
280 +
281 + ### Usage Example:
282 + 1. Register a user: `POST /api/register`
283 + 2. Login to get token: `POST /api/login`
284 + 3. Use the returned JWT token in subsequent requests as:
285 + ```
286 + Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
287 + ```
288 +
289 + ### Security Considerations:
290 + - Passwords are hashed with bcrypt
291 + - JWT tokens have expiration time
292 + - All routes require authentication
293 + - Input validation and error handling
294 + - MongoDB connection security
295 +
296 + 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.
Newer Older