Database
It is a place where data is stored persistently.
Databases were are created using protocols that browsers don’t understand.
Database supports 4 operations(CRUD):
Create
Read
Update
Delete
MongoDB
MongoDB is a popular, open-source, NoSQL database management system designed for handling large amounts of data in a flexible and scalable manner.
MongoDB stores data in flexible, JSON-like documents, which means fields can vary from document to document and data structure can be changed over time.
Let's create an app that stores todo list and user information.
File Structure:
Firstly we define the schema of the database in db.js file
// db.js
const mongoose = require('mongoose')
mongoose.connect('YOUR_MONGODB_URL')
const user = new mongoose.Schema({
email: String,
firstname: String,
lastname: String,
password: String
})
const todo = new mongoose.Schema({
userId:{
type: mongoose.Schema.types.objectId,
ref: 'user'
},
title: String,
completed: Boolean
})
const User = mongoose.model('User', user)
const Todo = mongoose.model('Todo', todo)
module.exports={
User,
Todo
}
Now next we have to create the routes.
First create index.js file.
// index.js
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
app.use(express.json())
app.listen(3000, ()=>{
console.log('Server running at 3000')
})
Create a config.js file to store your jwt secret key.
// config.js
module.exports={
JWT_SECRET: 'hello'
}
Let's setup user routes.
// routes/users.js
const express = require('express')
const router = express.Router()
const {User} = require('../db.js')
const {JWT_SECRET} = require('../config')
const zod = require('zod')
const jwt = require('jsonwebtoken')
const signupBody = zod.object({
email: zod.string().email(),
firstname: zod.string(),
lastname: zod.string(),
password: zod.string()
})
const signinBody = zod.object({
email: zod.string().email(),
password: zod.string()
})
router.post('/signup',async(req, res)=>{
const {success} = signupBody.safeParse(req.body)
if(!success){
return res.status(411).json({
message:'Email already taken'
})
}
const ExistingUser = await User.findOne({
email: req.body.email,
firstname: req.body.firstname,
lastname: req.body.lastname,
password: req.body.password
})
if(ExistingUser){
return res.status(411).json({
message: "Account already exists"
})
}
const user = await User.create({
email: req.body.email,
firstname: req.body.firstname,
lastname: req.body.lastname,
password: req.body.password
})
const userId = user._id
const token = jwt.sign({ userId },JWT_SECRET)
res.json({
message: "Account created successfully",
token: token
})
})
router.post('/signin', async(req, res)=>{
const {success} = signinBody.safeParse(req.body)
if(!success){
return res.status(411).json({
message: 'User does not exist'
})
}
const user = User.findOne({
email: req.body.email,
password: req.body.password
})
if(user){
const token = jwt.sign({ userId: user._id }, JWT_SECRET)
return res.status(200).json({
message: 'Sign in successful',
token: token
})
}
res.status(400).json({
message: 'Invalid email or password'
})
})
module.exports= router
Next we setup Todo routes. Before that we need to setup our middlewares.
// middleware.js
const {JWT_SECRET} = require('../config.js')
const jwt = jsonwentoken
const middleware = (req, res, next)=>{
const authHeader = req.headers.authorization
if(!authHeader || !authHeader.startsWith('Bearer')){
return req.status(400).json({
message:"Unauthorized"
})
}
const token = authHeader.split(' ')[1]
try{
const payload = jwt.verify(token, JWT_SECRET)
req.userId = payload.userId
next()
}catch(err){
return res.json({
message: 'Invalid'
})
}
}
module.exports = middleware
// routes/ todo.js
const express = require('express')
const {Todo} = require('../db')
const router = express.Router()
const {middleware} = require('../middleware')
router.post('/addTodo', async(req, res)=>{
const result = req.body
const todo =await Todo.create({
userId: req.userId,
title: req.title,
completed: req.completed
})
res.status(200).json({
message:"Todo addded"
result
})
})
router.get('/todolist', middleware, async(req, res)=>{
const todo = await Todo.find({
userId: req.userId
})
res.status(200).json({
todo
})
})
module.exports = router
Next we create index.js for router to route each request to their specific routes.
// routes/index.js
const express = require('express')
const userRouter = require('./users')
const todoRouter = require('./todo')
const router = express.Router()
router.use('/users', userRouter)
router.use('/todo', todoRouter)
module.exports = router
Then we can update our original index.js.
// index.js
const express = require('express')
const cors = require('cors')
const router = require('../routes/index')
const app = express()
app.use(cors())
app.use(express.json())
app.use('/api', router)
app.listen(3000, ()=>{
console.log('Server running at 3000')
})
Testing the backend.