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

Express API - Dog breeds - Jenny A #529

Open
wants to merge 5 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
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Project Express 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.
In our first step into backend, the assigment was to create an API using Express. The API should have at least a couple of RESTful endpoints which return either an array of data or a single item.

## 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?
I created an API about dog breeds using Express.js and Node.js. The main challenge was getting the file paths right and figuring out how to filter the data by categories. I learned a lot about working with JSON data and API endpoints.
If I had more time, I would add more filtering options and create a simple frontend to display the data in a user-friendly way.

## 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-y1pr.onrender.com/

GET "/" - Shows API documentation
GET "/dogs" - Returns all dogs (can be filtered by category using ?category=...)
GET "/dogs/:id" - Returns a specific dog by ID
242 changes: 242 additions & 0 deletions data/dog-breeds.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
[
{
"id": 1,
"name": "German Shepherd",
"origin": "Germany",
"category": "Herding",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 2,
"name": "Labrador Retriever",
"origin": "Canada",
"category": "Sporting",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 3,
"name": "Poodle",
"origin": "Germany/France",
"category": "Non-Sporting",
"familyFriendly": "yes",
"size": "Various"
},
{
"id": 4,
"name": "Golden Retriever",
"origin": "Scotland",
"category": "Sporting",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 5,
"name": "Bulldog",
"origin": "England",
"category": "Non-Sporting",
"familyFriendly": "yes",
"size": "Medium"
},
{
"id": 6,
"name": "Rottweiler",
"origin": "Germany",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 7,
"name": "Beagle",
"origin": "England",
"category": "Hound",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 8,
"name": "Siberian Husky",
"origin": "Russia",
"category": "Working",
"familyFriendly": "yes",
"size": "Medium"
},
{
"id": 9,
"name": "Chihuahua",
"origin": "Mexico",
"category": "Toy",
"familyFriendly": "no",
"size": "Small"
},
{
"id": 10,
"name": "Great Dane",
"origin": "Germany",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 11,
"name": "Pug",
"origin": "China",
"category": "Toy",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 12,
"name": "Doberman Pinscher",
"origin": "Germany",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 13,
"name": "Yorkshire Terrier",
"origin": "England",
"category": "Toy",
"familyFriendly": "no",
"size": "Small"
},
{
"id": 14,
"name": "Boxer",
"origin": "Germany",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 15,
"name": "Shih Tzu",
"origin": "Tibet",
"category": "Toy",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 16,
"name": "Australian Shepherd",
"origin": "United States",
"category": "Herding",
"familyFriendly": "yes",
"size": "Medium"
},
{
"id": 17,
"name": "Border Collie",
"origin": "Scotland",
"category": "Herding",
"familyFriendly": "yes",
"size": "Medium"
},
{
"id": 18,
"name": "Chow Chow",
"origin": "China",
"category": "Non-Sporting",
"familyFriendly": "no",
"size": "Medium"
},
{
"id": 19,
"name": "Bernese Mountain Dog",
"origin": "Switzerland",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 20,
"name": "French Bulldog",
"origin": "France",
"category": "Non-Sporting",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 21,
"name": "Dachshund",
"origin": "Germany",
"category": "Hound",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 22,
"name": "Saint Bernard",
"origin": "Switzerland",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 23,
"name": "Corgi",
"origin": "Wales",
"category": "Herding",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 24,
"name": "Dalmatian",
"origin": "Croatia",
"category": "Non-Sporting",
"familyFriendly": "yes",
"size": "Medium"
},
{
"id": 25,
"name": "Afghan Hound",
"origin": "Afghanistan",
"category": "Hound",
"familyFriendly": "no",
"size": "Large"
},
{
"id": 26,
"name": "Alaskan Malamute",
"origin": "United States",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 27,
"name": "Bichon Frise",
"origin": "Spain",
"category": "Non-Sporting",
"familyFriendly": "yes",
"size": "Small"
},
{
"id": 28,
"name": "Bull Terrier",
"origin": "England",
"category": "Terrier",
"familyFriendly": "yes",
"size": "Medium"
},
{
"id": 29,
"name": "Greyhound",
"origin": "Egypt",
"category": "Hound",
"familyFriendly": "yes",
"size": "Large"
},
{
"id": 30,
"name": "Newfoundland",
"origin": "Canada",
"category": "Working",
"familyFriendly": "yes",
"size": "Large"
}
]
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"cors": "^2.8.5",
"express": "^4.17.3",
"express": "^4.21.2",
"express-list-endpoints": "^7.1.1",
"nodemon": "^3.0.1"
}
},
"main": "server.js",
"keywords": []
}
84 changes: 65 additions & 19 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,76 @@
import express from "express";
import cors from "cors";
const express = require("express"); // Web application framework
const cors = require("cors"); // CORS is needed to allow requests from different domains
const listEndpoints = require('express-list-endpoints'); // Used to generate API documentation
const dogs = require("./data/dog-breeds.json"); // Import our dogs data from JSON file

// 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
// Sets up server port - uses environment variable if available, otherwise use 8080
const port = process.env.PORT || 8080;
// Initialize express application
const app = express();

// Add middlewares to enable cors and json body parsing
app.use(cors());
app.use(express.json());
// Middleware setup
app.use(cors()); // Enable CORS for all routes
app.use(express.json()); // Parse incoming JSON requests

// Route for getting a single dog by ID
app.get("/dogs/:id", (req, res) => {
const id = req.params.id; // Get the ID from the URL parameter
console.log("Requested ID:", id, "Type:", typeof id);

// Finds the dog with matching ID (converts string ID to number for comparison)
const dog = dogs.find(dog => {
return dog.id === parseInt(id);
});

// If no dog is found with that ID, return 404 error
if (!dog) {
res.status(404).json({ error: "Dog breed not found" });
} else {
res.json(dog); // Return the found dog
}
});

// Route for getting all dogs, with optional filters
app.get("/dogs", (req, res) => {
const { category, size, origin, familyFriendly } = req.query; // Get all filters from query parameters
console.log("Query parameters:", req.query);

let filteredDogs = [...dogs];

// Start defining your routes here
if (category) {
filteredDogs = filteredDogs.filter(dog =>
dog.category.toLowerCase() === category.toLowerCase()
);
}
if (size) {
filteredDogs = filteredDogs.filter(dog =>
dog.size.toLowerCase() === size.toLowerCase()
);
}
if (origin) {
filteredDogs = filteredDogs.filter(dog =>
dog.origin.toLowerCase() === origin.toLowerCase()
);
}
if (familyFriendly) {
filteredDogs = filteredDogs.filter(dog =>
dog.familyFriendly.toLowerCase() === familyFriendly.toLowerCase()
);
}

res.json(filteredDogs);
});
Comment on lines +34 to +62
Copy link
Contributor

Choose a reason for hiding this comment

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

Excellent work making use of query params and chaining the filters like this, works like a charm ⭐

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for the feedback @HIPPIEKICK! Hahaha I was also really confused by the "Toy" category so I asked ChatGPT and apparently it's "the official classification for small breeds that were specifically developed to be companion pets rather than working dogs". So small lap dogs! You live and you learn 😂😂


// Root route - returns API documentation
app.get("/", (req, res) => {
res.send("Hello Technigo!");
const endpoints = listEndpoints(app); // Generate list of all available endpoints
res.json({
description: "Dog Breeds API - Access information about different dog breeds",
endpoints: endpoints // Shows all available API endpoints
});
});

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