In this lesson, we'll dive into the practical aspects of using Mongoose with Express to create and view a todo item via an API. By the end of this lesson, you'll know how to define a Mongoose schema and model, create a sample todo item, and view it.
In this lesson you'll learn:
- How to set up an Express server with Mongoose.
- How to define a Mongoose schema and model with additional fields.
- How to create a sample todo item.
- How to view the created todo items via the API.
We'll start by importing the required libraries, initializing our Express application, and setting up middleware to parse JSON request bodies.
JavaScript1const express = require('express'); 2const mongoose = require('mongoose'); 3 4const app = express(); 5 6// Middleware to parse JSON request bodies 7app.use(express.json());
Here, we:
- Import
express
andmongoose
. - Create an Express application instance.
- Use middleware to allow our Express application to understand and parse JSON bodies from incoming requests.
Next, we'll establish a connection to our MongoDB database.
JavaScript1// Set mongoose strictQuery to true to suppress deprecation warning 2mongoose.set('strictQuery', true); 3 4mongoose.connect('mongodb://127.0.0.1:27017/todo-app', { 5 useNewUrlParser: true, 6 useUnifiedTopology: true, 7}) 8.then(() => console.log("Connected to MongoDB")) 9.catch((error) => console.error("Failed to connect to MongoDB:", error));
This code:
- Connects to a MongoDB database named
todo-app
running locally. - Logs a success message upon successful connection.
- Catches and logs any connection errors.
Now, let's create a schema and a model for our todo items.
JavaScript1const todoSchema = new mongoose.Schema({ 2 task: { type: String, required: true }, 3 status: { type: String, required: true } 4}); 5 6const Todo = mongoose.model('Todo', todoSchema);
Here we:
- Define a schema with two fields:
task
, which is a required string, andstatus
, which is also a required string. - Create a
Todo
model from the schema, which we will use to interact with thetodos
collection in MongoDB.
Understanding Automatically Added Fields: _id and __v:
Mongoose automatically adds some fields to each document, which you may notice in the API responses:
_id
: Mongoose adds an_id
field to each document, which uniquely identifies the document within the collection. This is similar to a primary key in a relational database and is essential for distinguishing individual documents.__v
: Mongoose also adds a__v
field to track the version of the document. This is useful for handling concurrency and ensuring that updates to documents are applied correctly.
Now, let's move on to creating API routes to handle creating and viewing todo items.
To ensure our schema and model work correctly, let's create an API route to handle the creation of todo items.
JavaScript1app.post('/todos', async (req, res) => { 2 try { 3 const { task, status } = req.body; 4 const newTodo = new Todo({ 5 task, 6 status: status || 'In Progress' 7 }); 8 const savedTodo = await newTodo.save(); 9 res.status(201).send(savedTodo); 10 } catch (err) { 11 res.status(400).send({ error: 'Error creating Todo: ' + err.message }); 12 } 13});
In this snippet:
- We define a POST route
/todos
to create new todo items. - Extract
task
andstatus
from the request body. - Create a new
Todo
document with the task description and status, defaulting to "In Progress" if no status is provided. - Attempt to save the new document to the database.
- If successful, we send the created todo item back to the client with a 201 status code.
- If there's an error, we catch it and respond with a 400 status code and an error message.
Next, let's create an API route to get all todo items.
JavaScript1app.get('/todos', async (req, res) => { 2 try { 3 const todos = await Todo.find(); 4 res.status(200).send(todos); 5 } catch (err) { 6 res.status(400).send({ error: 'Error fetching Todos: ' + err.message }); 7 } 8});
In this snippet:
- We define a GET route
/todos
to retrieve all todo items from the database. - Attempt to find all documents in the
todos
collection. - If successful, we send the retrieved todo items back to the client with a 200 status code.
- If there's an error, we catch it and respond with a 400 status code and an error message.
Finally, we start the server and listen on the defined port.
JavaScript1const port = process.env.PORT || 3000; 2 3app.listen(port, () => { 4 console.log(`Server listening on port ${port}`); 5}); 6 7// Export the model (optional, useful for importing in other files) 8module.exports = Todo;
This code starts the Express server and logs a message indicating that the server is running. To make the model available for import in other files, we need to export it.
In this lesson, we learned how to set up an Express server with Mongoose, define a schema and model with additional fields, create a sample todo item via an API route, and view the created todo items via another API route. By following these steps, you can effectively manage your data using Mongoose and expose functionality through a RESTful API.