create-aziz-app 2.0.15 → 3.0.0
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.
- package/README.md +3 -3
- package/bin/create-aziz-app.js +9 -9
- package/package.json +10 -11
- package/template/README.md +5 -5
- package/template/_framework/boot.js +3 -3
- package/template/_framework/hooks.js +1 -1
- package/template/{modules → _framework}/next-response.js +5 -13
- package/template/_framework/router.js +1 -1
- package/template/_framework/runtime.js +1 -1
- package/template/api/createUser.js +1 -1
- package/template/api/hello.js +1 -1
- package/template/api/loginUser.js +1 -1
- package/template/api/users.js +1 -1
- package/template/app/about/page.js +1 -1
- package/template/app/layout.js +1 -1
- package/template/components/Footer.js +1 -1
- package/template/components/Navbar.js +1 -1
- package/template/package.json +4 -7
- package/template/scripts/dev-server.js +1 -1
- package/template/.vscode/settings.json +0 -15
- package/template/api/getUser.js +0 -60
- package/template/api/getUserWithDB.js +0 -65
- package/template/app.config.js +0 -41
- package/template/app.html +0 -55
- package/template/components/Counter.jsx +0 -36
- package/template/components/Footer.jsx +0 -9
- package/template/components/Navbar.jsx +0 -17
- package/template/docs/API-GUIDE.md +0 -196
- package/template/docs/API-ROUTES.md +0 -538
- package/template/docs/AUTO-IMPORT.md +0 -99
- package/template/docs/AUTO-REGISTRATION.md +0 -248
- package/template/docs/CSS-FRAMEWORKS.md +0 -221
- package/template/docs/DEV-SERVER.md +0 -184
- package/template/docs/GETTING-STARTED.md +0 -205
- package/template/docs/HOW-IT-WORKS.md +0 -362
- package/template/docs/NEXTJS-APP-ROUTER.md +0 -536
- package/template/docs/NEXTJS-COMPARISON.md +0 -473
- package/template/docs/QUICK-START.md +0 -111
- package/template/docs/STYLING.md +0 -269
- package/template/docs/TROUBLESHOOTING.md +0 -282
- package/template/modules/README.md +0 -129
- package/template/modules/api.js +0 -44
- package/template/modules/auto-import.js +0 -130
- package/template/modules/router.js +0 -218
- package/template/modules/state.js +0 -248
- package/template/package-lock.json +0 -13
- package/template/pages/About.jsx +0 -48
- package/template/pages/ApiDemo.jsx +0 -209
- package/template/pages/Contact.jsx +0 -25
- package/template/pages/Example.jsx +0 -59
- package/template/pages/Home.jsx +0 -39
- package/template/pages/HooksDemo.jsx +0 -194
- package/template/pages/test.jsx +0 -72
- package/template/scripts/build.js +0 -81
- package/template/scripts/generate-imports.js +0 -88
- package/template/tailwind.config.js +0 -17
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# API Routes Guide
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Your app now has a Next.js-like API route system! Create API endpoints in the `api/` folder and call them from your components.
|
|
6
|
-
|
|
7
|
-
## Creating API Routes
|
|
8
|
-
|
|
9
|
-
### Basic Example
|
|
10
|
-
|
|
11
|
-
Create a file in `api/` folder:
|
|
12
|
-
|
|
13
|
-
```javascript
|
|
14
|
-
// api/myroute.js
|
|
15
|
-
registerApiRoute('myroute', async (req, res) => {
|
|
16
|
-
return res.status(200).json({
|
|
17
|
-
message: 'Hello from API!'
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Request Object (req)
|
|
23
|
-
|
|
24
|
-
The request object contains:
|
|
25
|
-
- `req.method` - HTTP method (GET, POST, PUT, DELETE)
|
|
26
|
-
- `req.body` - Request body (parsed JSON)
|
|
27
|
-
- `req.query` - Query parameters from URL
|
|
28
|
-
- `req.params` - Route parameters
|
|
29
|
-
|
|
30
|
-
### Response Object (res)
|
|
31
|
-
|
|
32
|
-
The response object has methods:
|
|
33
|
-
- `res.status(code)` - Set HTTP status code
|
|
34
|
-
- `res.json(data)` - Send JSON response
|
|
35
|
-
- `res.send(data)` - Send plain response
|
|
36
|
-
|
|
37
|
-
### Full CRUD Example
|
|
38
|
-
|
|
39
|
-
```javascript
|
|
40
|
-
// api/todos.js
|
|
41
|
-
const todos = [];
|
|
42
|
-
|
|
43
|
-
registerApiRoute('todos', async (req, res) => {
|
|
44
|
-
switch (req.method) {
|
|
45
|
-
case 'GET':
|
|
46
|
-
// Get all todos
|
|
47
|
-
return res.status(200).json(todos);
|
|
48
|
-
|
|
49
|
-
case 'POST':
|
|
50
|
-
// Create new todo
|
|
51
|
-
const newTodo = {
|
|
52
|
-
id: Date.now(),
|
|
53
|
-
title: req.body.title,
|
|
54
|
-
completed: false
|
|
55
|
-
};
|
|
56
|
-
todos.push(newTodo);
|
|
57
|
-
return res.status(201).json(newTodo);
|
|
58
|
-
|
|
59
|
-
case 'PUT':
|
|
60
|
-
// Update todo
|
|
61
|
-
const id = req.body.id;
|
|
62
|
-
const index = todos.findIndex(t => t.id === id);
|
|
63
|
-
if (index !== -1) {
|
|
64
|
-
todos[index] = { ...todos[index], ...req.body };
|
|
65
|
-
return res.status(200).json(todos[index]);
|
|
66
|
-
}
|
|
67
|
-
return res.status(404).json({ error: 'Not found' });
|
|
68
|
-
|
|
69
|
-
case 'DELETE':
|
|
70
|
-
// Delete todo
|
|
71
|
-
const deleteId = req.query.id;
|
|
72
|
-
const deleteIndex = todos.findIndex(t => t.id === parseInt(deleteId));
|
|
73
|
-
if (deleteIndex !== -1) {
|
|
74
|
-
todos.splice(deleteIndex, 1);
|
|
75
|
-
return res.status(200).json({ message: 'Deleted' });
|
|
76
|
-
}
|
|
77
|
-
return res.status(404).json({ error: 'Not found' });
|
|
78
|
-
|
|
79
|
-
default:
|
|
80
|
-
return res.status(405).json({ error: 'Method not allowed' });
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Using API Routes in Components
|
|
86
|
-
|
|
87
|
-
### Basic GET Request
|
|
88
|
-
|
|
89
|
-
```javascript
|
|
90
|
-
const MyComponent = () => {
|
|
91
|
-
const [data, setData] = useState(null);
|
|
92
|
-
|
|
93
|
-
const loadData = async () => {
|
|
94
|
-
const response = await fetchApi('/api/myroute');
|
|
95
|
-
const result = await response.json();
|
|
96
|
-
setData(result);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<div>
|
|
101
|
-
<button onClick={loadData}>Load Data</button>
|
|
102
|
-
{data && <p>{data.message}</p>}
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### POST Request
|
|
109
|
-
|
|
110
|
-
```javascript
|
|
111
|
-
const addItem = async () => {
|
|
112
|
-
const response = await fetchApi('/api/todos', {
|
|
113
|
-
method: 'POST',
|
|
114
|
-
body: JSON.stringify({
|
|
115
|
-
title: 'New Todo'
|
|
116
|
-
})
|
|
117
|
-
});
|
|
118
|
-
const result = await response.json();
|
|
119
|
-
console.log('Created:', result);
|
|
120
|
-
};
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Query Parameters
|
|
124
|
-
|
|
125
|
-
```javascript
|
|
126
|
-
// Fetch with query params
|
|
127
|
-
const response = await fetchApi('/api/users?id=123&name=John');
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### DELETE Request
|
|
131
|
-
|
|
132
|
-
```javascript
|
|
133
|
-
const deleteItem = async (id) => {
|
|
134
|
-
const response = await fetchApi(`/api/todos?id=${id}`, {
|
|
135
|
-
method: 'DELETE'
|
|
136
|
-
});
|
|
137
|
-
const result = await response.json();
|
|
138
|
-
console.log(result.message);
|
|
139
|
-
};
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Available API Routes
|
|
143
|
-
|
|
144
|
-
### /api/hello
|
|
145
|
-
Simple hello world endpoint
|
|
146
|
-
- **GET** `/api/hello?name=YourName`
|
|
147
|
-
- Returns: `{ message: "Hello, YourName!", timestamp: "...", method: "GET" }`
|
|
148
|
-
|
|
149
|
-
### /api/users
|
|
150
|
-
User management endpoint
|
|
151
|
-
- **GET** `/api/users` - Get all users
|
|
152
|
-
- **GET** `/api/users?id=1` - Get specific user
|
|
153
|
-
- **POST** `/api/users` - Create user (body: `{ name, email }`)
|
|
154
|
-
- **PUT** `/api/users?id=1` - Update user (body: `{ name, email }`)
|
|
155
|
-
- **DELETE** `/api/users?id=1` - Delete user
|
|
156
|
-
|
|
157
|
-
## Tips
|
|
158
|
-
|
|
159
|
-
1. **Mock Data**: Currently, API routes use in-memory data. Replace with real backend calls when ready.
|
|
160
|
-
|
|
161
|
-
2. **Error Handling**: Always wrap API calls in try-catch:
|
|
162
|
-
```javascript
|
|
163
|
-
try {
|
|
164
|
-
const response = await fetchApi('/api/myroute');
|
|
165
|
-
const data = await response.json();
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error('API Error:', error);
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
3. **Loading States**: Use loading state for better UX:
|
|
172
|
-
```javascript
|
|
173
|
-
const [loading, setLoading] = useState(false);
|
|
174
|
-
|
|
175
|
-
const loadData = async () => {
|
|
176
|
-
setLoading(true);
|
|
177
|
-
try {
|
|
178
|
-
const response = await fetchApi('/api/data');
|
|
179
|
-
const data = await response.json();
|
|
180
|
-
setData(data);
|
|
181
|
-
} finally {
|
|
182
|
-
setLoading(false);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
4. **Real Backend**: To connect to a real backend, modify `fetchApi` in `api.js` to use `fetch()` instead of the mock system.
|
|
188
|
-
|
|
189
|
-
## Demo
|
|
190
|
-
|
|
191
|
-
Visit `#/api-demo` in your app to see a live demo of the API system with:
|
|
192
|
-
- GET requests
|
|
193
|
-
- POST requests (create users)
|
|
194
|
-
- DELETE requests
|
|
195
|
-
- Loading states
|
|
196
|
-
- Error handling
|
|
@@ -1,538 +0,0 @@
|
|
|
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!
|