DEV Community

Cover image for Note App - Part 1: Setup the Node API
Akhila Ariyachandra
Akhila Ariyachandra

Posted on • Updated on • Originally published at akhilaariyachandra.com

Note App - Part 1: Setup the Node API

This was originally posted on my blog. Check it out if you want learn more about React and JavaScript!

In this series we're going to create a notes app with Node, MongoDB & React. For the first part, let's setup the API.

I'm going to be using yarn as my package manager, but feel free to use npm or pnpm instead.

Initialize the project

First let's create a folder called 'notes-api' and initialize a project in it using

yarn init --yes
Enter fullscreen mode Exit fullscreen mode

We're going to use Backpack to build and run our API, so we'll install it as a dev dependency. Backpack has useful features like automatically reloading the server when any of the files are changed and being able to run ES6 code with without any configuration.

yarn add backpack-core -D
Enter fullscreen mode Exit fullscreen mode

Then add the following scripts to package.json.

{
  "scripts": {
    "dev": "backpack",
    "build": "backpack build"
  }
}
Enter fullscreen mode Exit fullscreen mode

yarn dev is used to start the development server and yarn build is used to get the production build.

Setup the database

Next let's setup the MongoDB database. If you want a more detailed explanation on setting up the database, you can check out my previous post Setup MongoDB in Node.js with Mongoose.

We'll create a database with mLab. Once you create it, you should create an user for the database and keep note of it's path. The path should be something like mongodb://<dbuser>:<dbpassword>@ds250607.mlab.com:38485/notes-db where <dbuser> and <dbpassword> are the username and password of the user you created for the database respectively.

Then install the mongoose dependency.

yarn add mongoose
Enter fullscreen mode Exit fullscreen mode

After that create a folder with the name 'src' in the project,create a file named database.js and insert the following code in it.

// src/database.js
// Import the dependency
import mongoose from "mongoose";

// The database path
const dbPath =
  "mongodb://<dbuser>:<dbpassword>@ds250607.mlab.com:38485/test-db";

// Connect the database
mongoose.connect(dbPath, {
  useNewUrlParser: true
});

// Check if the API successfully connected to the database
const db = mongoose.connection;
db.on("error", () => {
  console.log("> error occurred from the database");
});
db.once("open", () => {
  console.log("> successfully opened the database");
});

// Export the database instance
export default mongoose;
Enter fullscreen mode Exit fullscreen mode

Replace the value of dbPath with the path of your database.

Create the notes model

Once we're done setting up the database, we need to create a model to perform CRUD (Create, Retrieve, Update & Delete) operations on the database.

First create a folder with the name 'models' in 'src'. Then create a file called noteModel.js in it and add the following code.

// src/models/noteModel.js
// Import the database instance
import mongoose from "../database";

// Define the schema for a note
const schema = {
  title: { type: mongoose.SchemaTypes.String, required: true },
  content: { type: mongoose.SchemaTypes.String, required: true }
};

const collectionName = "notes"; // Name of the collection of documents
const noteSchema = mongoose.Schema(schema);
const Note = mongoose.model(collectionName, noteSchema);

// Export the Note model
export default Note;
Enter fullscreen mode Exit fullscreen mode

Setup the server and routes

Now that we have setup the database and user model, we can start creating the server and the routes for the API. We'll be creating the server with Express.

Let's install the dependencies

yarn add express body-parser cors
Enter fullscreen mode Exit fullscreen mode

After the dependencies have finished installing create the file index.js in 'src' with the code

// src/index.js
// Import the dependencies
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import Note from "./models/noteModel";

// Create a new instance of the express server
const app = express();

// Apply middleware
app.use(bodyParser.json({ type: "application/json" })).use(
  cors({
    methods: ["POST", "GET", "PUT", "DELETE"],
    allowedHeaders: [
      "Access-Control-Allow-Origin",
      "Content-Type",
      "x-access-token"
    ]
  })
);

/**
 * We'll define our routes here for the CRUD operations
 */

// Set port number
const portNo = process.env.PORT || 8080;

// Start server
app.listen(portNo, () => {
  console.log(`> Server listening at http://localhost:${portNo}`);
});
Enter fullscreen mode Exit fullscreen mode

Just to make sure what we've done so far works fine run yarn dev. If nothing's wrong it should show

> Server listening at http://localhost:8080
> successfully opened the database
Enter fullscreen mode Exit fullscreen mode

Let's stop the server with Ctrl+C and continue adding the routes in the API.

Our first route will be one to create new notes.

// Route to save a new note - POST method
app.post("/note", async (req, res) => {
  try {
    // Save note to DB
    const result = await Note.create({
      title: req.body.title,
      content: req.body.content
    });

    // Send the result of the save function as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});
Enter fullscreen mode Exit fullscreen mode

The next route will be to get the entire list of notes

// Route to get all the notes - GET method
app.get("/note", async (req, res) => {
  try {
    // Get all notes from the database
    const result = await Note.find({}).exec();

    // Send the results as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});
Enter fullscreen mode Exit fullscreen mode

We'll need a route to get a single note based on the ID.

// Route to get one note based on the ID - GET method
app.get("/note/:id", async (req, res) => {
  try {
    // Get the ID
    const id = req.params.id;

    // Find the note from the ID
    const result = await Note.findById(id).exec();

    // Send the result as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});
Enter fullscreen mode Exit fullscreen mode

The second to last route will be to update a note.

// Route to update a note - PUT method
app.put("/note/:id", async (req, res) => {
  try {
    // Get the ID
    const id = req.params.id;

    // Update the note
    const result = await Note.findByIdAndUpdate(id, {
      title: req.body.title,
      content: req.body.content
    }).exec();

    // Send the result as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});
Enter fullscreen mode Exit fullscreen mode

Our final route will be to delete a note.

// Route to delete a note - DELETE method
app.delete("/note/:id", async (req, res) => {
  try {
    // Get the ID
    const id = req.params.id;

    // Delete the note
    const result = await Note.findByIdAndDelete(id).exec();

    // Send the result as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});
Enter fullscreen mode Exit fullscreen mode

Finally index.js should look like this.

// src/index.js
// Import the dependencies
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import Note from "./models/noteModel";

// Create a new instance of the express server
const app = express();

// Apply middleware
app.use(bodyParser.json({ type: "application/json" })).use(
  cors({
    methods: ["POST", "GET", "PUT", "DELETE"],
    allowedHeaders: [
      "Access-Control-Allow-Origin",
      "Content-Type",
      "x-access-token"
    ]
  })
);

// Route to save a new note - POST method
app.post("/note", async (req, res) => {
  try {
    // Save note to DB
    const result = await Note.create({
      title: req.body.title,
      content: req.body.content
    });

    // Send the result of the save function as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});

// Route to get all the notes - GET method
app.get("/note", async (req, res) => {
  try {
    // Get all notes from the database
    const result = await Note.find({}).exec();

    // Send the results as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});

// Route to get one note based on the ID - GET method
app.get("/note/:id", async (req, res) => {
  try {
    // Get the ID
    const id = req.params.id;

    // Find the note from the ID
    const result = await Note.findById(id).exec();

    // Send the result as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});

// Route to update a note - PUT method
app.put("/note/:id", async (req, res) => {
  try {
    // Get the ID
    const id = req.params.id;

    // Update the note
    const result = await Note.findByIdAndUpdate(id, {
      title: req.body.title,
      content: req.body.content
    }).exec();

    // Send the result as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});

// Route to delete a note - DELETE method
app.delete("/note/:id", async (req, res) => {
  try {
    // Get the ID
    const id = req.params.id;

    // Delete the note
    const result = await Note.findByIdAndDelete(id).exec();

    // Send the result as the server response
    return res.json(result);
  } catch (error) {
    // Handle error
    // Display error in console
    console.log(error);
  }
});

// Set port number
const portNo = process.env.PORT || 8080;

// Start server
app.listen(portNo, () => {
  console.log(`> Server listening at http://localhost:${portNo}`);
});
Enter fullscreen mode Exit fullscreen mode

Wrapping up

I deliberately left out testing the API as I didn't want to make this post too long but you could use software like Postman or Insomnia to test the API.
My next post will be about creating a front-end with React to use with this API.
I hope you found this post useful. If you have any questions or suggestions on how I could improve this, leave a comment below! 😊

Top comments (5)

Collapse
 
talk2sohail profile image
Sohail • Edited

Your code is wonderful and comprehensive.
I have one question..
What is the purpose of 'cors' you used in index.js?
Thank you.

Collapse
 
akhilaariyachandra profile image
Akhila Ariyachandra

'cors' is needed if we're going to use the API from a different domain or port. Without 'cors' we won't be able to connect the API to any other apps, like the React app we're going to develop in the next post. As far as running the API in just this post, 'cors' isn't needed. Hope that helps!

Collapse
 
talk2sohail profile image
Sohail

Understood.
Thanks.

Collapse
 
syed456 profile image
syed

Hi Akhila Ariyachandra,
Please give me the link if you have made a next part of this series as you mentioned here
Thanks
Syed

Collapse
 
akhilaariyachandra profile image
Akhila Ariyachandra • Edited

Hi Syed, I just posted the second part on my blog.