create-aziz-app 2.0.11 → 2.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,538 @@
1
+ # API Routes Guide
2
+
3
+ ## Overview
4
+
5
+ API routes run on the **SERVER** (Node.js), just like Next.js! They're real backend endpoints, not client-side mocks.
6
+
7
+ ## How It Works
8
+
9
+ ```
10
+ Browser Dev Server (Node.js)
11
+ │ │
12
+ │ GET /api/users │
13
+ ├─────────────────────────────►│
14
+ │ │ Loads api/users.js
15
+ │ │ Executes handler()
16
+ │ │
17
+ │ { users: [...] } │
18
+ │◄─────────────────────────────┤
19
+ │ │
20
+ ```
21
+
22
+ ## Creating an API Route
23
+
24
+ ### File Structure
25
+
26
+ ```
27
+ api/
28
+ ├── hello.js → /api/hello
29
+ ├── users.js → /api/users
30
+ └── posts.js → /api/posts
31
+ ```
32
+
33
+ Each file in `api/` becomes an endpoint!
34
+
35
+ ### Basic Example
36
+
37
+ ```javascript
38
+ // api/hello.js
39
+
40
+ module.exports = async function handler(req, res) {
41
+ return res.status(200).json({
42
+ message: 'Hello from the server!'
43
+ });
44
+ };
45
+ ```
46
+
47
+ ### Request Object
48
+
49
+ The `req` object contains:
50
+
51
+ ```javascript
52
+ {
53
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE',
54
+ body: {}, // Parsed JSON body
55
+ query: {}, // URL query parameters
56
+ headers: {}, // Request headers
57
+ url: '/api/users?id=1'
58
+ }
59
+ ```
60
+
61
+ ### Response Object
62
+
63
+ The `res` object has these methods:
64
+
65
+ ```javascript
66
+ // Set status code
67
+ res.status(200)
68
+
69
+ // Send JSON response
70
+ res.json({ data: 'value' })
71
+
72
+ // Send text response
73
+ res.send('Hello')
74
+
75
+ // Set custom header
76
+ res.setHeader('X-Custom', 'value')
77
+
78
+ // Chain methods
79
+ res.status(201).json({ created: true })
80
+ ```
81
+
82
+ ## Examples
83
+
84
+ ### GET Request
85
+
86
+ ```javascript
87
+ // api/users.js
88
+
89
+ const users = [
90
+ { id: 1, name: 'Aziz' },
91
+ { id: 2, name: 'John' }
92
+ ];
93
+
94
+ module.exports = async function handler(req, res) {
95
+ if (req.method === 'GET') {
96
+ // Get specific user
97
+ if (req.query.id) {
98
+ const user = users.find(u => u.id === parseInt(req.query.id));
99
+ if (user) {
100
+ return res.status(200).json(user);
101
+ }
102
+ return res.status(404).json({ error: 'User not found' });
103
+ }
104
+
105
+ // Get all users
106
+ return res.status(200).json(users);
107
+ }
108
+
109
+ return res.status(405).json({ error: 'Method not allowed' });
110
+ };
111
+ ```
112
+
113
+ **Usage:**
114
+ ```javascript
115
+ // Get all users
116
+ const response = await fetchApi('/api/users');
117
+ const users = await response.json();
118
+
119
+ // Get specific user
120
+ const response = await fetchApi('/api/users?id=1');
121
+ const user = await response.json();
122
+ ```
123
+
124
+ ### POST Request
125
+
126
+ ```javascript
127
+ // api/users.js
128
+
129
+ module.exports = async function handler(req, res) {
130
+ if (req.method === 'POST') {
131
+ const { name, email } = req.body;
132
+
133
+ // Validate
134
+ if (!name || !email) {
135
+ return res.status(400).json({
136
+ error: 'Name and email are required'
137
+ });
138
+ }
139
+
140
+ // Create user
141
+ const newUser = {
142
+ id: Date.now(),
143
+ name,
144
+ email
145
+ };
146
+
147
+ return res.status(201).json(newUser);
148
+ }
149
+ };
150
+ ```
151
+
152
+ **Usage:**
153
+ ```javascript
154
+ const response = await fetchApi('/api/users', {
155
+ method: 'POST',
156
+ body: JSON.stringify({
157
+ name: 'Aziz',
158
+ email: 'aziz@example.com'
159
+ })
160
+ });
161
+ const user = await response.json();
162
+ ```
163
+
164
+ ### PUT Request
165
+
166
+ ```javascript
167
+ // api/users.js
168
+
169
+ module.exports = async function handler(req, res) {
170
+ if (req.method === 'PUT') {
171
+ const userId = req.query.id;
172
+ const updates = req.body;
173
+
174
+ // Update user logic here
175
+
176
+ return res.status(200).json({
177
+ message: 'User updated',
178
+ user: updatedUser
179
+ });
180
+ }
181
+ };
182
+ ```
183
+
184
+ **Usage:**
185
+ ```javascript
186
+ const response = await fetchApi('/api/users?id=1', {
187
+ method: 'PUT',
188
+ body: JSON.stringify({
189
+ name: 'New Name'
190
+ })
191
+ });
192
+ ```
193
+
194
+ ### DELETE Request
195
+
196
+ ```javascript
197
+ // api/users.js
198
+
199
+ module.exports = async function handler(req, res) {
200
+ if (req.method === 'DELETE') {
201
+ const userId = req.query.id;
202
+
203
+ // Delete user logic here
204
+
205
+ return res.status(200).json({
206
+ message: 'User deleted'
207
+ });
208
+ }
209
+ };
210
+ ```
211
+
212
+ **Usage:**
213
+ ```javascript
214
+ const response = await fetchApi('/api/users?id=1', {
215
+ method: 'DELETE'
216
+ });
217
+ ```
218
+
219
+ ### Multiple Methods
220
+
221
+ ```javascript
222
+ // api/users.js
223
+
224
+ module.exports = async function handler(req, res) {
225
+ switch (req.method) {
226
+ case 'GET':
227
+ // Handle GET
228
+ return res.status(200).json({ method: 'GET' });
229
+
230
+ case 'POST':
231
+ // Handle POST
232
+ return res.status(201).json({ method: 'POST' });
233
+
234
+ case 'PUT':
235
+ // Handle PUT
236
+ return res.status(200).json({ method: 'PUT' });
237
+
238
+ case 'DELETE':
239
+ // Handle DELETE
240
+ return res.status(200).json({ method: 'DELETE' });
241
+
242
+ default:
243
+ return res.status(405).json({
244
+ error: 'Method not allowed'
245
+ });
246
+ }
247
+ };
248
+ ```
249
+
250
+ ## Using in Components
251
+
252
+ ### Basic Fetch
253
+
254
+ ```jsx
255
+ function MyComponent() {
256
+ const [data, setData] = useState(null);
257
+ const [loading, setLoading] = useState(false);
258
+
259
+ const loadData = async () => {
260
+ setLoading(true);
261
+ try {
262
+ const response = await fetchApi('/api/users');
263
+ const users = await response.json();
264
+ setData(users);
265
+ } catch (error) {
266
+ console.error('Error:', error);
267
+ }
268
+ setLoading(false);
269
+ };
270
+
271
+ return (
272
+ <div>
273
+ <button onClick={loadData}>Load Users</button>
274
+ {loading && <p>Loading...</p>}
275
+ {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
276
+ </div>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ### With Error Handling
282
+
283
+ ```jsx
284
+ const [error, setError] = useState(null);
285
+
286
+ const loadData = async () => {
287
+ try {
288
+ const response = await fetchApi('/api/users');
289
+
290
+ if (!response.ok) {
291
+ throw new Error('Failed to fetch');
292
+ }
293
+
294
+ const users = await response.json();
295
+ setData(users);
296
+ setError(null);
297
+ } catch (err) {
298
+ setError(err.message);
299
+ setData(null);
300
+ }
301
+ };
302
+ ```
303
+
304
+ ## Database Integration
305
+
306
+ ### Using a Real Database
307
+
308
+ ```javascript
309
+ // api/users.js
310
+
311
+ // Example with a database (you need to install the package)
312
+ // npm install better-sqlite3
313
+
314
+ const Database = require('better-sqlite3');
315
+ const db = new Database('mydb.sqlite');
316
+
317
+ module.exports = async function handler(req, res) {
318
+ if (req.method === 'GET') {
319
+ const users = db.prepare('SELECT * FROM users').all();
320
+ return res.status(200).json(users);
321
+ }
322
+
323
+ if (req.method === 'POST') {
324
+ const { name, email } = req.body;
325
+ const result = db.prepare(
326
+ 'INSERT INTO users (name, email) VALUES (?, ?)'
327
+ ).run(name, email);
328
+
329
+ return res.status(201).json({
330
+ id: result.lastInsertRowid,
331
+ name,
332
+ email
333
+ });
334
+ }
335
+ };
336
+ ```
337
+
338
+ ### Using External APIs
339
+
340
+ ```javascript
341
+ // api/weather.js
342
+
343
+ module.exports = async function handler(req, res) {
344
+ const city = req.query.city || 'London';
345
+
346
+ try {
347
+ const response = await fetch(
348
+ `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_KEY`
349
+ );
350
+ const data = await response.json();
351
+
352
+ return res.status(200).json(data);
353
+ } catch (error) {
354
+ return res.status(500).json({
355
+ error: 'Failed to fetch weather'
356
+ });
357
+ }
358
+ };
359
+ ```
360
+
361
+ ## Environment Variables
362
+
363
+ ```javascript
364
+ // api/config.js
365
+
366
+ module.exports = async function handler(req, res) {
367
+ // Access environment variables
368
+ const apiKey = process.env.API_KEY;
369
+ const dbUrl = process.env.DATABASE_URL;
370
+
371
+ return res.status(200).json({
372
+ hasApiKey: !!apiKey,
373
+ hasDbUrl: !!dbUrl
374
+ });
375
+ };
376
+ ```
377
+
378
+ Set environment variables:
379
+ ```bash
380
+ # Windows
381
+ set API_KEY=your_key
382
+ npm run dev
383
+
384
+ # Mac/Linux
385
+ API_KEY=your_key npm run dev
386
+ ```
387
+
388
+ ## Hot Reload
389
+
390
+ API routes support hot reload! When you save an API file:
391
+
392
+ 1. Dev server detects the change
393
+ 2. Reloads the API handler
394
+ 3. Next request uses the new code
395
+ 4. No server restart needed!
396
+
397
+ ## CORS
398
+
399
+ CORS is automatically enabled for all API routes:
400
+ ```
401
+ Access-Control-Allow-Origin: *
402
+ Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
403
+ Access-Control-Allow-Headers: Content-Type
404
+ ```
405
+
406
+ ## Error Handling
407
+
408
+ ### Server Errors
409
+
410
+ ```javascript
411
+ module.exports = async function handler(req, res) {
412
+ try {
413
+ // Your code here
414
+ const data = await someAsyncOperation();
415
+ return res.status(200).json(data);
416
+ } catch (error) {
417
+ console.error('API Error:', error);
418
+ return res.status(500).json({
419
+ error: 'Internal server error',
420
+ message: error.message
421
+ });
422
+ }
423
+ };
424
+ ```
425
+
426
+ ### Validation Errors
427
+
428
+ ```javascript
429
+ module.exports = async function handler(req, res) {
430
+ if (req.method === 'POST') {
431
+ const { name, email } = req.body;
432
+
433
+ if (!name) {
434
+ return res.status(400).json({
435
+ error: 'Name is required'
436
+ });
437
+ }
438
+
439
+ if (!email || !email.includes('@')) {
440
+ return res.status(400).json({
441
+ error: 'Valid email is required'
442
+ });
443
+ }
444
+
445
+ // Process valid data
446
+ }
447
+ };
448
+ ```
449
+
450
+ ## Status Codes
451
+
452
+ Common HTTP status codes:
453
+
454
+ - `200` - OK (successful GET, PUT, DELETE)
455
+ - `201` - Created (successful POST)
456
+ - `400` - Bad Request (validation error)
457
+ - `401` - Unauthorized (authentication required)
458
+ - `403` - Forbidden (no permission)
459
+ - `404` - Not Found (resource doesn't exist)
460
+ - `405` - Method Not Allowed (wrong HTTP method)
461
+ - `500` - Internal Server Error (server error)
462
+
463
+ ## Best Practices
464
+
465
+ ### 1. Always Handle Methods
466
+
467
+ ```javascript
468
+ module.exports = async function handler(req, res) {
469
+ if (req.method === 'GET') {
470
+ // Handle GET
471
+ } else {
472
+ return res.status(405).json({
473
+ error: 'Method not allowed'
474
+ });
475
+ }
476
+ };
477
+ ```
478
+
479
+ ### 2. Validate Input
480
+
481
+ ```javascript
482
+ if (!req.body.name || typeof req.body.name !== 'string') {
483
+ return res.status(400).json({ error: 'Invalid name' });
484
+ }
485
+ ```
486
+
487
+ ### 3. Use Try-Catch
488
+
489
+ ```javascript
490
+ try {
491
+ const data = await database.query();
492
+ return res.status(200).json(data);
493
+ } catch (error) {
494
+ return res.status(500).json({ error: error.message });
495
+ }
496
+ ```
497
+
498
+ ### 4. Return Early
499
+
500
+ ```javascript
501
+ if (!user) {
502
+ return res.status(404).json({ error: 'Not found' });
503
+ }
504
+
505
+ // Continue with logic
506
+ ```
507
+
508
+ ### 5. Use Async/Await
509
+
510
+ ```javascript
511
+ module.exports = async function handler(req, res) {
512
+ const data = await fetchData();
513
+ return res.status(200).json(data);
514
+ };
515
+ ```
516
+
517
+ ## Comparison with Next.js
518
+
519
+ | Feature | Aziz App | Next.js |
520
+ |---------|----------|---------|
521
+ | File-based routing | ✅ | ✅ |
522
+ | Server-side execution | ✅ | ✅ |
523
+ | Hot reload | ✅ | ✅ |
524
+ | Request/Response API | ✅ | ✅ |
525
+ | Dynamic routes | ❌ | ✅ |
526
+ | Middleware | ❌ | ✅ |
527
+ | Edge runtime | ❌ | ✅ |
528
+
529
+ ## Summary
530
+
531
+ - API routes run on the **server** (Node.js)
532
+ - Each file in `api/` becomes an endpoint
533
+ - Use `module.exports` to export the handler
534
+ - Access via `fetchApi('/api/routename')`
535
+ - Supports GET, POST, PUT, DELETE
536
+ - Hot reload enabled
537
+ - CORS enabled by default
538
+ - Just like Next.js API routes!