## Exercise: Implementing a RESTful API with Express.js
### Overview
In this exercise, you will create a RESTful API for managing a simple to-do list using Express.js, a popular web framework for Node.js. You will apply the principles of RESTful design to create endpoints that allow clients to interact with to-do list items.
### Requirements
- Node.js and npm installed
- A text editor or IDE of your choice
- Postman or any API testing tool
### Setup
1. Initialize a new Node.js project and install Express:
```bash
mkdir todo-api
cd todo-api
npm init -y
npm install express body-parser
```
2. Create a new file named `app.js`.
### Instructions
1. **Set up your Express application**:
```javascript
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
```
2. **Create a data structure to store to-dos**. Use an array of objects:
```javascript
let todos = [
{ id: 1, task: 'Learn Node.js', completed: false },
{ id: 2, task: 'Build a RESTful API', completed: false }
];
```
3. **Implement RESTful endpoints**:
- GET all to-dos:
```javascript
app.get('/api/todos', (req, res) => {
res.status(200).json(todos);
});
```
- GET a single to-do by ID:
```javascript
app.get('/api/todos/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).send('The to-do with the given ID was not found.');
res.status(200).json(todo);
});
```
- POST to create a new to-do:
```javascript
app.post('/api/todos', (req, res) => {
const todo = {
id: todos.length + 1,
task: req.body.task,
completed: false
};
todos.push(todo);
res.status(201).json(todo);
});
```
- PUT to update a to-do:
```javascript
app.put('/api/todos/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).send('The to-do with the given ID was not found.');
todo.task = req.body.task;
todo.completed = req.body.completed;
res.status(200).json(todo);
});
```
- DELETE to remove a to-do:
```javascript
app.delete('/api/todos/:id', (req, res) => {
todos = todos.filter(t => t.id !== parseInt(req.params.id));
res.status(204).send();
});
```
4. **Start your Express server**:
```javascript
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));
```
### Testing Your API
Use Postman or a similar tool to test your API endpoints. Ensure you can:
- Retrieve the full list of to-dos.
- Retrieve a single to-do by ID.
- Add a new to-do.
- Update an existing to-do.
- Delete a to-do.
### Deliverables
- An Express.js application file named `app.js`.
- A collection of Postman requests to test each endpoint.
### Bonus
- Implement JWT-based authentication.
- Add pagination and sorting to the GET all to-dos endpoint.
- Validate incoming data before creating or updating to-dos.
- Write integration tests for your API endpoints.
### Conclusion
This exercise will solidify your understanding of creating RESTful APIs with Express.js. You'll practice defining routes, handling different HTTP methods, and responding with appropriate status codes and data.