Skip to content

Commit cbf35c3

Browse files
committed
Initial Commit
0 parents  commit cbf35c3

13 files changed

+1697
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/node_modules
2+
.env

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# STORE API

app.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const express = require("express");
2+
const app = express();
3+
require("dotenv").config();
4+
require("express-async-errors");
5+
6+
const notFoundMiddleware = require("./middleware/not-found");
7+
const errorMiddleware = require("./middleware/error-handler");
8+
const productsRouter = require("./routes/products");
9+
const connectDB = require("./db/connect");
10+
11+
app.use(express.json());
12+
13+
app.get("/", (req, res) => {
14+
res.send('<h1>Store API</h1><a href="/api/v1/products">products route</a>');
15+
});
16+
17+
app.use("/api/v1/products", productsRouter);
18+
19+
app.use(notFoundMiddleware);
20+
app.use(errorMiddleware);
21+
22+
const port = process.env.PORT || 3000;
23+
24+
const start = async () => {
25+
try {
26+
await connectDB(process.env.MONGO_URI);
27+
app.listen(port, () => console.log(`Server is listening on port ${port}...`));
28+
} catch (error) {
29+
console.log(error);
30+
}
31+
};
32+
33+
start();

controllers/products.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const Product = require("../models/product");
2+
3+
const getAllProductsStatic = async (req, res) => {
4+
const products = await Product.find({ price: { $gt: 30 } })
5+
.sort("price")
6+
.select("name price");
7+
8+
res.status(200).json({ products, nbHits: products.length });
9+
};
10+
11+
const getAllProducts = async (req, res) => {
12+
const { featured, company, name, sort, fields, numericFilters } = req.query;
13+
const queryObject = {};
14+
15+
if (featured) {
16+
queryObject.featured = featured === "true" ? true : false;
17+
}
18+
if (company) {
19+
queryObject.company = company;
20+
}
21+
if (name) {
22+
queryObject.name = { $regex: name, $options: "i" };
23+
}
24+
if (numericFilters) {
25+
const operatorMap = {
26+
">": "$gt",
27+
">=": "$gte",
28+
"=": "$eq",
29+
"<": "$lt",
30+
"<=": "$lte",
31+
};
32+
33+
const regEx = /\b(<|>|>=|=|<|<=)\b/g;
34+
35+
let filters = numericFilters.replace(
36+
regEx,
37+
(match) => `-${operatorMap[match]}-`
38+
);
39+
40+
const options = ["price", "rating"];
41+
42+
filters = filters.split(",").forEach((item) => {
43+
const [field, operator, value] = item.split("-");
44+
if (options.includes(field)) {
45+
queryObject[field] = { [operator]: Number(value) };
46+
}
47+
});
48+
}
49+
50+
let result = Product.find(queryObject);
51+
52+
if (sort) {
53+
const sortList = sort.split(",").join(" ");
54+
result = result.sort(sortList);
55+
} else {
56+
result = result.sort("createdAt");
57+
}
58+
59+
if (fields) {
60+
const fieldsList = fields.split(",").join(" ");
61+
result = result.select(fieldsList);
62+
}
63+
64+
const page = Number(req.query.page) || 1;
65+
const limit = Number(req.query.limit) || 10;
66+
const skip = (page - 1) * limit;
67+
68+
result = result.skip(skip).limit(limit);
69+
70+
const products = await result;
71+
res.status(200).json({ products, nbHits: products.length });
72+
};
73+
74+
module.exports = {
75+
getAllProducts,
76+
getAllProductsStatic,
77+
};

db/connect.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const mongoose = require("mongoose");
2+
3+
const connectDB = (url) => {
4+
return mongoose.connect(url, {
5+
useNewUrlParser: true,
6+
useFindAndModify: false,
7+
useUnifiedTopology: true,
8+
});
9+
};
10+
11+
module.exports = connectDB;

middleware/error-handler.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const errorHandlerMiddleware = async (err, req, res, next) => {
2+
return res
3+
.status(500)
4+
.json({ msg: "Something went wrong, please try again" });
5+
};
6+
7+
module.exports = errorHandlerMiddleware;

middleware/not-found.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const notFound = (req, res) => res.status(404).send("Route does not exist");
2+
3+
module.exports = notFound;

models/product.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const mongoose = require("mongoose");
2+
3+
const productSchema = new mongoose.Schema({
4+
name: {
5+
type: String,
6+
required: [true, "product name must be provided"],
7+
},
8+
price: {
9+
type: Number,
10+
required: [true, "product price must be provided"],
11+
},
12+
featured: {
13+
type: Boolean,
14+
default: false,
15+
},
16+
rating: {
17+
type: Number,
18+
default: 4.5,
19+
},
20+
createdAt: {
21+
type: Date,
22+
default: Date.now(),
23+
},
24+
company: {
25+
type: String,
26+
enum: {
27+
values: ["ikea", "liddy", "caressa", "marcos"],
28+
message: "{VALUE} is not supported",
29+
},
30+
},
31+
});
32+
33+
module.exports = mongoose.model("Product", productSchema);

0 commit comments

Comments
 (0)