Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maryyy_ux_project-mongo-API #515

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# Project Mongo API

Replace this readme with your own information about your project.
Week 18th proyect. Build an API with Mongo DataBase.
This week's goal was very broad:
✓ How to create an API using Mongo DB.
✓ How to model data in Mongo using Mongoose
✓ How to store secret information such as database passwords
✓ How to return useful error messages from your API endpoints
✓ How to fetch items from a Mongo database using Mongoose
✓ How to seed large amounts of data to a database

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
All of the key objectives have been challenging, especially with large amounts of data like in this case, but I have learned a lot doing it. I decided to keep on Netflix films to see the differences between one API and the other.

## 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 most challenging issues that I had were the seeding of data and the error messages (as clear as possible). I am half way from adding styling but I don not have enough time to render it on time to meet the schedule. I'll do it just for fun. I really love API's and Data Bases!

## 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://maryyy-ux-project-mongo-api.onrender.com
18 changes: 18 additions & 0 deletions models/NetflixModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import mongoose from "mongoose";

const NetflixSchema = new mongoose.Schema({
show_id: Number,
title: String,
director: String,
cast: String,
country: String,
date_added: String,
release_year: Number,
rating: String,
duration: String,
listed_in: String,
description: String,
type: String,
});

export const Netflix = mongoose.model("Netflix", NetflixSchema);
20 changes: 11 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@
"name": "project-mongo-api",
"version": "1.0.0",
"description": "Starter project to get up and running with express quickly",
"main": "server.js",
"keywords": [],
"author": "",
"license": "ISC",
"scripts": {
"start": "babel-node server.js",
"dev": "nodemon server.js --exec babel-node"
},
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"@babel/core": "^7.26.0",
"@babel/node": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"cors": "^2.8.5",
"express": "^4.17.3",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
"express": "^4.21.2",
"mongoose": "^8.8.4",
"nodemon": "^3.1.7"
}
}
}
119 changes: 104 additions & 15 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,121 @@
import express from "express";
import cors from "cors";
import mongoose from "mongoose";
import { Netflix } from "./models/NetflixModel.js";
import netflixData from "./data/netflix-titles.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";

const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";
const mongoUrl = process.env.MONGO_URL || "mongodb://localhost:27017/project-mongo";
mongoose.connect(mongoUrl);
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();

// Add middlewares to enable cors and json body parsing
app.use(cors());
app.use(express.json());

// Start defining your routes here
// Seed the database if RESET_DB is set
if (process.env.RESET_DB) {
const seedDatabase = async () => {
await Netflix.deleteMany({});
netflixData.forEach(async (item) => {
await new Netflix(item).save();
});
};
seedDatabase();
}

// Home route with API documentation
app.get("/", (req, res) => {
res.send("Hello Technigo!");
res.send({
message: "Welcome to the Marias Netflix API!",
endpoints: [
{ path: "/", method: "GET", description: "API documentation" },
{ path: "/shows", method: "GET", description: "Get all shows" },
{
path: "/shows/:id",
method: "GET",
description: "Get a single show by ID",
},
{
path: "/shows/search",
method: "GET",
description: "Search shows by filters (e.g., title, type, country)",
},
],
});
});

// Search shows by filters
app.get("/shows/search", async (req, res) => {
const { title, type, country } = req.query;
const query = {};

if (title) {
query.title = new RegExp(title, "i");
}
if (type) {
query.type = type;
}
if (country) {
query.country = country;
}

try {
const shows = await Netflix.find(query);
res.status(200).json(shows);
} catch (err) {
res.status(500).json({ error: "Failed to fetch shows", details: err.message });
}
});

// Example stats route
app.get("/shows/stats", async (req, res) => {
try {
const count = await Netflix.countDocuments();
res.status(200).json({ totalShows: count });
} catch (err) {
res.status(500).json({ error: "Failed to fetch stats", details: err.message });
}
});

// Get all shows with pagination
app.get("/shows", async (req, res) => {
Comment on lines +50 to +83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three could all just be one endpoint called /shows. Then you can use different query params to filter on specific things

const { page = 1, limit = 10 } = req.query; // Default: page 1, limit 10

try {
const shows = await Netflix.find()
.skip((page - 1) * limit) // Skip the results of previous pages
.limit(Number(limit)); // Limit the number of results per page

const totalShows = await Netflix.countDocuments(); // Count total number of documents
const totalPages = Math.ceil(totalShows / limit); // Calculate total pages

res.status(200).json({
totalShows,
totalPages,
currentPage: Number(page),
shows,
});
} catch (err) {
res.status(500).json({ error: "Failed to fetch shows", details: err.message });
}
});

// Get a single show by ID
app.get("/shows/:id", async (req, res) => {
const { id } = req.params;

try {
const show = await Netflix.findOne({ show_id: id });
if (show) {
res.status(200).json(show);
} else {
res.status(404).json({ error: "Show not found" });
}
} catch (err) {
res.status(500).json({ error: "Failed to fetch the show" });
}
});

// Start the server
Expand Down