An Interest In:
Web News this Week
- April 19, 2024
- April 18, 2024
- April 17, 2024
- April 16, 2024
- April 15, 2024
- April 14, 2024
- April 13, 2024
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:
- Express
- MongoDB // we can use MySQL, PostgreSQL etc
- Node
This is the architecture we are trying to achieve:
On the root folder of the directory (blog-vue-application) that we created in the first tutorial.
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
Once done install the following packages
- express
- cors
- node
- body-parser
- mongoose
- mongodb // will be using for testing purposes
- jest // you can use a different testing
- dotenv
$ npm install express mongoose mongodb cors body-parser node express dotenv
Install the nodemon package as a dependency so you don't have to restart your server.
$ npm install -D nodemon
These are APIs that Node.js Express App will export:
Methods | URL | Actions |
---|---|---|
GET | api/blog | get many blogs |
GET | api/blog/:id | get a single blog |
POST | api/blog | create blog |
PUT | api/blog | update blog |
DELETE | api/blog | remove many blogs |
DELETE | api/blog/:id | remove single blog |
This is how your application structure should be:
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" }}
Create an index.js file in the backend folder. This will be the entry point for our application.
$ touch index.js
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}.`);});
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
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
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};
/app/controller/blog.controller.js
In this directory we will define how we want to handle the following actions:
- create
- findAll
- findOne
- update
- delete
- 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." }); });};
/app/model/index.js
In this directory, we are going to assemble the following files:
- /app/config/db.config
- /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;
/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; };
/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
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
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
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;};
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
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To