Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 31, 2021 11:39 am GMT

MongoDB, Express, Vue, and Node.

In our previous tutorial, we wanted to practically learn and understand the serverless, container, and server approaches https://dev.to/kevin_odongo35/serverless-container-or-server-approach-4mh5. This tutorial will be fun, a step by step guide.

In today's tutorial, we are going to handle the first approach of using the following:

  1. Express
  2. MongoDB // we can use MySQL, PostgreSQL etc
  3. Node

This is the architecture we are trying to achieve:

Alt Text

On the root folder of the directory (blog-vue-application) that we created in the first tutorial.

Alt Text

Run the following commands in the root folder:

$ mkdir blog-vue-back-end && cd blog-vue-back-end$ npm initpackage name: blog-vue-back-endversion: // press enterdescription: Tutorialentry point: index.jstest command: // press entergit repository: // press enterkeywords: Mongo DB, Node, Passport and Expressauthor: your namelicence: MIT// save
Enter fullscreen mode Exit fullscreen mode

Once done install the following packages

  1. express
  2. cors
  3. node
  4. body-parser
  5. mongoose
  6. mongodb // will be using for testing purposes
  7. jest // you can use a different testing
  8. dotenv
$ npm install express mongoose mongodb cors body-parser node express dotenv
Enter fullscreen mode Exit fullscreen mode

Install the nodemon package as a dependency so you don't have to restart your server.

$ npm install -D nodemon
Enter fullscreen mode Exit fullscreen mode

These are APIs that Node.js Express App will export:

MethodsURLActions
GETapi/blogget many blogs
GETapi/blog/:idget a single blog
POSTapi/blogcreate blog
PUTapi/blogupdate blog
DELETEapi/blogremove many blogs
DELETEapi/blog/:idremove single blog

This is how your application structure should be:

Alt Text

package.json

Once we have installed everything, update the sections of the script. This is how your package.js file should be:

{  "name": "blog-vue-back-end",  "version": "1.0.0",  "description": "Tutorial Backend for Blog Application",  "main": "index.js",  "scripts": {    "start": "node server/index.js",    "dev": "nodemon server/index.js",    "test-dev": "jest"  },  "keywords": [    "Mongo",    "DB",    "Express",    "Node"  ],  "author": "Kevin Odongo",  "license": "MIT",  "dependencies": {    "@shelf/jest-mongodb": "^1.2.3",    "body-parser": "^1.19.0",    "cors": "^2.8.5",    "dotenv": "^8.2.0",    "express": "^4.17.1",    "jest": "^26.6.3",    "mongodb": "^3.6.3",    "mongoose": "^5.11.14"  },  "devDependencies": {    "nodemon": "^2.0.7"  }}
Enter fullscreen mode Exit fullscreen mode

Create an index.js file in the backend folder. This will be the entry point for our application.

$ touch index.js
Enter fullscreen mode Exit fullscreen mode

index.js

const express = require("express");const bodyParser = require("body-parser");const cors = require("cors");require('dotenv').config()const app = express();// parse application/jsonapp.use(bodyParser.json())// parse application/x-www-form-urlencodedapp.use(bodyParser.urlencoded({ extended: true }))var corsOptions = {  origin: 'http://localhost:3000'}// use cors optionsapp.use(cors(corsOptions))// const db = require("./app/models");db.mongoose  .connect(db.url, {    useNewUrlParser: true,    useUnifiedTopology: true,    useFindAndModify: false,    useCreateIndex: true  })  .then(() => {    console.log("Connected to the database!");  })  .catch(err => {    console.log("Cannot connect to the database!", err);    process.exit();  });// routesconst blog = require('./app/routes/blog')app.use('/api/blog', blog)// listening portconst PORT = process.env.PORT || 3000;app.listen(PORT, () => {    console.log(`Server is running on port ${PORT}.`);});
Enter fullscreen mode Exit fullscreen mode

Once we have an entry point for our application let us initialize Mongo DB.

Create a file .env in the root folder

$ touch .env// add the followingMONGO_DB_URI = mongodb+srv://odongo:[email protected]/blog?retryWrites=true&w=majority
Enter fullscreen mode Exit fullscreen mode

To get your mongodb url register for a free account here https://account.mongodb.com/account/register. Once you register create a cluster, user, and database.

Add node modules and .env file in the .gitignore file.

$ touch .gitignore// add the followingnode_modules# local env files.env.local.env.*.local
Enter fullscreen mode Exit fullscreen mode

Create a directory called app that will hold the following files.

/app/config/db.config.js

Expose the Mongo DB URI from your environment file

module.exports = {  url: process.env.MONGO_DB_URI};
Enter fullscreen mode Exit fullscreen mode

/app/controller/blog.controller.js

In this directory we will define how we want to handle the following actions:

  1. create
  2. findAll
  3. findOne
  4. update
  5. delete
  6. deleteAll
const db = require("../models");const Blog = db.blog;// Create and Save a new blogexports.create = (req, res) => {    // Validate request  if (!req.body.content) {    res.status(400).send({ message: "Content can not be empty!" });    return;  }  // Create a blog  const blog = new Blog({    author: req.body.author,    content: req.body.content,    published: req.body.published ? req.body.published : false  });  // Save blog in the database  blog    .save(blog)    .then(data => {      res.send(data);    })    .catch(err => {      res.status(500).send({        message:          err.message || "Some error occurred while creating the blog."      });    });};// Retrieve all blogs from the database.exports.findAll = (req, res) => {    const content = req.query.content;    var condition = content ? { content: { $regex: new RegExp(content), $options: "i" } } : {};    Blog.find(condition)      .then(data => {        res.send(data);      })      .catch(err => {        res.status(500).send({          message:            err.message || "Some error occurred while retrieving blogs."        });      });};// Find a single blog with an idexports.findOne = (req, res) => {    const id = req.params.id;    Blog.findById(id)      .then(data => {        if (!data)          res.status(404).send({ message: "Not found blog with id " + id });        else res.send(data);      })      .catch(err => {        res          .status(500)          .send({ message: "Error retrieving blog with id=" + id });      });};// Update a blog by the id in the requestexports.update = (req, res) => {    if (!req.body) {        return res.status(400).send({          message: "Data to update can not be empty!"        });      }      const id = req.params.id;      Blog.findByIdAndUpdate(id, req.body, { useFindAndModify: false })        .then(data => {          if (!data) {            res.status(404).send({              message: `Cannot update Blog with id=${id}. Maybe Blog was not found!`            });          } else res.send({ message: "Blog was updated successfully." });        })        .catch(err => {          res.status(500).send({            message: "Error updating Blog with id=" + id          });        });};// Delete a blog with the specified id in the requestexports.delete = (req, res) => {    const id = req.params.id;    Blog.findByIdAndRemove(id)      .then(data => {        if (!data) {          res.status(404).send({            message: `Cannot delete Blog with id=${id}. Maybe Blog was not found!`          });        } else {          res.send({            message: "Blog was deleted successfully!"          });        }      })      .catch(err => {        res.status(500).send({          message: "Could not delete Tutorial with id=" + id        });      });};// Delete all blogs from the database.exports.deleteAll = (req, res) => {    Blog.deleteMany({})    .then(data => {      res.send({        message: `${data.deletedCount} Blogs were deleted successfully!`      });    })    .catch(err => {      res.status(500).send({        message:          err.message || "Some error occurred while removing all blogs."      });    });};// Find all published blogsexports.findAllPublished = (req, res) => {    Blog.find({ published: true })    .then(data => {      res.send(data);    })    .catch(err => {      res.status(500).send({        message:          err.message || "Some error occurred while retrieving blogs."      });    });};
Enter fullscreen mode Exit fullscreen mode

/app/model/index.js

In this directory, we are going to assemble the following files:

  1. /app/config/db.config
  2. /app/model/blog.model.js

Ensure you import this directory in your index file and connect to your Mongo DB.

const dbConfig = require("../config/db.config");const mongoose = require("mongoose");mongoose.Promise = global.Promise;const db = {};db.mongoose = mongoose;db.url = dbConfig.url;db.blog = require("./blog.model.js")(mongoose);module.exports = db;
Enter fullscreen mode Exit fullscreen mode

/app/model/blog.model.js

Our blog schema will be in this directory.

module.exports = mongoose => {    const Blog = mongoose.model(      "blog",      mongoose.Schema(        {          author: String,          content: String,          published: Boolean        },        { timestamps: true }      )    );    // We can add a category to categorize articles    // Incase you want to replace _.id with id     // schema.method("toJSON", function() {    //   const { __v, _id, ...object } = this.toObject();    //   object.id = _id;    //   return object;    // });    // const Blog = mongoose.model("blog", schema);    return Blog;  };
Enter fullscreen mode Exit fullscreen mode

/app/routes/blog.js

This will handle all our routes. Ensure you export this file in the index.js file.

const express = require("express")const router = express.Router()const blog = require("../controller/blog.controller");// /api/blog: GET, POST, DELETE// /api/blog/:id: GET, PUT, DELETE// /api/blog/published: GET// Create a new blogrouter.post("/", blog.create);// Retrieve all blogrouter.get("/", blog.findAll);// Retrieve all published blogrouter.get("/published", blog.findAllPublished);// Retrieve a single blog with idrouter.get("/:id", blog.findOne);// Update a Tutorial with idrouter.put("/:id", blog.update);// Delete a Tutorial with idrouter.delete("/:id", blog.delete);// Create a new Tutorialrouter.delete("/", blog.deleteAll);module.exports = router
Enter fullscreen mode Exit fullscreen mode

Now that we have our backend ready we can integrate the backend and the front-end. You can test your routes using postman or any other tool out there.

Remember our routes are currently not protected therefore you can not go to production like this. We will need to protect our routes and add authentication to our application. In the next article, we are going to handle this.

Open your front-end directory in a new window of vs-code or whatever text editor you are using and run the application.

$ cd .. && cd /blog-vue-front-end$ npm run serve// Your front-end will be running on PORT 8080 || PORT 8081// Your back-end will be running on PORT 3000
Enter fullscreen mode Exit fullscreen mode

Once the application is running let us create the following file in the components folder:

/components/mongo-express-script.js

This will hold all our requests to the backend for mongo-express-script.js.

Install axios in the front-end

$ yarn add axios
Enter fullscreen mode Exit fullscreen mode

In the mongo-express-script.js file add the following:

import axios from "axios";// create new blogexport const createnewblog = async item => {  let data = {    author: JSON.stringify({      name: item.author.name,      email: item.author.email,      about: item.author.about    }), // replace with auth user    content: JSON.stringify({      title: item.content.title,      src: item.content.src,      text: item.content.text    })  };  let request = {    url: "http://localhost:3000/api/blog", // should be replaced after going to production with domain url    method: "post",    headers: {      "Content-type": "application/json"    },    data: JSON.stringify(data)  };  const response = await axios(request);  return response;};// delete blogexport const deleteblog = async item => {  let request = {    url: "http://localhost:3000/api/blog/" + item, // should be replaced after going to production with domain url    method: "delete",    headers: {      "Content-type": "application/json"    }  };  const response = await axios(request);  return response;};// update blogexport const updateblog = async item => {  let data = {    author: JSON.stringify({      name: item.author.name,      email: item.author.email,      about: item.author.about    }), // replace with auth user    content: JSON.stringify({      title: item.content.title,      src: item.content.src,      text: item.content.text    }),    published: item.published  };  let request = {    url: "http://localhost:3000/api/blog/" + item._id, // should be replaced after going to production with domain url    method: "put",    headers: {      "Content-type": "application/json"    },    data: JSON.stringify(data)  };  const response = await axios(request);  return response;};// get all blogexport const retriveallblog = async () => {  let request = {    url: "http://localhost:3000/api/blog", // should be replaced after going to production with domain url    method: "get",    headers: {      "Content-type": "application/json"    }  };  const response = await axios(request);  return response;};
Enter fullscreen mode Exit fullscreen mode

Here is how the blog should be working currently with your backend setup. We have completed the integration. Ensure your backend and front end are running concurrently.

What's next?. We need to protect our routes and authentication and go to production.

Here is a repo for the backend https://github.com/kevinodongo/tutorial-blog-backend.git.

Currently, we have not gone to production yet and therefore we can still use the Container or Server approach.

Thank you


Original Link: https://dev.to/kevin_odongo35/mongodb-express-vue-and-node-2cml

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To