Todo API with Nodejs, Express and JSON
Tags: node, express
Published: 2023-07-16 18:49:25

### Prerequisites

To follow along with this tutorial, you will need to have the following installed on your machine:

[Nodejs](https://nodejs.org/)
[npm](https://www.npmjs.com/)
[nodemon](https://www.npmjs.com/package/nodemon)


Now that we know the basics concept, it's time to build real CRUD API (create, read, update, delete)

We will build all those CRUD routes:

Read all: GET /todos

Read one: GET /todos/1

Create: POST /todos

Update: PUT /todos/1

Delete: DELETE /todos/1


### Return status

With a CRUD API you can return data but also status code.

Here is a list of some status code and there meaning

`res.status(200) // Ok
res.status(201) // Created
res.status(204) // No content
res.status(400) // Bad request
res.status(401) // Unauthorized
res.status(403) // Forbidden
res.status(404) // Not found
res.status(500) // Server error
`

 Create a file name todo.json and copy/paste this code 

```
{
    "todos": [
        {
            "id": 1,
            "title": "Lorem ipsum dolor sit amet",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            "status": "completed"
        },
        {
            "id": 2,
            "title": "Consectetur adipiscing elit",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            "status": "pending"
        },
        {
            "id": 3,
            "title": "Lorem ipsum dolor consectetur",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            "status": "completed"
        },
        {
            "id": 4,
            "title": "Lorem ipsum adipiscing elit",
            "description": "dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
            "status": "completed"
        }
    ]
}
```

### Load data and start the server 

```
const express = require('express')
const app = express()
app.use(express.json())

const data = require('./data/todos.json')
const todos = data.todos

app.listen(5000, () => {
    console.log('server is listening on port 5000')
})
```

### Read all: GET /todos 

```
app.get('/todos', (req, res) => {
    res.json(todos)
})
```
### Read: GET /todos/1 

```
app.get('/todos/:id', (req, res) => {
    const id = Number(req.params.id)
    const todo = todos.find((item) => item.id === id)

    !todo ? res.status(404).send('Todo not found') : res.json(todo)  
})
```
In this section, we first check the todo `id` & confirm whether the product exists, then send a response accordingly.

res.json(todo) send the product in JSON format with a 200 ok status code.

###  Create: POST /todos
```
app.post('/todos', (req, res) => {
    const newTodo = {
        id: todos.length + 1,
        title: req.body.title,
        description: req.body.description,
        status: req.body.status
    }
    todos.push(newTodo)
    res.json(todos)
})
```
The app.use(express.json) is a middleware that take JSON content and create related req.body properties. (ex. req.body.title and req.body.description)

The res.status(201).json(newTodo) set the return response status to 201 (created) and also return the newTodo data in JSON format.

### Update: PUT /todos/1 

```
app.put('/todos/:id', (req, res) => {
    const id = Number(req.params.id)
    const index = todos.findIndex((item) => item.id === id)
    // console.log(todo)
    if (index === -1) {
        res.status(404).json('Todo not found!') 
    }
    const updatedTodo = {
        id: todos[index].id,
        title: req.body.title,
        description: req.body.description,
        status: req.body.status
    } 

    todos[index] = updatedTodo
    res.status(201).json('Todo was updated succesfully!')
})
```

###  Delete: DELETE /api/todos/1 

```
app.delete('/todos/:id', (req, res) => {
    const id = Number(req.params.id)
    const todo = todos.findIndex((item) => item.id === id)

    todo === -1 ? res.status(404).send('Todo not found') : res.status(200).json('Todo deleted successfully!')
})
```

### Conclusion
Our application is now complete. You can run the application by using the command `nodemon server` and test it out using [postman](https://www.postman.com/).

There are other ways you can improve the API by using MVC (separating the router from the controller) & also integrate [MongoDB](https://www.mongodb.com/) instead of JSON.

I'll implement these features in the source code of the application. You can check it out [here](https://github.com/Andrew-Ochieng/node-express-crud-api)

### Resources

- [Nodejs](https://nodejs.org/)
- [Express](https://expressjs.com/)
- [Json](https://www.json.org/json-en.html)

Thank you for reading this tutorial. If you have any questions, feel free to reach out to me on [Email](https://mailto:andrewomosh44@gmail.com) or [LinkedIn](https://www.linkedin.com/in/andrew-ochieng-00b076180/)