diff --git a/README.md b/README.md index 35019cd8a..1c1aa7e59 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,10 @@ # Project Mongo API - -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +This project was designed to develop a RESTful API for avocado sales data, utilizing Express.js and MongoDB to manage the database and implement API endpoints effectively. ## The problem -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +The main challenge was to create efficient queries to retrieve and manipulate data according to the API's requirements. If I had more time, I would implement additional features like authentication and more complex data aggregation to enhance the API's functionality. ## View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +https://project-mongo-api-ude1.onrender.com \ No newline at end of file diff --git a/package.json b/package.json index 6830a48aa..c0e9aec7e 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,10 @@ "name": "project-mongo-api", "version": "1.0.0", "description": "Starter project to get up and running with express quickly", + "type": "module", "scripts": { "start": "babel-node server.js", - "dev": "nodemon server.js --exec babel-node" + "dev": "nodemon -r dotenv/config server.js --exec babel-node" }, "author": "", "license": "ISC", @@ -13,8 +14,10 @@ "@babel/node": "^7.16.8", "@babel/preset-env": "^7.16.11", "cors": "^2.8.5", - "express": "^4.17.3", - "mongoose": "^8.0.0", - "nodemon": "^3.0.1" + "express": "^4.19.2", + "express-list-endpoints": "^7.1.0", + "mongoose": "^8.3.4", + "nodemon": "^3.0.1", + "dotenv": "^16.0.0" } } diff --git a/server.js b/server.js index 647e7b144..038748352 100644 --- a/server.js +++ b/server.js @@ -1,32 +1,93 @@ import express from "express"; import cors from "cors"; import mongoose from "mongoose"; +import expressListEndpoints from "express-list-endpoints"; +import avocadoSalesData from "./data/avocado-sales.json" with { type: "json" }; -// If you're using one of our datasets, uncomment the appropriate import below -// to get started! -// import avocadoSalesData from "./data/avocado-sales.json"; -// import booksData from "./data/books.json"; -// import goldenGlobesData from "./data/golden-globes.json"; -// import netflixData from "./data/netflix-titles.json"; -// import topMusicData from "./data/top-music.json"; - +// Database connection const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; -mongoose.connect(mongoUrl); +mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true }); mongoose.Promise = Promise; -// Defines the port the app will run on. Defaults to 8080, but can be overridden -// when starting the server. Example command to overwrite PORT env variable value: -// PORT=9000 npm start -const port = process.env.PORT || 8080; const app = express(); +const port = process.env.PORT || 8080; + +// Avocado sales model +const AvocadoSales = mongoose.model("AvocadoSales", { + id: Number, + date: Date, + averagePrice: Number, + totalVolume: Number, + totalBagsSold: Number, + smallBagsSold: Number, + largeBagsSold: Number, + xLargeBagsSold: Number, + region: String, +}); + +// Seed database if required +if (process.env.RESET_DB) { + const seedDatabase = async () => { + await AvocadoSales.deleteMany(); + const salesDocuments = avocadoSalesData.map( + (salesData) => new AvocadoSales(salesData) + ); + await AvocadoSales.insertMany(salesDocuments); + console.log("Database seeded"); + }; + seedDatabase(); +} -// Add middlewares to enable cors and json body parsing +// Middleware app.use(cors()); app.use(express.json()); -// Start defining your routes here +// API documentation endpoint app.get("/", (req, res) => { - res.send("Hello Technigo!"); + res.json( + expressListEndpoints(app).map((endpoint) => ({ + method: endpoint.methods.join(", "), + path: endpoint.path, + description: "Describe what each endpoint does", + })) + ); +}); + +// List all sales +app.get("/avocado-sales", async (req, res) => { + try { + const sales = await AvocadoSales.find().select("-_id -__v").sort({ id: 1 }); + res.json(sales); + } catch (error) { + res.status(500).json({ error: "Failed to retrieve sales data" }); + } +}); + +// Get sales by region +app.get("/avocado-sales/region/:regionName", async (req, res) => { + const { regionName } = req.params; + try { + const sales = await AvocadoSales.find({ region: regionName }) + .select("-_id -__v") + .sort({ id: 1 }); + res.json(sales); + } catch (error) { + res.status(500).json({ error: "Failed to retrieve sales by region" }); + } +}); + +// Get sales by specific date +app.get("/avocado-sales/date/:date", async (req, res) => { + const { date } = req.params; + try { + const formattedDate = new Date(date).toISOString(); + const sales = await AvocadoSales.find({ date: formattedDate }) + .select("-_id -__v") + .sort({ id: 1 }); + res.json(sales); + } catch (error) { + res.status(500).json({ error: "Failed to retrieve sales by date" }); + } }); // Start the server