Skip to content

Commit

Permalink
Refactor to basics and Redis Cache with user ID
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronak Bokaria committed Oct 18, 2020
1 parent fe44e07 commit 2bf6493
Show file tree
Hide file tree
Showing 22 changed files with 183 additions and 230 deletions.
30 changes: 15 additions & 15 deletions app/controllers/categoriesController.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import APIError from '../services/error.js';
import Category from '../models/Category.js';
const APIError = require('../services/error.js');
const Category = require('../models/Category.js');

export async function index(req, res, next) {
exports.index = async function index(req, res, next) {
try {
const category = await req.paginationProcess(Category.find());
apiResponse.successResponseWithData(res, 'Category', category);
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function store(req, res, next) {
exports.store = async function store(req, res, next) {
try {
const category = await Category.create(req.body);
apiResponse.successResponseWithData(
Expand All @@ -21,30 +21,30 @@ export async function store(req, res, next) {
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function show(req, res, next) {
exports.show = async function show(req, res, next) {
try {
const category = await Category.findById(req.params.id);
apiResponse.successResponseWithData(res, 'Category', category.toJSON());
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function edit(req, res, next) {
exports.edit = async function edit(req, res, next) {
try {
const category = await Category.findById(req.params.id);
apiResponse.successResponseWithData(res, 'Category', category.toJSON());
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function update(req, res, next) {
exports.update = async function update(req, res, next) {
try {
let category = await Category.findById(req.params.id);
for(var field in req.body) {
for (var field in req.body) {
category[field] = req.body[field];
}
await category.save();
Expand All @@ -53,13 +53,13 @@ export async function update(req, res, next) {
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function destroy(req, res, next) {
exports.destroy = async function destroy(req, res, next) {
try {
await Category.findOneAndDelete({ _id: req.params.id });
apiResponse.successResponse(res, 'Category deleted.');
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};
28 changes: 14 additions & 14 deletions app/controllers/productsController.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import APIError from '../services/error.js';
import Product from '../models/Product.js';
const APIError = require('../services/error.js');
const Product = require('../models/Product.js');

export async function index(req, res, next) {
exports.index = async function index(req, res, next) {
try {
const product = await req.paginationProcess(Product.find());
apiResponse.successResponseWithData(res, 'Product', product);
} catch (err) {
console.log(err);
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function store(req, res, next) {
exports.store = async function store(req, res, next) {
try {
const product = await Product.create(req.body);
apiResponse.successResponseWithData(
Expand All @@ -23,41 +23,41 @@ export async function store(req, res, next) {
console.log(err);
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function show(req, res, next) {
exports.show = async function show(req, res, next) {
try {
const product = await Product.findById(req.params.id);
apiResponse.successResponseWithData(res, 'Product', product.toJSON());
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function edit(req, res, next) {
exports.edit = async function edit(req, res, next) {
try {
const product = await Product.findById(req.params.id);
apiResponse.successResponseWithData(res, 'Product', product.toJSON());
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function update(req, res, next) {
exports.update = async function update(req, res, next) {
try {
let product = await Product.findOneAndUpdate({ _id: req.params.id }, req.body);
product = await Product.findById(req.params.id);
apiResponse.successResponseWithData(res, 'Product', product.toJSON());
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function destroy(req, res, next) {
exports.destroy = async function destroy(req, res, next) {
try {
await Product.findOneAndDelete({ _id: req.params.id });
apiResponse.successResponse(res, 'Product deleted.');
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};
16 changes: 8 additions & 8 deletions app/controllers/userController.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import APIError from '../services/error.js';
import User from '../models/User.js';
const APIError = require('../services/error.js');
const User = require('../models/User.js');

export async function register(req, res, next) {
exports.register = async function register(req, res, next) {
try {
const user = await User.create(req.body);
apiResponse.successResponseWithData(
Expand All @@ -12,9 +12,9 @@ export async function register(req, res, next) {
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function login(req, res, next) {
exports.login = async function login(req, res, next) {
try {
const email = req.body.email;
const user = await User.findOne({ email });
Expand All @@ -30,13 +30,13 @@ export async function login(req, res, next) {
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};

export async function index(req, res, next) {
exports.index = async function index(req, res, next) {
try {
const users = await req.paginationProcess(User.find());
apiResponse.successResponseWithData(res, 'Users', users);
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}
};
24 changes: 15 additions & 9 deletions app/middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
import jwt from 'jsonwebtoken';
import config from '../../config/env/index.js';
import APIError from '../services/error.js';
import User from '../models/User.js';
const jwt = require('jsonwebtoken');
const config = require('../../config/env/index.js');
const APIError = require('../services/error.js');
const User = require('../models/User.js');

export async function checkToken(req, res, next) {
async function checkToken(req, res, next) {
try {
let token = req.headers['x-access-token'] || req.headers['authorization'];
if (token.startsWith('Bearer ')) {
// Remove Bearer from string
// Remove Bearer = require( string
token = token.slice(7, token.length);
}
if (token) {
jwt.verify(token, config.JWT_SECRET, async (err, decoded) => {
if (err) {
apiResponse.expiredAuthResponse(res, 'Token is invalid, Please refresh token or Authenticate again');
apiResponse.expiredAuthResponse(
res,
'Token is invalid, Please refresh token or Authenticate again',
);
} else {
const user = await User.findById(decoded._id);
req.User = user;
next();
}
});
} else {
apiResponse.unauthorizedResponse(res, 'Token Missing, Please check headers or Authenticate to obtain new token');
apiResponse.unauthorizedResponse(
res,
'Token Missing, Please check headers or Authenticate to obtain new token',
);
}
} catch (err) {
next(new APIError(null, apiResponse.API_STATUS.UNPROCESSABLE_ENTITY, true, err));
}
}

export default checkToken;
module.exports = checkToken;
93 changes: 51 additions & 42 deletions app/middlewares/pagination.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,54 @@
export async function pagination(req, res, next) {
let paginationDetails = {
page:0,
limit: 50,
orderBy: 'createdAt',
orderAsc: false,
};
if(req.query.no_limit) {
paginationDetails = null;
} else {
if(req.query.page){
paginationDetails.page = parseInt(req.query.page<=1?0:req.query.page-1);
}
if(req.query.limit){
paginationDetails.limit = parseInt(req.query.limit>0?req.query.limit:50);
}
if(req.query.orderBy){
paginationDetails.orderBy = req.query.orderBy;
}
if(req.query.orderAsc){
paginationDetails.orderAsc = req.query.orderAsc==false?-1:1;
}
async function pagination(req, res, next) {
let paginationDetails = {
page: 0,
limit: 50,
orderBy: 'createdAt',
orderAsc: false,
};
if (req.query.noLimit==1) {
paginationDetails.limit = 99999999;
} else {
if (req.query.page) {
paginationDetails.page = parseInt(
req.query.page <= 1 ? 0 : req.query.page - 1,
);
}
req.pagination = paginationDetails;
res.pagination = paginationDetails;
res.routePath = req.route.path+'::'+req.originalUrl;
req.paginationProcess = function(model) {
try {
if(this.pagination !== null){
let order = {};
order[this.pagination.orderBy] = this.pagination.orderAsc;
model.limit(this.pagination.limit)
.skip(this.pagination.limit * this.pagination.page)
.sort(order);
}
} catch(err) {
console.log(err);
} finally {
return model;
}
};
next();
if (req.query.limit) {
paginationDetails.limit = parseInt(req.query.limit > 0 ? req.query.limit : 50);
}
}
if (req.query.orderBy) {
paginationDetails.orderBy = req.query.orderBy;
}
if (req.query.orderAsc) {
paginationDetails.orderAsc = req.query.orderAsc == 0 ? -1 : 1;
}
req.pagination = paginationDetails;
res.pagination = paginationDetails;
res.routePath = req.route.path + '::' + req.originalUrl;
let cacheKey = '';
if (req.User) {
cacheKey = req.User._id + '::';
}
res.cacheKey = cacheKey + res.routePath;

req.paginationProcess = function (model) {
try {
if (this.pagination !== null) {
let order = {};
order[this.pagination.orderBy] = this.pagination.orderAsc;
model
.limit(this.pagination.limit)
.skip(this.pagination.limit * this.pagination.page)
.sort(order);
}
} catch (err) {
console.log(err);
} finally {
return model;
}
};
next();
}

export default pagination;
module.exports = pagination;
20 changes: 11 additions & 9 deletions app/middlewares/redisApiCache.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import redis from 'redis';
import config from '../../config/env/index.js';
const redis = require('redis');
const config = require('../../config/env/index.js');

const PORT_REDIS = process.env.REDIS_PORT || 6379;
const redisClient = redis.createClient(PORT_REDIS);

export function setApiCache(key, value) {
exports.setApiCache = function setApiCache(key, value) {
redisClient.set(key, JSON.stringify(value));
}
};

export function getApiCache(req, res, next) {
exports.getApiCache = function getApiCache(req, res, next) {
if (config.REDIS_API_CACHE) {
let key = req.route.path + '::' + req.originalUrl;
redisClient.get(key, (error, data) => {
let cacheKey = '';
if(req.User){
cacheKey = req.User._id+'::';
}
redisClient.get(cacheKey+key, (error, data) => {
if (error) res.status(400).send(error);
if (data !== null) res.status(200).send(JSON.parse(data));
else next();
});
} else {
next();
}
}

export default getApiCache;
};
4 changes: 2 additions & 2 deletions app/models/Category.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mongoose from 'mongoose';
const mongoose = require('mongoose');
const { Schema } = mongoose;

const CategorySchema = new Schema(
Expand Down Expand Up @@ -59,4 +59,4 @@ try {
Category = mongoose.model('Category', CategorySchema);
}

export default Category;
module.exports = Category;

0 comments on commit 2bf6493

Please sign in to comment.