From 1ccbc36c3cafd5ad079d75bafeb67396eb43ae60 Mon Sep 17 00:00:00 2001 From: iamfannyhenriques Date: Thu, 5 Dec 2024 00:36:57 +0100 Subject: [PATCH 1/3] initial commit --- data/harry-potter-characters.json | 402 ++++++++++++++++++++++++++++++ server.js | 72 +++++- 2 files changed, 463 insertions(+), 11 deletions(-) create mode 100644 data/harry-potter-characters.json diff --git a/data/harry-potter-characters.json b/data/harry-potter-characters.json new file mode 100644 index 000000000..98290a000 --- /dev/null +++ b/data/harry-potter-characters.json @@ -0,0 +1,402 @@ +[ + { + "id": 1, + "name": "Harry Potter", + "house": "Gryffindor", + "role": "Student", + "rating": 9.8, + "yearIntroduced": 1997 + }, + { + "id": 2, + "name": "Hermione Granger", + "house": "Gryffindor", + "role": "Student", + "rating": 9.7, + "yearIntroduced": 1997 + }, + { + "id": 3, + "name": "Ron Weasley", + "house": "Gryffindor", + "role": "Student", + "rating": 9.5, + "yearIntroduced": 1997 + }, + { + "id": 4, + "name": "Albus Dumbledore", + "house": "Gryffindor", + "role": "Headmaster", + "rating": 9.9, + "yearIntroduced": 1997 + }, + { + "id": 5, + "name": "Severus Snape", + "house": "Slytherin", + "role": "Professor", + "rating": 9.6, + "yearIntroduced": 1997 + }, + { + "id": 6, + "name": "Draco Malfoy", + "house": "Slytherin", + "role": "Student", + "rating": 8.7, + "yearIntroduced": 1997 + }, + { + "id": 7, + "name": "Minerva McGonagall", + "house": "Gryffindor", + "role": "Professor", + "rating": 9.8, + "yearIntroduced": 1997 + }, + { + "id": 8, + "name": "Rubeus Hagrid", + "house": "Gryffindor", + "role": "Keeper of Keys", + "rating": 9.4, + "yearIntroduced": 1997 + }, + { + "id": 9, + "name": "Lord Voldemort", + "house": "Slytherin", + "role": "Antagonist", + "rating": 9.2, + "yearIntroduced": 1997 + }, + { + "id": 10, + "name": "Sirius Black", + "house": "Gryffindor", + "role": "Order of the Phoenix", + "rating": 9.5, + "yearIntroduced": 1999 + }, + { + "id": 11, + "name": "Remus Lupin", + "house": "Gryffindor", + "role": "Professor", + "rating": 9.6, + "yearIntroduced": 1999 + }, + { + "id": 12, + "name": "Ginny Weasley", + "house": "Gryffindor", + "role": "Student", + "rating": 8.9, + "yearIntroduced": 1997 + }, + { + "id": 13, + "name": "Neville Longbottom", + "house": "Gryffindor", + "role": "Student", + "rating": 8.8, + "yearIntroduced": 1997 + }, + { + "id": 14, + "name": "Luna Lovegood", + "house": "Ravenclaw", + "role": "Student", + "rating": 9.3, + "yearIntroduced": 2003 + }, + { + "id": 15, + "name": "Cho Chang", + "house": "Ravenclaw", + "role": "Student", + "rating": 7.8, + "yearIntroduced": 1999 + }, + { + "id": 16, + "name": "Bellatrix Lestrange", + "house": "Slytherin", + "role": "Death Eater", + "rating": 9.0, + "yearIntroduced": 1999 + }, + { + "id": 17, + "name": "Fred Weasley", + "house": "Gryffindor", + "role": "Student", + "rating": 8.5, + "yearIntroduced": 1997 + }, + { + "id": 18, + "name": "George Weasley", + "house": "Gryffindor", + "role": "Student", + "rating": 8.5, + "yearIntroduced": 1997 + }, + { + "id": 19, + "name": "Lucius Malfoy", + "house": "Slytherin", + "role": "Death Eater", + "rating": 8.2, + "yearIntroduced": 1997 + }, + { + "id": 20, + "name": "Nymphadora Tonks", + "house": "Hufflepuff", + "role": "Auror", + "rating": 9.1, + "yearIntroduced": 1999 + }, + { + "id": 21, + "name": "Cedric Diggory", + "house": "Hufflepuff", + "role": "Student", + "rating": 8.4, + "yearIntroduced": 1999 + }, + { + "id": 22, + "name": "Molly Weasley", + "house": "Gryffindor", + "role": "Order of the Phoenix", + "rating": 9.2, + "yearIntroduced": 1997 + }, + { + "id": 23, + "name": "Arthur Weasley", + "house": "Gryffindor", + "role": "Ministry Worker", + "rating": 8.7, + "yearIntroduced": 1997 + }, + { + "id": 24, + "name": "Peter Pettigrew", + "house": "Gryffindor", + "role": "Death Eater", + "rating": 6.8, + "yearIntroduced": 1997 + }, + { + "id": 25, + "name": "Fleur Delacour", + "house": "Beauxbatons", + "role": "Triwizard Champion", + "rating": 8.3, + "yearIntroduced": 2000 + }, + { + "id": 26, + "name": "Viktor Krum", + "house": "Durmstrang", + "role": "Triwizard Champion", + "rating": 8.1, + "yearIntroduced": 2000 + }, + { + "id": 27, + "name": "Moaning Myrtle", + "house": "Ravenclaw", + "role": "Ghost", + "rating": 7.5, + "yearIntroduced": 1997 + }, + { + "id": 28, + "name": "Nearly Headless Nick", + "house": "Gryffindor", + "role": "Ghost", + "rating": 7.8, + "yearIntroduced": 1997 + }, + { + "id": 29, + "name": "Dobby", + "house": "N/A", + "role": "House Elf", + "rating": 9.7, + "yearIntroduced": 1998 + }, + { + "id": 30, + "name": "Kreacher", + "house": "N/A", + "role": "House Elf", + "rating": 8.0, + "yearIntroduced": 1997 + }, + { + "id": 31, + "name": "Horace Slughorn", + "house": "Slytherin", + "role": "Professor", + "rating": 8.5, + "yearIntroduced": 2006 + }, + { + "id": 32, + "name": "Gilderoy Lockhart", + "house": "Ravenclaw", + "role": "Professor", + "rating": 6.5, + "yearIntroduced": 1992 + }, + { + "id": 33, + "name": "Argus Filch", + "house": "N/A", + "role": "Caretaker", + "rating": 5.0, + "yearIntroduced": 1997 + }, + { + "id": 34, + "name": "Peeves", + "house": "N/A", + "role": "Poltergeist", + "rating": 7.0, + "yearIntroduced": 1997 + }, + { + "id": 35, + "name": "Barty Crouch Jr.", + "house": "Slytherin", + "role": "Death Eater", + "rating": 8.1, + "yearIntroduced": 1994 + }, + { + "id": 36, + "name": "Fenrir Greyback", + "house": "N/A", + "role": "Werewolf", + "rating": 7.2, + "yearIntroduced": 1997 + }, + { + "id": 37, + "name": "Dolores Umbridge", + "house": "Slytherin", + "role": "Professor", + "rating": 6.0, + "yearIntroduced": 1995 + }, + { + "id": 38, + "name": "Mad-Eye Moody", + "house": "Hufflepuff", + "role": "Auror", + "rating": 9.0, + "yearIntroduced": 1995 + }, + { + "id": 39, + "name": "Kingsley Shacklebolt", + "house": "Hufflepuff", + "role": "Auror", + "rating": 9.2, + "yearIntroduced": 1995 + }, + { + "id": 40, + "name": "Rita Skeeter", + "house": "Ravenclaw", + "role": "Journalist", + "rating": 7.5, + "yearIntroduced": 1992 + }, + { + "id": 41, + "name": "The Grey Lady (Helena Ravenclaw)", + "house": "Ravenclaw", + "role": "Ghost", + "rating": 8.3, + "yearIntroduced": 1997 + }, + { + "id": 42, + "name": "The Bloody Baron", + "house": "Slytherin", + "role": "Ghost", + "rating": 8.0, + "yearIntroduced": 1991 + }, + { + "id": 43, + "name": "Salazar Slytherin", + "house": "Slytherin", + "role": "Founder", + "rating": 8.7, + "yearIntroduced": 1991 + }, + { + "id": 44, + "name": "Godric Gryffindor", + "house": "Gryffindor", + "role": "Founder", + "rating": 9.5, + "yearIntroduced": 1991 + }, + { + "id": 45, + "name": "Helga Hufflepuff", + "house": "Hufflepuff", + "role": "Founder", + "rating": 8.9, + "yearIntroduced": 1991 + }, + { + "id": 46, + "name": "Rowena Ravenclaw", + "house": "Ravenclaw", + "role": "Founder", + "rating": 9.2, + "yearIntroduced": 1991 + }, + { + "id": 47, + "name": "Horace Slughorn", + "house": "Slytherin", + "role": "Professor", + "rating": 8.4, + "yearIntroduced": 1997 + }, + { + "id": 48, + "name": "Narcissa Malfoy", + "house": "Slytherin", + "role": "Mother", + "rating": 7.9, + "yearIntroduced": 1997 + }, + { + "id": 49, + "name": "Astoria Greengrass", + "house": "Slytherin", + "role": "Wife", + "rating": 7.4, + "yearIntroduced": 2007 + }, + { + "id": 50, + "name": "Bill Weasley", + "house": "Gryffindor", + "role": "Order of the Phoenix", + "rating": 8.7, + "yearIntroduced": 1994 + } +] \ No newline at end of file diff --git a/server.js b/server.js index b5fec6fe2..5e04623ea 100644 --- a/server.js +++ b/server.js @@ -1,18 +1,10 @@ import express from "express"; import cors from "cors"; +import harryPotterCharactersData from "./data/harry-potter-characters.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"; - -// 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 port = process.env.PORT || 9000; const app = express(); // Add middlewares to enable cors and json body parsing @@ -21,9 +13,67 @@ app.use(express.json()); // Start defining your routes here app.get("/", (req, res) => { - res.send("Hello Technigo!"); + res.send("Welcome to the Harry potter page!"); +}); + +//Reoute to get all the characters from the json file - or filter by house +app.get("/harryPotterCharacters", (req, res) => { + const house = req.query.house; + + // If a 'house' query parameter is provided.... + if (house) { + const filteredCharacters = harryPotterCharactersData.filter(character => + character.house.toLocaleLowerCase() === house.toLocaleLowerCase() + ); + res.json(filteredCharacters); // ...then return a filtered list based on house + } else { + res.json(harryPotterCharactersData); // No filter = respond with all characters + } +}); +//_____________________________________________________________ +app.get("/harryPotterCharacters/role/:role", (req, res) => { + const role = req.params.role; + + const characterRole = harryPotterCharactersData.filter(character => + character.role.toLocaleLowerCase() === role.toLocaleLowerCase() + ); + + if (characterRole.length > 0) { + res.json(characterRole); + } else { + res.status(404).send("No characters found with that role"); + } }); +//_____________________________________________________________ +//Sort by id - getting each character based on the id number +app.get("/harryPotterCharacters/:id", (req, res) => { + const id = req.params.id; + + const harryPotterCharacter = harryPotterCharactersData.find(character => character.id === +id); + if (harryPotterCharacter) { + res.status(200).json(harryPotterCharacter); + } else { + res.status(404).send("No character found with that id"); + } +}); +// //_____________________________________________________________ +// Filter by yearIntroduced +app.get("/harryPotterCharacters/:yearIntroduced", (req, res) => { + const year = req.params.yearIntroduced; + + //Filter the characters based on the yearIntroduced property + const charactersIntroducedInYear = harryPotterCharactersData.filter(character => character.yearIntroduced === +year); + + if (charactersIntroducedInYear.length > 0) { + res.status(200).json(charactersIntroducedInYear); + } else { + res.status(404).send("No characters found from that year"); + } +}); + +//_____________________________________________________________ + // Start the server app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); From d984215f5c2381ff912b18425796f4a7c8015846 Mon Sep 17 00:00:00 2001 From: iamfannyhenriques Date: Thu, 5 Dec 2024 17:11:41 +0100 Subject: [PATCH 2/3] moved the filtering for house, role and year to the first route as query params using if else statements and tried adding name in a separate route --- package.json | 1 + server.js | 78 +++++++++++++++++++++++++++++----------------------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index f93ddb524..fcbf92020 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@babel/preset-env": "^7.16.11", "cors": "^2.8.5", "express": "^4.17.3", + "express-list-endpoints": "^7.1.1", "nodemon": "^3.0.1" } } diff --git a/server.js b/server.js index 5e04623ea..83a09574f 100644 --- a/server.js +++ b/server.js @@ -1,5 +1,6 @@ import express from "express"; import cors from "cors"; +import listEndpoints from "express-list-endpoints"; import harryPotterCharactersData from "./data/harry-potter-characters.json"; // when starting the server. Example command to overwrite PORT env variable value: @@ -13,40 +14,48 @@ app.use(express.json()); // Start defining your routes here app.get("/", (req, res) => { - res.send("Welcome to the Harry potter page!"); + const endpoints = listEndpoints(app); + res.json({ + message: "Welcome to the Harry Potter page!", + endpoints: endpoints + }); }); -//Reoute to get all the characters from the json file - or filter by house +// Route to get all characters or filter by house, year, role app.get("/harryPotterCharacters", (req, res) => { - const house = req.query.house; + const house = req.query.house; // Query parameter for house + const year = req.query.yearIntroduced; // Query parameter for yearIntroduced + const role = req.query.role; // Query parameter for role - // If a 'house' query parameter is provided.... + // Filter by house if (house) { const filteredCharacters = harryPotterCharactersData.filter(character => - character.house.toLocaleLowerCase() === house.toLocaleLowerCase() + character.house.toLowerCase() === house.toLowerCase() ); - res.json(filteredCharacters); // ...then return a filtered list based on house - } else { - res.json(harryPotterCharactersData); // No filter = respond with all characters + res.json(filteredCharacters); } -}); -//_____________________________________________________________ -app.get("/harryPotterCharacters/role/:role", (req, res) => { - const role = req.params.role; - - const characterRole = harryPotterCharactersData.filter(character => - character.role.toLocaleLowerCase() === role.toLocaleLowerCase() - ); - - if (characterRole.length > 0) { + // Filter by role + else if (role) { + const characterRole = harryPotterCharactersData.filter(character => + character.role.toLowerCase() === role.toLowerCase() + ); res.json(characterRole); - } else { - res.status(404).send("No characters found with that role"); + } + // Filter by yearIntroduced + else if (year) { + const charactersIntroducedInYear = harryPotterCharactersData.filter(character => + character.yearIntroduced === +year + ); + res.json(charactersIntroducedInYear); + } + else { + res.json(harryPotterCharactersData); // No filters = return all characters + } }); -//_____________________________________________________________ -//Sort by id - getting each character based on the id number + +//Sort by id - getting each character based on their unique id number app.get("/harryPotterCharacters/:id", (req, res) => { const id = req.params.id; @@ -54,27 +63,26 @@ app.get("/harryPotterCharacters/:id", (req, res) => { if (harryPotterCharacter) { res.status(200).json(harryPotterCharacter); } else { - res.status(404).send("No character found with that id"); + res.status(404).send("Sorry - no character found with that id"); } }); -// //_____________________________________________________________ -// Filter by yearIntroduced -app.get("/harryPotterCharacters/:yearIntroduced", (req, res) => { - const year = req.params.yearIntroduced; - //Filter the characters based on the yearIntroduced property - const charactersIntroducedInYear = harryPotterCharactersData.filter(character => character.yearIntroduced === +year); +// Sort by name - getting each character based on their unique name (adding the extra /name "prefix" to distinguish this route from the /id route) +app.get("/harryPotterCharacters/name/:name", (req, res) => { + const name = req.params.name.toLowerCase(); - if (charactersIntroducedInYear.length > 0) { - res.status(200).json(charactersIntroducedInYear); + const harryPotterCharacterName = harryPotterCharactersData.find(character => + character.name.toLowerCase() === name + ); + + if (harryPotterCharacterName) { + res.status(200).json(harryPotterCharacterName); } else { - res.status(404).send("No characters found from that year"); + res.status(404).send("Sorry - no character found with that name"); } }); -//_____________________________________________________________ - // Start the server app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); -}); +}); \ No newline at end of file From 276c2cf32b9f9f1e3a4751f10f40d726e338c8b1 Mon Sep 17 00:00:00 2001 From: iamfannyhenriques Date: Sun, 8 Dec 2024 23:08:50 +0100 Subject: [PATCH 3/3] added deployed link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5241826b3..455e3a253 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ Describe how you approached to problem, and what tools and techniques you used t ## 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-express-api-qyuo.onrender.com/