You can use it for your project. If it is useful for you,
don't forget to give me a GitHub star, please.
In this node/express template
- Express framework
- Typescript
- DB - MySQL or PostgreSQL
- Prisma ORM
- REST api
- JWT auth
- bcrypt
- express-validator
- error handler
- file uploading
- Authorization
- Pagination ( offset-based & cursor-based ) etc.
In order to use it,
Create a .env file and add this.
For MySQL
DATABASE_URL="mysql://username:password@localhost:3306/mydb"
TOKEN_SECRET="something hard to guess"
For PostgreSQL
DATABASE_URL="postgresql://username:password@localhost:5432/mydb?schema=public"
TOKEN_SECRET="something hard to guess"
Please note.
TOKEN_SECRET should be complex and hard to guess.
If you use file uploading feature in this kit,
create nested folders uploads/images
in the root directory.
But making directories is up to you. You can configure in src/middlewares/uploadFile.js
.
For large projects, it is the best solution to use aws S3, DigitalOcean space, etc.,
instead of using file system.
mkdir lucky
cd lucky
git clone https://github.com/Bonekyaw/node-express-prisma-rest.git .
rm -rf .git
npm install
npm run dev
Before you run, make sure you've created .env file and completed required information.
I'm trying best to provide the latest version. But some packages may not be latest after some months. If so, you can upgrade manually one after one, or you can upgrade all at once.
npm install -g npm-check-updates
npm outdated
ncu --upgrade
npm install
If you find some codes not working well, please let me know your problems.
List of available routes:
POST /api/v1/register
- Register
POST /api/v1/verify-otp
- Verify OTP
POST /api/v1/confirm-password
- Confirm password
POST /api/v1/login
- Login
POST /api/v1/refresh-token
- Refresh for expired Token
PUT /api/v1/admins/upload
- Uploading file or files
GET /api/v1/admins
- Get admins' list by pagination
Auth routes:
POST /api/v1/register
- Register
Request
{
"phone": "0977******7"
}
Response
{
"message": "We are sending OTP to 0977******7.",
"phone": "77******7",
"token": "3llh4zb6rkygbrah5demt7"
}
POST /api/v1/verify-otp
- Verify OTP
Request
{
"phone": "77******7",
"token": "3llh4zb6rkygbrah5demt7",
"otp": "123456"
}
Response
{
"message": "Successfully OTP is verified",
"phone": "77******7",
"token": "xdyj8leue6ndwqoxc9lzaxl16enm0gkn"
}
POST /api/v1/confirm-password
- Confirm password
Request
{
"token": "xdyj8leue6ndwqoxc9lzaxl16enm0gkn",
"phone": "77******7",
"password": "12345678"
}
Response
{
"message": "Successfully created an account.",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWIwZDhmNmUwNGJiOGMzNWY0MTlkNiIsImlhdCI6MTcxNzI0MzI4MCwiZXhwIjoxNzE3MjQ2ODgwfQ.dvJT2UsGsC1za3lhcu3b3OrMR8BCIKvSlbiIgoBoLJQ",
"user_id": "1",
"randomToken": "p1jlepl7t7pqcdgg1sm0crbgbodi67auj"
}
POST /api/v1/login
- Login
Request
{
"phone": "0977******7",
"password": "12345678"
}
Response
{
"message": "Successfully Logged In.",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NTVlMDI5NzE2ZjljYTU1NTRjYTU4NCIsImlhdCI6MTcxNzQwMjQ1OSwiZXhwIjoxNzE3NDA2MDU5fQ.tZNAwjt4rM3tiZgl1LdwfYScbPqoOnMTtaKOTI1pEXY",
"user_id": "1",
"randomToken": "25uzndvz1lzu65fpjn9b6suaxj8gm91k"
}
Refresh routes:
POST /api/v1/refresh-token
- Refresh for expired Token
Request with Authorization Header
{
"user_id": "1",
"randomToken": "b6x9na0z5abc7wix1t2ojj5hdkk7aosm6"
}
Response
{
"message": "Successfully sent a new token.",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NTgzODYyNzliMmEzZjEzNDZhYjAwZCIsImlhdCI6MTcxNzA1NzY5NiwiZXhwIjoxNzE3MDYxMjk2fQ.4QyftFaMZE7MT_odGdP8yWsGrclaMstc_867PvTfV88",
"user_id": "1",
"randomToken": "x3y20n178w8m6fwptxx5pdwqao8ihpsl"
}
File Upload routes:
PUT /api/v1/admins/upload
- Uploading file or files
Request with Authorization Header
Body form-data Key = avatar
Pagination routes:
GET /api/v1/admins
- Get admins' list by pagination
Request with Authorization Header
Params Key = page, limit (OR) cursor, limit
When you add other route files, you can also create routes/v1/api
routes/v1/web
folders and use prefix for route defination. for example,
const adminRoutes = require("./routes/v1/web/admin");
...
app.use("/v1/admins", isAuth, authorise(true, "admin"), adminRoutes);
Hey, you see the words: isAuth
& authorise
?
Yeah, these are custom middlewares. You can create and use them by yourself. I will show how to use my sample authorization middleware.
Authorization as a middleware
const authorise = require('./middlewares/authorise');
...
app.use("/api/v1", isAuth, authorise(true, "admin"), adminRoutes);
router.get('/admins', authorise(true, "admin"), adminController.index);
Authorization as a function
const authorise = require("./../utils/authorise");
...
authorise(true, user, "admin");
true, "admin"
means the account is allowed only if its role is "admin". false, "user"
means the account is not allowed if its role is "user".
ture, "admin"
=== false, "user", "supplier"
false, "user"
=== true, "admin", "supplier"
true, user, "admin"
In these parameters, user param is an instance model of the database table.
There are two ways in pagination: offset-based and cursor-based. You can read more about pros and cons here. But you can use my pagination logic very easily.
For offset-based
const { offset, noCount, cursor } = require("./../utils/paginate");
...
const { page, limit } = req.query;
const filters = { status: "active" };
const order = { createdAt: "desc" };
const fields = {
id: true,
name: true,
phone: true,
role: true,
status: true,
lastLogin: true,
profile: true,
createdAt: true,
};
const admins = await offset(
prisma.admin,
page,
limit,
filters,
order,
fields,
);
res.status(200).json(admins);
For cursor-based
const { offset, noCount, cursor } = require("./../utils/paginate");
...
const cursors = req.query.cursor ? { id: +req.query.cursor } : null;
const limit = req.query.limit;
const filters = { status: "active" };
const order = { createdAt: "desc" };
const fields = {
id: true,
name: true,
phone: true,
role: true,
status: true,
lastLogin: true,
profile: true,
createdAt: true,
};
const admins = await cursor(
prisma.admin,
cursors,
limit,
filters,
order,
fields
);
res.status(200).json(admins);
I promise new features will come in the future if I have much time.
If you have something hard to solve,
DM
phonenai2014@gmail.com
https://www.facebook.com/phonenyo1986/
https://www.linkedin.com/in/phone-nyo-704596135
Nest JS for REST Api
Nest JS + Prisma ORM - REST api
Nest JS for Graphql Api
Nest JS + Prisma ORM - Graphql api
Node Express JS For REST Api
Express + Prisma ORM + mongodb - rest api
Express + Prisma ORM + SQL - rest api - Now you are here
Express + mongodb - rest api
Express + mongoose ODM - rest api
Express + sequelize ORM - rest api
Node Express JS For Graphql Api
Apollo server + Prisma ORM + SDL modulerized - graphql api
Express + Prisma ORM + graphql js SDL modulerized - graphql api
Express + Apollo server + mongoose - graphql api
Express + graphql js + mongoose - graphql api
Express + graphql js + sequelize ORM - graphql api
Mobile App Development