# Final Step In Building TODO Backend- Creating Routes and Controllers

Finally, We reached at the End of this Tutorial Series.

In this Section, we will see how to configure the `routes` and `controllers` together and also one request to you is `to keep` a little more **focus** and have `patience` and `faith` in me : D, because from this point of time, you may get lost inside files and folder and nothing will make sense to you, and you wouldn't know what exactly is happening so have patience, in the end, `everything` will connect and make sense : )

So we will start with the `routes`, we have already defined our routes and their purpose.

||||
|--- |--- |--- |
|**Method**|**Path**|**Description**|
|GET|/todos|Get all todos items|
|GET|/todos/:id|Get one todo item|
|POST|/todos|Create a new todo item|
|PUT|/todos/:id|Update a todo item|
|DELETE|/todos/:id|Delete a new todo item|

As we can see in the table, we have `5 routes`, so we will have `5 controllers.` But there is one logical problem we have only 2 routes not 5, if you closely look at the **Path** column we only have `/todos` and `/todos/:id` and they are reused multiple times this is because we can future differentiate same route based on the `HTTP` methods `( GET, POST, PUT, DELETE, etc )`. So you can see in the **Method** column, we have different HTTP methods for the same routes.

So let's start with the `/todos` route, this will return all tasks from database, now we will create a `route` and define the respective `controller` for it and then the process will repeat for other routes.

Create a `todoRoutes.js` file inside `/routers` folder we had created previously.

`/todos/todoRouters.js`

```
// import express
const express = require("express");

// controllers
const { getAllTodos } = require("../controllers/todoControllers");

// initialize route using express router
const todoRoute = express.Router();

// define the /todos + / => /todos/ route to get all todos
todoRoute
  .route("/")
  .get(getAllTodos);  // we will define and import this function soon

// export the route
module.exports = todoRoute;
```

Now, let's move onto the `controller`, create a `todoControllers.js` file inside `/controllers` and also now we will require our **todo model** we had created inside `model/todos.js`

`/controllers/todoControllers.js`

```
// import the todo model
const Todos = require("../models/todos");

const getAllTodos = (req, res) => {

 // mongoose find
  Todos.find({}) 

      .then((todos) => {

        res.status(200); // setting 200 ok  response status
        res.setHeader("Content-Type", "application/json");  // setting header as json
        res.json({ todos: todos });  // sending data to client in JSON 

      })
      .catch((err) => {

        res.status(500);   // setting 500 internal server error
        res.json({ error: err });   // sending error to client in JSON 

      });
};

// export the controllers
module.exports = {
  getAllTodos,
};

```
Now, lets link our `router` to our express app.

Open `app.js` file and `import todoRouter from todoRouters.js` :

```
//routes
const todoRouter = require("./routes/todoRoutes");

now, add the following line below your initialization of express app line 

.
.

const app = express();
.
.

app.use("/todos", todoRouter);
```

**Updated app.js**

```
// import express
const express = require("express");

//import mongoose
const mongoose = require("mongoose");

// import dotenv
const dotenv = require("dotenv");

// routers
const todoRouter = require("./routes/todoRoutes");

// load environment variable
dotenv.config({ path: ".env" });

// read env variable using process.env.<your_env_variable_name>
const PORT = process.env.PORT;
const dbURI = process.env.DATABASE_URL;

// making connection object
const connect = mongoose.connect(dbURI, {

  useNewUrlParser: true,
  useUnifiedTopology: true,

});

// connecting with database
connect.then(

  (db) => {
    console.log("Connected Successfully to Mongodb Server");
  },

  (err) => {
    console.log(err);
  }

);

// initialize express app
const app = express();

// sending a hello response on visiting http://localhost:3000/
app.get("/", (req, res) => {

  res
    .status(200)
    .json({ message: "Hi I am Server", data: "no data on this endpoint" });

});

app.use("/todos", todoRouter);

// listening for any HTTP requests on PORT 3000
app.listen(PORT, () => {

  console.log(`Server is running at http://localhost:${PORT}`);

});

```
Now if you visit <http://localhost:3000/todos/> you should see the below `response` on your browser.

**Output:**

```
{"todos":[]}
```

`Congratulations!` You have created your very own `REST API` backend : )

Now, let's move on to completing our `routes` and `controllers` for all the remaining Endpoints.

## Completing Routes And Controllers - CRUD Operations
​
​We are almost done! Finally, let's implement the remaining routes and controllers, and after that, we will `test` our API Endpoints using `Postman`.

Now, the process remains the same for all other routes except the logic will change, like for `delete route` your controller will implement the logic to delete the todo using the provided `todoID`.

Lets, quickly define the `route handlers` for all the remaining routes

`Final /todos/todoRouters.js`

```
// import express
const express = require("express");

//controllers
const {
  getAllTodos,
  createTodo,
  getTodoById,
  updateTodo,
  deleteTodo,
  taskCompletionTime,
} = require("../controllers/todoControllers");

// initialize route using express router
const todoRoute = express.Router();

// define the /todos + / => /todos/ route to get all todos
todoRoute.route("/").get(getAllTodos).post(createTodo); // same route different method chained together
todoRoute.route("/:id").get(getTodoById).put(updateTodo).delete(deleteTodo);

// export the route
module.exports = todoRoute;

```

>  Kindly ignore the `error` and `warning` in the console they all will disappear soon : D

Remaining Controllers
---------------------

`Create Todo Controller`

```
// import uniquid to generate unique ids
const uniquid = require("uniquid");

const createTodo = (req, res) => {
    const { description } = req.body;

    Todos.create({ taskID: uniquid(), description: description})
    .then((todo) => {
      res.status(200);
      res.setHeader("Content-Type", "application/json");
      res.json({ status: "Todo added successfully", data: todo });
    })
    .catch((err) => {
      res.status(404);
      res.json({ message: "Invalid Object Property", error: err });
    });
};

```

`Get Single Todo Controller`

```
const getTodoById = (req, res) => {
  Todos.findById(req.params.id)
    .then((todo) => {
        res.status(200);
        res.setHeader("Content-Type", "application/json");
        res.json(todo);
    })
    .catch((err) => {
      res.status(404);
      res.json({ message: "Id did not exists", error: err });
    });
};

```

`Update Todo Controller`

```
const updateTodo = (req, res, next) => {
     Todos.findByIdAndUpdate(
          { _id: req.params.id },
          {
            $set: req.body,
          },
          { new: true, useFindAndModify: false } //get updated result
        )
          .then((todo) => {
            res.status(200);
            res.setHeader("Content-Type", "application/json");
            res.json(todo);
          })
          .catch((err) => {
            res.status(404);
            res.json({ message: "unable to update", error: err });
     });
};

```

`Delete Todo Controller`

```
const deleteTodo = (req, res, next) => {
    Todos.findByIdAndRemove(req.params.id)
        .then((response) => {
            res.status(200);
            res.setHeader("Content-Type", "application/json");
            res.json({
              status: "Todo deleted successfully",
              response: response,
            });
          })
        .catch((err) => {
            res.status(404);
            res.json({ message: "unable to delete", error: err });
      });
};

```

Updated Controllers - Final
---------------------------

`/controllers/todoControllers.js`

```
// import uniquid to generate unique ids
const uniquid = require("uniquid");

// import the todo model
const Todos = require("../models/todos");

// get all todos
const getAllTodos = (req, res) => {
  // mongoose find
  Todos.find({})
    .then((todos) => {
      res.status(200); // setting 200 ok  response status
      res.setHeader("Content-Type", "application/json"); // setting header as json
      res.json({ todos: todos }); // sending data to client in JSON
    })
    .catch((err) => {
      res.status(500); // setting 500 internal server error
      res.json({ error: err }); // sending error to client in JSON
    });
};

// create task in todo
const createTodo = (req, res) => {
  const { description } = req.body;

  Todos.create({ taskID: uniquid(), description: description })
    .then((todo) => {
      res.status(200);
      res.setHeader("Content-Type", "application/json");
      res.json({ status: "Todo added successfully", data: todo });
    })
    .catch((err) => {
      res.status(404);
      res.json({ message: "Invalid Object Property", error: err });
    });
};

// get a single todo task
const getTodoById = (req, res) => {
  Todos.findById(req.params.id)
    .then((todo) => {
      res.status(200);
      res.setHeader("Content-Type", "application/json");
      res.json(todo);
    })
    .catch((err) => {
      res.status(404);
      res.json({ message: "Id did not exists", error: err });
    });
};

// update todo task
const updateTodo = (req, res, next) => {
  Todos.findByIdAndUpdate(
    { _id: req.params.id },
    {
      $set: req.body,
    },
    { new: true, useFindAndModify: false } //get updated result
  )
    .then((todo) => {
      res.status(200);
      res.setHeader("Content-Type", "application/json");
      res.json(todo);
    })
    .catch((err) => {
      res.status(404);
      res.json({ message: "unable to update", error: err });
    });
};

// delete single todo task
const deleteTodo = (req, res, next) => {
  Todos.findByIdAndRemove(req.params.id)
    .then((response) => {
      res.status(200);
      res.setHeader("Content-Type", "application/json");
      res.json({
        status: "Todo deleted successfully",
        response: response,
      });
    })
    .catch((err) => {
      res.status(404);
      res.json({ message: "unable to delete", error: err });
    });
};

// export the controllers
module.exports = {
  getAllTodos,
  createTodo,
  getTodoById,
  updateTodo,
  deleteTodo,
};

```

> `Browser` can only perform `GET` request, so in order to perform **POST**, **PUT**, **DELETE** requests we will be using an industry-standard tool for testing APIs i.e `Postman`

Lastly, add following more lines into the `app.js`:

```
npm install cors
```

`Cors` module allows your frontend application to fetch data from this backend, which is running on different `ORIGIN. `Learn more about Browser's [Same Origin Policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) 

```
// import cors on top
const cors = require("cors");

Now below this line add the following lines
const app = express();
.
.
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

```

** Updated app.js **

```
// import express
const express = require("express");
//import mongoose
const mongoose = require("mongoose");
// import dotenv
const dotenv = require("dotenv");
const cors = require("cors");

// routers
const todoRouter = require("./routes/todoRoutes");

// load environment variable
dotenv.config({ path: ".env" });

// read env variable using process.env.<your_env_variable_name>
const PORT = process.env.PORT;
const dbURI = process.env.DATABASE_URL;

// making connection object
const connect = mongoose.connect(dbURI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

// connecting with database
connect.then(
  (db) => {
    console.log("Connected Successfully to Mongodb Server");
  },
  (err) => {
    console.log(err);
  }
);

// initialize express app
const app = express();

app.use(cors());
app.use(express.json());  // parse JSON data into JS object
app.use(express.urlencoded({ extended: false })); //allows you to accept form submitted data

// sending a hello response on visiting http://localhost:3000/
app.get("/", (req, res) => {
  res
    .status(200)
    .json({ message: "Hi I am Server", data: "no data on this endpoint" });
});

app.use("/todos", todoRouter);

// listening for any HTTP requests on PORT 3000
app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`);
});

```

So Finally, Our Code is Completed, we had successfully created our `REST API Backend` using `Nodejs`, `MongoDB`, and `Express`. In the next section, we will test our backend using `Postman`

## Get the Final Code on Github

[Building Todo Backend Code](https://github.com/teachmebro/todo-backend-nodejs-tutorial)

## Workshop Video

Watch My Hands-On **Workshop** on `Building A TODO REST API BAckend` 

%[https://youtu.be/hsGOl_28R10]



​
