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

project-18-mongo-api #516

Open
wants to merge 12 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ node_modules
.env.development.local
.env.test.local
.env.production.local
package-lock.json
package-lock.json
.env
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@babel/preset-env": "^7.16.11",
"cors": "^2.8.5",
"express": "^4.17.3",
"mongodb": "^6.12.0",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
}
Expand Down
5 changes: 2 additions & 3 deletions pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
## Netlify link
Add your Netlify link here.
PS. Don't forget to add it in your readme as well.
Render link: https://project-18-mongo-api.onrender.com/ (not working yet..)

## Collaborators
Add any collaborators here.
-
153 changes: 143 additions & 10 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import express from "express";
import cors from "cors";
import mongoose from "mongoose";
import dotenv from "dotenv";
import expressListEndpoints from "express-list-endpoints";
import booksData from "./data/books.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";
dotenv.config()

const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";

const mongoUrl = process.env.MONGO_URL || "https://project-18-mongo-api.onrender.com/ ";
mongoose.connect(mongoUrl);
mongoose.Promise = Promise;

Expand All @@ -24,11 +22,146 @@ const app = express();
app.use(cors());
app.use(express.json());

// Start defining your routes here

//Check if mongo is connected
mongoose.connect(mongoUrl)
.then(() => console.log("Connected to MongoDB"))
.catch(err => console.error("Failed to connect to MongoDB:", err));


const Book = mongoose.model('Book', {
"bookID": Number,
"title": String,
"authors": String,
"average_rating": Number,
"isbn": Number,
"isbn13": Number,
"language_code": String,
"num_pages": Number,
"ratings_count": Number,
"text_reviews_count": Number
})



if (process.env.RESET_DB) {
const seedDatabase = async () => {
await Book.deleteMany({})

booksData.forEach((book) => {
new Book(book).save()
})
}

seedDatabase()
}



// Home page - first route
app.get("/", (req, res) => {
res.send("Hello Technigo!");
res.send("Welcome to the website where you can find your favourite book!");

const endpoints = expressListEndpoints(app);
response.json({
message: "Welcome to the Elves API! Here are the available endpoints:",
description: {
"/books": "all books",
"/books/pages": "by number of pages",
"/books/:bookID": "by ID",
"/test": "Test endpoint",
},
endpoints: endpoints
});
});

// Route with all the books - full API
app.get("/books", async (req, res) => {
try {
const books = await Book.find();
res.json(books);
} catch (error) {
res.status(500).json({ error: "An error occurred while fetching books" });
}
});


// Ge books based on number of pages (needs to be befor bookID otherwise that route will override this)
app.get("/books/pages", async (req, res) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be named just /books, because that's what this endpoint is returning

const { min, max } = req.query;

// Parse min and max values or assign default values
const minPages = parseInt(min, 10) || 0; // Default: 0 pages
const maxPages = parseInt(max, 10) || Number.MAX_SAFE_INTEGER; // Default: No upper limit

console.log(`Filtering books with num_pages between ${minPages} and ${maxPages}`);

try {
// Query to find books within the range
const numberOfPages = await Book.find({
num_pages: { $gte: minPages, $lte: maxPages },
});

// Return books if found, otherwise send 404
if (numberOfPages.length > 0) {
res.json(numberOfPages);
} else {
res.status(404).json({
error: `No books found with page count between ${minPages} and ${maxPages}`,
});
}
} catch (error) {
// Handle any server-side errors
res.status(500).json({ error: "An error occurred while fetching books" });
}
});


// Get individual books from id
app.get("/books/:bookID", async (req, res) => {
const bookID = parseInt(req.params.bookID);

try {
const book = await Book.findOne({ bookID: bookID });

if (book) {
res.json(book); // return the specifik book
} else {
res.status(404).json({ error: "Book not found" }); // error page if book not founf
}
} catch (error) {
res.status(500).json({ error: "An error occurred while fetching the book" }); // 500 page when wrong
}
});


// Get book-books by author
app.get("/books/authors/:author", async (req, res) => {
const author = req.params.author;

try {
// $regex = to match name and not case sensitive
const booksByAuthor = await Book.find({
authors: { $regex: author, $options: "i" }, // "i" case-insensitive
});

if (booksByAuthor.length > 0) {
res.json(booksByAuthor); // Returnera böckerna om de finns
} else {
res.status(404).json({ error: "No books found for this author" });
}
} catch (error) {
res.status(500).json({ error: "An error occurred while fetching books" });
}
});
Comment on lines +139 to +156
Copy link
Contributor

Choose a reason for hiding this comment

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

And this should also be a query under your /books endpoint to make it more RESTful. Even though you're filtering on author, you still return books


// test
app.get("/test", (req, res) => {
response.send("Yesbox!");
console.log("Yesbox!");
});


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