A Step By Step Guide On How I Built A Blogging Api.
This is actually my very first API to be deployed to the cloudš.
This piece, asides from the obvious purpose of helping a beginner out there, it would also serve as a way of measuring how far Iāve come in my journey as a "backend developer". Iād look back to this in a few years and smile at how far Iāve come.š
In this tutorial article, I'd show you how I built a Blogging API using Nodejs, Express, and MongoDB, and wrote tests for them using jest and super test. Here are some of the features and requirements we would be implementing in this Project. Itemizing them would help us carefully implement all of them.
Features/Requirements for the Blogging API;
Users must signup with :
a. First_name(required)
b. Last_name(required)
c. Email(required)
d. Password(required)
Users must log in with :
a. Email
b. Password for login
Authenticated users can create blog posts.
Blog created must have:
a. Title
b. Description
c. Tags
d. Author
e. State(draft and published)
f. Read_count
g. Read_time(use Algorithm for calculating reading_tme)
h. Body.
Users can get all published blogs (whether login or logout).
The owner of the blog can edit both the published blog and draft blog, delete it, also view all its blogs.
The owner of the blog should be able to get a list of their blogs.
a. The endpoint should be paginated.
b. It should be filterable by state.
Tools to use
a. Apply JWT Authentication and expire after one hour.
b. Apply Pagination: each page should contain 20 blogs per page.
Blog Features
A page should contain 20blogs
A blog should be searchable by author, title and tags
A blog should be ordered by read_count, read_time and timestamp
getById should return the author information with the blog and the read_count should be updated by one.
Now let us dive into developing the project after which we deploy our server to the cloud. This will be a pretty long tutorial and it'll be best to split it into parts one and two. Part one will cover the following areas:
Create a MongoDB database URL
Set up the development environment and define the project file structure
Install dependencies and configure package.json
Set up the server, and
Connect to MongoDB database URL
You can find the source code for this tutorial in my GitHub repo here .
Create a MongoDB database URL
To kickstart our project our very first task in this section is to create a database with MongoDB and get the connection URL which we will integrate into our code subsequently. The following steps will help us achieve this:
If you can obtain a MongoDB connection URL on your own, you can skip this sectionš
Firstly, create an account with MongoDB on their official website here or if you have an account already, just sign in.
Secondly, create a new organization and a new project. Your database will live in this new project you just created.
Now after creating a new project, youāll be required to choose a plan/cluster. For this tutorial, Iāll be making use of the shared cluster which is free. It is okay for this use case.
On the next page, select a suitable cloud provider region. You might want to choose the one closest to you. I chose the default AWS service and clicked on the create button just below it. Note: This stage may take some time.
After creating the cluster, navigate to the connect tab and click on it. You may need to add your IP address before you continue. Create a database user by supplying your username and password. Click on the create database user button below and then click on the Choose a connection method button. On the next page, there are three options. For this tutorial, I chose the second option, connect your application. Copy the database URL provided there.
The URL should look similar to:
mongodb+srv://Godsent-Michael:<password>@cluster0.3fre0mm.mongodb.net/?retryWrites=true&w=majority
- Finally, enter your database password. This is our database URL.
Setting up the development environment
In order to achieve our aim in this section you must have a basic knowledge of creating and cloning a GitHub repository. You will also need to have Node and npm installed in your system.
Now we create a GitHub repository and clone it into our local machine. Then open your code editor or terminal and cd into the Git directory you just cloned.
In order to create a project in this directory, we'll need to create a file named package.json, which will hold all our dependencies and some key commands. To create this file, run the following command in your terminal:
npm init-y
The command shown above initiates a package.json file in the root directory of our project. In the package.json file, change the value of the main field to index.js. You should have something similar to the following:
"name": "blogging-api",
"version": "1.0.0",
"description": "blogging API",
"main": "index.js",
"scripts": {
"start": "nodemon index.js"
...
Now, we need to set up our folder structure.
Create an index.js. file. This file will contain codes firing up our server.
Next, we need to create some directories inside our root directory. These directories are controller, model, routes, middlewares, logger, tests.
Create a db.js file this file is where we implement our database configuration.
The controller directory will contain all our functions.
The model directory will contain a userModel.js file that will define the structure and attributes of each user weāll create. More on this later.
The routes directory will contain the various HTTP request methods that weāll be using to interact with the API.
The tests directory will contain the tests weāll be writing to test our API.
Finally, create a .env file in the root of your directory. This file will contain our environmental variables like the database URL we created a while ago.
Install dependencies and configure package.json
Next, we need to install all the dependencies we'll need for this project. Run the following command in your terminal:
npm install mongoose dotenv express mongoose bcrypt --save
This command will install these packages as core dependencies because of the --save flag.
We also need to install some other packages that are important for developmental purposes. Run the following command in your terminal:
npm install nodemon passport passport-jwt winston logger joi --save-dev
The --save-dev flag will install these dependencies as development dependencies (devDependencies), signifying their purpose.
Set up the Server
Open the index.js file you created and add the following code snippets.
const express = require("express");
const dotenv = require("dotenv").config();
const app = express()
app.use(express.static('public'));
app.use(express.json())
//Home route
app.get('/', (req, res) => {
res.send('Welcome to the blog API');
});
app.use('*', (req, res) => {
return res.status(404).json({ message: 'route not found' })
})
// Start server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}....!`);
});
From the above code snippet, you can see we required and initialized our packages (express, dotenv), Then we defined our port, which is where our server will be listening to. To start our server, run the following command:
npm start
Now your server should start in development mode on the specified port in the .env file or port 5000. You should see Server is running on port 5000....! printed out in your terminal. This means your server started successfully. Navigating to localhost:5000 in your browser should have āWelcome to the blog APIā displayed on your screen.
Connecting the server with the database URL
In the .env file you created earlier, paste your database URL as follows:
DEV_MONGODB_URI=mongodb+srv://Godsent-Michael:<password>@cluster0.3fre0mm.mongodb.net/?retryWrites=true&w=majority
TEST_MONGODB_URI=mongodb+srv://Godsent-Michael:<password>@cluster0.3fre0mm.mongodb.net/?retryWrites=true&w=majority
Of course, your dbname can be anything of your choosing, but ensure you have two different database names for the two environments we'll be working in, namely: test and development environments. That said, let's go on to configure our database connection. This will be done in a db.js file we created earlier. Paste the following code snippets in your db.js file:
const mongoose = require("mongoose")
require("dotenv").config()
const MONGODB_URI = process.env.MONGODB_URI
//connect to mongoDB
function connectToMongoDB(){
mongoose.connect(MONGODB_URI)
mongoose.connection.on('connected', ()=> {
console.log('Connected to MongoDB succesfully');
})
mongoose.connection.on('error', (err)=>{
console.log('Error connecting to the MongoDB', err);
})
}
module.exports = {connectToMongoDB}
First, we required/imported mongoose and dotenv. Mongoose will be used to establish a connection and communicate with MongoDB. Dotenv is required to access our environmental variables(database URLs) in the .env file. Next, we initialized dotenv. Next, we create a function (connectToMongoDB) thatāll be called when we need to establish a connection. We then call the 'mongoose.connection' module with the 'on' listener, this should help us connect to the MongoDB database. We console.log the 'connection successful message',to notify us that we've succesfully made a connection to our database. Also, repeat the process to display an error in your terminal.
Next, we connect our server to our database, by requiring/importing the connectToMongoDB function in index.js. Importing and calling the connectToMongoDB function in our index.js file should have the file look like the following:
const express = require("express");
const dotenv = require("dotenv").config();
const { connectToMongoDB } = require("./db");
const app = express()
app.use(express.static('public'));
app.use(express.json())
//connecting to MonGoDB Instance
connectToMongoDB();
//Home route
app.get('/', (req, res) => {
res.send('Welcome to the blog API');
});
app.use('*', (req, res) => {
return res.status(404).json({ message: 'route not found' })
})
// Start server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}....!`);
});
Start up your server by running the following code:
npm run start
You should have results similar to the image below printed in your terminal:
Summary
Clearly we have successfully achieved our aim for this part. In the part two, we will go straight into writing more codes to create our business model, methods, and functions. Stay tuned š