Simple todo API with complex concepts
Tags: beginners, api, mongodb, database
Published: 2022-06-24 16:22:02

## Getting started 
In this article you will learn how to build a simple todo API using Nodejs. Nodejs is an open-source , JavaScript runtime environment use foe backend development. It's is used by the tech giants all over the world having wonderful community support and well structured documentation.

## Install the dependencies 
Before you satrt building the API you must install the following dependencies mentioned below.

- [nodejs](https://nodejs.org/en/)
- [expressjs](https://expressjs.com/)
- [mongoosejs] (https://mongoosejs.com/)
- [Mongodb](https://www.mongodb.com/)
- [clone this repo] (https://github.com/kum9748ar/hc-api-event)
After you clone the github repo open the folder named `hc-api-event`in the terminal and hit `npm install`, this will install all the required packages mentioned in the `package.json` file.

## The File structure 
![Fs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8plmwmzgmigfhv0q8g8.png)
 
## Import the modules 
 To start using the libraries we need to import them first
```
/*Importing the moudule*/
const express = require('express');
const mongoose = require('mongoose');
const app = express()
app.use(express.json())
require('dotenv').config();
```
## Connect the database and start the API 
As we are building a todo API so we need to store the data `todo's` and there it comes the need of database.Database is an organized way to store collection of data just like taking down notes in a notebook.We are using Mongodb which is a popular nosql database.So to store the todo's into the database first we need to connect our API with Mongodb. We will use the `mongoose` instance which is having a `connect `funtion which takes two parameters one is the `connection string` which is necessary and other is options . Use the below piece of code to connect the database with the API 
```
const start = () => {
    mongoose.connect(process.env.MONGODB_CONNECTION_STRING, {
        useNewUrlParser: true,
        useUnifiedTopology: true
    }).then(
        app.listen(5000, () => {
            console.log("App is listining ");
        })
    ).catch((err) => {
        console.log("Error ")
    })
}
start()
```
`mongoose.connect()` returns a `promise` which we are handling using `then()` and `catch()`. Here we are declaring that if the db connection is successfull then only start the API else catch the eror and stop the API. Now use our API we need to have some ednpoint so we are creating an HTTP server which will listen to port=5000, this is just like watching your favourite show on a particular channel out of many.

## Designing the schema and creting the Model 
 Schemas are like skeleteal structures of data, It contains the necessary metadata of the data we are passing into the database.  Suppose our data is related to a person so there will be a property named say `name` of type string which is required or say a property named `isEmployed` of type `boolean` and defalut value will be `false `

```
person schema :{
 isEmployed : { type: Boolean, default: false },
  Name: {type: String, required: true}

}
```  
Model on the other hand provides an interface to the database for creating, querying, updating, deleting records, etc.

```
// Mongodb Schema & Model 
const todoSchema = mongoose.Schema({
    todo: String
})
const Todo = mongoose.model('Todo', todoSchema)

```
## Designing the API request
Let me tell you that the behavior of an API is to accept a `request` and then pass a desired `response`. The request contains are metadata about what we want, in which form we are requesting the data, from which browser, which IP and a lot more similarly a response all the metadata taht we are passing to the Cient. In CRUD architechture we deal with 4 types of requests `get` Reading , `post` for Creating , `put` for updating and `delete` for deleting.So,Now we have created a model named `Todo` and we can use it to interact with our db. 

### `Get All Todo's` 
 We will just grab all the todo's using `find()` and pass it as a response 
```
app.get('/', async (req, res) => {
    const data = await Todo.find();
    res.json(data)
})
 ```
### `Create a Todo `

We will use  the `create()` and will store the todo in the db
```
app.post('/', async (req, res) => {
    const data = await Todo.create(req.body);
    res.send(data)
})
```

## Working with a particular document 
Every doccument Mongodb creates it generated an ID. ID's are necessary to filter documents having similar property, just like there can be two employees with same name and same height but will have different employee ID's. Just like that every documnet we create mongobd automatically generates an Unique ID for it . Now we will be using these id in our request to filter data

### `Get a single Todo `
As I have stated that our request contains all the metadata so we will be grabing the id of a todo from the request params and will us to filter that particular todo from our db using the `findById`

```
app.get('/:id', async (req, res) => {
    const data = await Todo.findById(req.params.id);
    res.json(data)
})
```

### `Update a Todo`
We will use a method named `findByIdAndUpdate` and there will pass the `id` of the todo we want to delete followed by `req.body` with conataines the updated todo and lastly we will pass a option `new` which will be set to `true`

```
app.put('/:id', async (req, res) => {
    const data = await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true })
    res.send(data)
})
```

### ` Delete a Todo `
Finally we will use the same approach to  delete a todo using a method named `findByIdAndUpdate` and will pass the todo `id `and our todo will be deleted.

```
app.delete("/:id", async (req, res) => {
    const data = await Todo.findByIdAndDelete(req.params.id)
    res.send("Todo deleted")
})
```

### The Final code

```
/*Importing the moudule*/
const express = require('express');
const mongoose = require('mongoose');
const app = express()
app.use(express.json())
require('dotenv').config();

// Mongodb Schema & Model 
const todoSchema = mongoose.Schema({
    todo: String
})
const Todo = mongoose.model('Todo', todoSchema)


//api requests 

app.get('/', async (req, res) => {
    const data = await Todo.find();
    res.json(data)
})
app.post('/', async (req, res) => {
    const data = await Todo.create(req.body);
    res.send(data)
})
app.get('/:id', async (req, res) => {
    const data = await Todo.findById(req.params.id);
    res.json(data)
})

app.put('/:id', async (req, res) => {
    const data = await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true })
    res.send(data)
})

app.delete("/:id", async (req, res) => {
    const data = await Todo.findByIdAndDelete(req.params.id)
    res.send("Todo deleted")
})



const start = () => {
    mongoose.connect(process.env.MONGODB_CONNECTION_STRING, {
        useNewUrlParser: true,
        useUnifiedTopology: true
    }).then(
        app.listen(5000, () => {
            console.log("App is listining ");
        })
    ).catch((err) => {
        console.log("Error ")
    })
}
```
## Key Take aways
- Request & Response 
- CRUD Architechture 
- Mongoose model, Schema & simple data filtering

## Conclusion
Do share this article with your friends and peers if you find it useful and make sure to hit a reaction as it helps my page grow. Feel free to ask any questions in the comments

## Connect 
[Twitter](https://twitter.com/kumarkalyan_)
[Linkedin](https://www.linkedin.com/in/kumar009/)