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

Jonas Mongo API #520

Open
wants to merge 9 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
26 changes: 15 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
{
"name": "project-mongo-api",
"version": "1.0.0",
"description": "Starter project to get up and running with express quickly",
"description": "Netflix titles API",
"main": "server.js",
"type": "module",
"scripts": {
"start": "babel-node server.js",
"dev": "nodemon server.js --exec babel-node"
"start": "node server.js",
"dev": "nodemon server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.17.9",
"@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"
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-list-endpoints": "^6.0.0",
"mongoose": "^7.8.3"
},
"devDependencies": {
"nodemon": "^3.1.7"
},
"engines": {
"node": "20.x"
}
}
156 changes: 139 additions & 17 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,157 @@
import express from "express";
import cors from "cors";
import mongoose from "mongoose";
import fs from "fs";
import dotenv from "dotenv";
dotenv.config();

// 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";
// Läs in JSON-data med felhantering
let netflixData = [];
try {
const rawData = fs.readFileSync("./data/netflix-titles.json");
netflixData = JSON.parse(rawData);
console.log(`✅ Loaded ${netflixData.length} titles from JSON file.`);
} catch (error) {
console.error("❌ Error reading or parsing JSON file:", error.message);
}
Comment on lines +10 to +16
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this for? 👀


const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";
mongoose.connect(mongoUrl);
const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/netflix_titles";
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
// Kontrollera MongoDB-anslutning
mongoose.connection.on("connected", () => {
console.log(`✅ Connected to MongoDB: ${mongoose.connection.name}`);
});
mongoose.connection.on("error", (err) => {
console.error("❌ MongoDB connection error:", err);
});

const port = process.env.PORT || 8080;
const app = express();

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

// Start defining your routes here
// Definiera Mongoose-modell med alla fält från JSON-filen
const NetflixTitle = mongoose.model(
"NetflixTitle",
{
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,
},
"netflixtitles" // Explicit namn på collection
);

// Seedningsfunktion för att lägga in data i databasen
if (process.env.RESET_DB) {
const seedDatabase = async () => {
console.log("🌱 Seeding the database...");

try {
const deleteResult = await NetflixTitle.deleteMany();
console.log(`🗑️ Deleted ${deleteResult.deletedCount} existing documents.`);

const insertedDocs = await NetflixTitle.insertMany(
netflixData.map((item) => ({
show_id: item.show_id,
title: item.title,
director: item.director,
cast: item.cast,
country: item.country,
date_added: item.date_added,
release_year: item.release_year,
rating: item.rating,
duration: item.duration,
listed_in: item.listed_in,
description: item.description,
type: item.type,
}))
);
console.log(`✅ Successfully seeded ${insertedDocs.length} documents!`);
} catch (error) {
console.error("❌ Error seeding database:", error.message);
}
};
seedDatabase();
}

// Routes
import listEndpoints from "express-list-endpoints";

// API Dokumentation
app.get("/", (req, res) => {
res.send("Hello Technigo!");
const documentation = {
welcome: "Welcome to the Netflix Titles API!",
description: "This API provides access to a collection of Netflix titles.",
endpoints: listEndpoints(app).map((endpoint) => ({
path: endpoint.path,
methods: endpoint.methods,
})),
queryParameters: {
"/netflix_titles": {
sorted: "Sort titles by rating (true/false)",
country: "Filter by country (case-insensitive)",
release_year: "Filter by release year",
},
},
};
res.json(documentation);
});

// Hämta alla Netflix-titlar med filter
app.get("/netflix_titles", async (req, res) => {
const { sorted, country, release_year } = req.query;

const query = {};
if (country) {
query.country = { $regex: country, $options: "i" };
}
if (release_year) {
query.release_year = Number(release_year);
}
Comment on lines +117 to +123
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice query-building 💯


try {
let titles = await NetflixTitle.find(query);
if (sorted) {
titles = titles.sort((a, b) => a.rating.localeCompare(b.rating));
}

res.setHeader("Content-Type", "application/json");
res.send(JSON.stringify(titles, null, 2));
} catch (error) {
res.status(500).json({ error: "Internal server error" });
}
});

// Hämta en specifik Netflix-titel baserat på show_id
app.get("/netflix_titles/:id", async (req, res) => {
const { id } = req.params;

try {
const title = await NetflixTitle.findOne({ show_id: Number(id) });
if (title) {
res.json(title);
} else {
res.status(404).json({ error: "Title not found" });
}
} catch (error) {
res.status(500).json({ error: "Internal server error" });
}
});
Comment on lines +139 to 152
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't get this endpoint to work on your deployed version, can you?


// Start the server
// Starta servern
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
console.log(`🚀 Server running on http://localhost:${port}`);
});