coders gyan(rest api) ---> book library(1.1)
project setup
mkdir elib
cd elib
code .
# initialize a node project
npm init ---> manually answer all question asked during setup
or
npm init -y
# install typescript as Dependency(for development) --> not necessary for production
# node_module folder is created
npm i -D typescript ts-node nodemon @types/node
# initialize tsconfig file --> create tsconfig.json file
npx tsc --init
# git setup to push code
git init
#install gitignore extension
# create git ignore file (node_module) --> using extension gitignore
ctrl+shift+p --->(search .git) add gitignore --> node
git add .
git commit -m "setup typescript"
# add dev script in package.json --> to run server.ts file
"dev": "nodemon server.ts"
npm run dev
# setup eslint --> to avoid bad code practice -->create .eslintrc.json
npm i @eslint/config
how would you like to use eslint?
-> to check code syntax and find problems
what type of module your project use?
-> javascript (import/export) --> not require
which framework are you using?
-> none
does yyour project use typescript?
-> yes
what does your code run in ?
-> node
format of config file?
-> json
requre extra pacakge for tyoescript, install them now?
-> yes
which package manager do you want to use?
-> npm
git add .
git commit -m "add eslint"
#install eslint extension --> help you to give error while coding(follow best practise)
# setup prettier for text formatting
# install prettier extension
# create .pretter.json file in root directory
{
"tabWidth" : 2
}
crtl + , --> format on save --> checked
git add .
git commit -m "add prettier"
# setup express server
npm i express
npm i -D @types/express
// src/app.ts
import express from "express";
const app = express();
export default app;
// server.ts
import app from "./src/app";
import { config } from "./src/config/config";
const startServer = async () => {
const port = config.port || 3000;
app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
};
startServer();
git add .
git commit -m "add express"
# setup dotenv --> project config
npm i dotenv
npm i -D @types/dotenv
# create .env file on root
PORT=5513
// src/config/config.ts
import { config as conf } from "dotenv";
conf();
const _config = {
port: process.env.PORT,
};
# to make it read only
export const config = Object.freeze(_config);
git add .
git commit -m "add config"
# setup mongo db
npm i mongoose
npm i -D @types/mongoose # dont req to install types seperately(inbuilt)
// src/config/db.ts
import mongoose from "mongoose";
import { config } from "./config";
const connectDB = async () => {
try {
// listeners to be registered 1st (1)
mongoose.connection.on("connected", () => {
console.log("Connected to database successfully");
});
// listeners to be registered 1st (2)
// throws error on connection fail
mongoose.connection.on("error", (err) => {
console.log("Error in connecting to database.", err);
});
await mongoose.connect(config.databaseUrl as string);
} catch (err) {
// throws error on 1st connection fail
console.error("Failed to connect to database.", err);
process.exit(1);
}
};
export default connectDB;
// server.ts
import app from "./src/app";
import { config } from "./src/config/config";
import connectDB from "./src/config/db";
const startServer = async () => {
// Connect database
await connectDB();
const port = config.port || 3000;
app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
};
startServer();
git add .
git commit -m "add database setup"
# setup error handling -->
npm i http-errors
npm i -D @types/http-errors
Middleware
Request Handler
2 types: async and sync
Req : Client —> Router —> Middleware 1 (next()) —> Middleware2 (next())—> …. —> Request Handler
Res : Request Handler —> Client
if there is error in Request Handler Sync
Req : Client —> Router —> Middleware 1 (next()) —> Middleware2 (next())—> …. —> Request Handler —> Global Error Handler
Res : Global Error Handler —> Client
if there is error in Request Handler Async
Req : Client —> Router —> Middleware 1 (next()) —> Middleware2 (next())—> …. —> Request Handler (next(error)) —> Global Error Handler
Res : Global Error Handler —> Client
// src/midlewares/globalErrorHandler.ts
import { Request, Response, NextFunction } from "express";
import { HttpError } from "http-errors";
import { config } from "../config/config";
const globalErrorHandler = (
err: HttpError, // installed package
req: Request,
res: Response,
next: NextFunction
) => {
const statusCode = err.statusCode || 500;
return res.status(statusCode).json({
message: err.message,
errorStack: config.env === "development" ? err.stack : "",//we dont want to expose errorStack on production
});
};
export default globalErrorHandler;
// app.ts
import express, { NextFunction, Request, Response } from "express";
import globalErrorHandler from "./middlewares/globalErrorHandler";
import { config } from "./config/config";
const app = express();
// Routes
// Http methods: GET, POST, PUT, PATCH, DELETE
app.get("/", (req, res, next) => {
res.json({ message: "Welcome to elib apis" });
});
// Global error handler
app.use(globalErrorHandler);
export default app;