DEV Community

Cover image for Todo API with Nodejs, Express and JSON
Andrew Ochieng
Andrew Ochieng

Posted on

Todo API with Nodejs, Express and JSON

Prerequisites

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

Nodejs
npm
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"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

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')
})
Enter fullscreen mode Exit fullscreen mode

Read all: GET /todos

app.get('/todos', (req, res) => {
    res.json(todos)
})
Enter fullscreen mode Exit fullscreen mode

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)  
})
Enter fullscreen mode Exit fullscreen mode

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)
})
Enter fullscreen mode Exit fullscreen mode

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!')
})
Enter fullscreen mode Exit fullscreen mode

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!')
})
Enter fullscreen mode Exit fullscreen mode

Conclusion

Our application is now complete. You can run the application by using the command nodemon server and test it out using postman.

There are other ways you can improve the API by using MVC (separating the router from the controller) & also integrate MongoDB instead of JSON.

I'll implement these features in the source code of the application. You can check it out here

Resources

Thank you for reading this tutorial. If you have any questions, feel free to reach out to me on Email or LinkedIn

Top comments (1)

Collapse
 
markadel profile image
Mark Adel

Your delete route handler is incomplete.