I am currently doing a GET
request that uses a bunch of methods that I wrote to query the database and display them. This works great, but I want to make it a POST
request method so that the methods do not have to depend on req.query
, deal with a json body instead of a string of URL params which would would facilitate the url string not to have anything else except the endpoints and make it as dynamic as possible. Any idea how to do this?
This is my controller method:
exports.getBooks = async (req, res, next) => {
const bookList = new BookList(Book.find(), req.query)
.filter()
.sort()
.paginate();
const books = await bookList.query;
res.status(200)
.json({
books,
});
};
This is the BookList class that has all the methods:
class BookList {
constructor(query, queryString) {
this.query = query;
this.queryString = queryString;
}
filter() {
const queryObj = { ...this.queryString };
const excludedFields = ['page', 'sort', 'limit', 'fields'];
excludedFields.forEach(el => delete queryObj[el]);
let queryStr = JSON.stringify(queryObj);
this.query = this.query.find(JSON.parse(queryStr));
return this;
}
sort() {
if (this.queryString.sort) {
const sortBy = this.queryString.sort.split(',').join(' ');
this.query = this.query.sort(sortBy);
} else {
this.query = this.query.sort('-createdAt');
}
return this;
}
paginate() {
const page = Number(this.queryString.page) || 1;
const limit = Number(this.queryString.limit) || 100;
const skip = (page - 1) * limit;
this.query = this.query.skip(skip).limit(limit);
return this;
}
}
module.exports = BookList;
This is what worked for me:
exports.getBooks = async (req, res, next) => {
let bookBody = req.body
const bookList = new BookList(Book.find(), req.query)
.filter(bookBody, req)
.sort()
.paginate();
const books = await bookList.query;
res.status(200)
.json({
books,
});
};
filter(bookBody, req) {
const filterBooks = bookBody.filter
const bookId = req.params.bookId
let requiredFilter
if (filterBooks) {
requiredFilter = {bookStatus: filterBooks.bookStatus, bookId};
} else {
requiredFilter = { bookId}
}
this.query = this.query.find(requiredFilter)
return this;
}