Building a rest API
- importing packages
- express
- nodemon
- listening to server
- router- controller
- Routes - is responsible for which path we should follow and where i should reach
- Controller : Is responsible for after reaching what next,perform the task
STEPS:
const express = require("express");
const router = express.Router();
// import what function you are passing
const {getAllPrducts,getAllPrductsTesting} = require("../controller/products");
// avg mehtod
router.get("/all", (req,res)=>{
res.json({msg: "welcome"})
});
router.get("/testing", (req, res)=>{
res.json({msg: "Testing"})
});
// Better method
router.get("/products",getAllPrducts)
router.get("/productstesting",getAllPrductsTesting)
// exporting the routes are very important
module.exports = router;
// Defing our function
const getAllPrducts = async (req, res) => {
res.json({msg: "all products"})
}
// Defining our function
const getAllPrductsTesting = async (req, res)=>{
res.json({msg: "all products"})
};
// export this function are very important
module.exports = {
getAllPrducts,
getAllPrductsTesting
}
// import the routes folder
const products_routes = require("./routes/products")
// use middlewae to navigate
app.use("/api/products", products_routes)
Create a Folder DB
STEP 1 : install mongoose and perform given task
npm i mongoose
const mongoose = require("mongoose")
URI ="mongodb_url"
const connectDB = ()=>{
console.log("db connected");
return mongoose.connect(URI)
}
// or
mongoose.connect(URI)
module.exports = connectDB
In app.js file
const connectDB = require("./db/connect")
// or call the funcion
app.listen(PORT, ()=>{
connectDB() }
)
npm i mongoose
create an a.env file and add it in the .gitignore file
// import he dotenv package
require("dotenv").config()
// This command either will access the value of PORT from .env file
// 0r
// if something goes wrong it willl access the given value i.e : 3000
const PORT = process.env.PORT || 3000
.env file
PORT = XXXX
DATABASE_URL = mongoose://something:/string/url/appname
process.env.DATABASE_URL
- create a model folder > product.js
- We just need to Define the schema and export it
Defining****
** schema **
const mongoose = require("mongoose")
const productSchema = new mongoose.Schema({
name: {
type : String,
required:[true, "Name should be provided"],
},
price :{
type:Number,
required:[true, "Price must be provided"],
},
featured :{
type : Boolean,
default :false,
},
rating:{
type:Number,
default: 4.9,
required:[true, "Rating must be provided"],
},
createdAt:{
type: Date,
default :Date.now()
},
company :{
type :String,
// here enums are validating the company : only the given company are allowed
enum:{
values:["Apple", "Samsung", "Dell", "MI"],
message:`${value} is not supported`
}
}
})
// now add this in my Databse collection
// creae new collection
module.exports = mongoose.model("Product", productSchema)
Till now it's empty : It should have a collection with name : eccomerce
it means - the collection should be MongoDB and we can feed some data to this collection
This is something different approach to create a schema and dumped the JSON Data in one go
In the Root Project
created products.json file
[
{
"name": "iphone",
"price": 154,
"featured": true,
"company": "apple"
},
{
"name": "iphone10",
"price": 1154,
"featured": true,
"company": "apple"
},
{
"name": "watch",
"price": 204,
"company": "apple"
},
{
"name": "watch10",
"price": 304,
"company": "apple"
},
{
"name": "s20",
"price": 404,
"company": "samsung"
},
{
"name": "s20",
"price": 505,
"company": "samsung"
},
{
"name": "dell gaming",
"price": 501,
"company": "dell"
},
{
"name": "mi20",
"price": 701,
"company": "mi"
}
]
And then just to dump these data directly, we use
// create productDb.js
// import the dependicies
require("dotenv").config()
const express = require("express")
const app = express()
const connectDB = require("./db/connect")
const Product = require("./models/product")
// This is important
const ProductJson = require("./products.json")
app.listen(process.env.PORT , async ()=>{
await connectDB(process.env.DATABASE_URL)
// just pass the variable who is holding whole json file
await Product.create(ProductJson)
console.log("success fully conected");
console.log("server is running..");
})
**create a new route **
// in route > product.js
router.post("/addproduct",createProduct)
// now this createProduct from **TOP**
const createProduct = async (req, res)=>{
console.log("i am here ... ");
await Product.create({
name: req.body.name,
price: req.body.price,
featured: req.body.featured,
rating: req.body.rating,
createdAt: req.body.createdAt,
company: req.body.company
})
console.log("i am done , check now ");
res.status(201).json({
msg: "Product created"
})
}
Get all the data from database
const Product = require("../models/product")
const getAllPrducts = async (req, res) => {
try {
// here all products comes as response
const products = await Product.find({products});
// H**ere only those products with name : "watch"**
// const products = await Product.find({name: "watch"});
// res.status(200).json({products}); if we return as json object
// then this variable will expand all products
res.status(200).json(products);
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
}
const getAllPrductsTesting = async (req, res)=>{
try {
// storing the query parameter in variable and searching
// can search in any way [
// localhost:5000/api/v1/products/productstesting?name=iphone
// localhost:5000/api/v1/products/productstesting?company=iphone
// Add more searches
// http://localhost:5000/api/v1/products/productstesting?company=apple&name=watch10](http://localhost:5000/api/v1/products/productstesting?name=iphone)
const search = req.query
const products = await Product.find(search);
res.status(200).json({products});
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};
Here if the first query parameter is OK, then the response will show the first part
localhost:5000/api/v1/products/productstesting?company=apple&adf=sdf
localhost:5000/api/v1/products/productstesting?adf=sdf&company=apple
const getAllPrductsTesting = async (req, res)=>{
try {
// if any part of query parameters is true , then show their result
const {company} = req.query
const queryObject = {}
if(company){
queryObject.company = company
// just to log the value : apple
console.log(queryObject.company)
}
const products = await Product.find(queryObject);
res.status(200).json({products});
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};
const getAllPrductsTesting = async (req, res)=>{
try {
const {company, name} = req.query
const queryObject = {}
if(company){
queryObject.company = company
console.log(queryObject.company)
}
if(name){
queryObject.name = name
console.log(queryObject.name)
}
// or
if(company && name){
queryObject.company = company
queryObject.company = company
console.log(queryObject.company)
console.log(queryObject.company)
}
}
console.log(queryObject);
const products = await Product.find(queryObject);
res.status(200).json({products});
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};
MongoDB offers an improved full-text search solution
**$regex**
Provides regular expression capabilities for pattern-matching strings in queries.
const getAllPrductsTesting = async (req, res)=>{
try {
const {company, name} = req.query
const queryObject = {}
if(company){
queryObject.company = company
console.log(queryObject.company)
}
if(name){
// here we can serach generalize : **not very strictly **
queryObject.name = {$regex : name, $options: "i"}
console.log(queryObject.name)
}
console.log(queryObject);
const products = await Product.find(queryObject);
res.status(200).json({products});
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};
const products = await Product.find().sort("name"); // asending
const products = await Product.find().sort("-name"); // descending
// sort two things together
let apiData = Product.find(queryObject);
if (sort) {
let sortFix = sort.split(",").join(" ");
apiData = apiData.sort(sortFix);
}
const getAllPrductsTesting = async (req, res)=>{
try {
const products = await Product.find().sort("-name");
res.status(200).json({products});
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};
only selected fields will be getting as response
const getAllPrductsTesting = async (req, res)=>{
try {
// return only selected field
const { company, name, featured, sort, select } = req.query;
const queryObject = {}
let apiData = Product.find(queryObject);
// (select = name company);
if (select) {
let selectFix = select.replace(",", " ");
// let selectFix = select.split(",").join(" ");
apiData = apiData.select(selectFix);
}
console.log(queryObject);
const myData = await apiData
res.status(200).json({myData})
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};
const getAllPrductsTesting = async (req, res)=>{
try {
// return only selected field
const { company, name, featured, sort, select,price } = req.query;
const queryObject = {}
let apiData = Product.find(queryObject);
let page = Number(req.query.page) || 1
let limit = Number(req.query.limit) || 3
let skip = (page -1) * limit
apiData = apiData.skip(skip).limit(limit)
console.log(queryObject);
const myData = await apiData
res.status(200).json({myData, nbHits: myData.length})
} catch (error){
res.status(500).json(
{ error: 'Internal server error' }
);
}
};