-
Notifications
You must be signed in to change notification settings - Fork 515
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
Fantasy Realm API #507
Open
HeleneWestrin
wants to merge
9
commits into
Technigo:master
Choose a base branch
from
HeleneWestrin:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Fantasy Realm API #507
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
cdb1441
Created a Fntasty World API with worlds, characters, quests and items…
HeleneWestrin 1e7e0e6
Vercel stuff
HeleneWestrin e42020e
Vercel updates
HeleneWestrin f41ecee
Update
HeleneWestrin 0e622f6
Added documenatation to README
HeleneWestrin a55a234
Added documenatation to README
HeleneWestrin 45211b9
Added documenatation to README
HeleneWestrin 13e6e4a
Added documenatation to README
HeleneWestrin 95e7b19
Added documenatation to README
HeleneWestrin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,172 @@ | ||
# Project Mongo API | ||
# Fantasy World API | ||
|
||
Replace this readme with your own information about your project. | ||
A REST API for managing a fantasy realm with characters, quests, items, and worlds. | ||
|
||
Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. | ||
## **See it live:** | ||
|
||
## The problem | ||
- Production: [https://fantasy-world-mongodb-api.vercel.app](https://fantasy-world-mongodb-api.vercel.app) | ||
You may need to refresh a couple of times before the server awakens. | ||
|
||
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? | ||
--- | ||
|
||
## View it live | ||
## **Endpoints** | ||
|
||
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. | ||
### **Worlds** | ||
|
||
#### **GET /worlds** | ||
|
||
Retrieve a list of all worlds. | ||
|
||
**Response:** | ||
|
||
```json | ||
[ | ||
{ | ||
"_id": "675c299a308f20c14cc641f4", | ||
"name": "Middle Earth", | ||
"description": "A mystical land with elves, dwarves, and hobbits." | ||
} | ||
] | ||
``` | ||
|
||
--- | ||
|
||
### **Characters** | ||
|
||
#### **GET /characters** | ||
|
||
Retrieve a list of characters. Supports optional query parameters. | ||
|
||
**Query Parameters:** | ||
|
||
- `homeWorld`: Filter characters by their home world ID. | ||
- `item`: Filter characters by the item they own. | ||
|
||
**Example Request:** | ||
|
||
```bash | ||
GET /characters?homeWorld=675c3e604c6a6806a5c1cf7c&item=675c3e604c6a6806a5c1cf92 | ||
``` | ||
|
||
**Response:** | ||
|
||
```json | ||
[ | ||
{ | ||
"_id": "675c299a308f20c14cc641fa", | ||
"name": "Frodo Baggins", | ||
"role": "Hobbit", | ||
"homeWorld": { | ||
"_id": "675c299a308f20c14cc641f4", | ||
"name": "Middle Earth", | ||
"description": "A mystical land with elves, dwarves, and hobbits." | ||
}, | ||
"quests": [ | ||
{ | ||
"_id": "675c299a308f20c14cc64202", | ||
"title": "Destroy the One Ring", | ||
"description": "Carry the One Ring to Mount Doom to save Middle Earth.", | ||
"reward": "Peace for Middle Earth" | ||
} | ||
], | ||
"item": { | ||
"_id": "675c299a308f20c14cc6420c", | ||
"name": "Sting", | ||
"type": "Weapon" | ||
} | ||
} | ||
] | ||
``` | ||
|
||
#### **POST /characters** | ||
|
||
Create a new character. | ||
|
||
**Request Body:** | ||
|
||
```json | ||
{ | ||
"name": "Aragorn", | ||
"role": "Ranger", | ||
"homeWorld": "675c299a308f20c14cc641f4", | ||
"item": "675c299a308f20c14cc6420d", | ||
"quests": ["675c299a308f20c14cc64202"] | ||
} | ||
``` | ||
|
||
**Response:** | ||
|
||
```json | ||
{ | ||
"_id": "675c299a308f20c14cc64215", | ||
"name": "Aragorn", | ||
"role": "Ranger", | ||
"homeWorld": "675c299a308f20c14cc641f4", | ||
"item": "675c299a308f20c14cc6420d", | ||
"quests": ["675c299a308f20c14cc64202"] | ||
} | ||
``` | ||
|
||
--- | ||
|
||
### **Quests** | ||
|
||
#### **GET /quests** | ||
|
||
Retrieve a list of all quests. | ||
|
||
**Response:** | ||
|
||
```json | ||
[ | ||
{ | ||
"_id": "675c299a308f20c14cc64202", | ||
"title": "Destroy the One Ring", | ||
"description": "Carry the One Ring to Mount Doom to save Middle Earth.", | ||
"reward": "Peace for Middle Earth", | ||
"assignedTo": ["675c299a308f20c14cc641fa", "675c299a308f20c14cc641fb"] | ||
} | ||
] | ||
``` | ||
|
||
--- | ||
|
||
### **Items** | ||
|
||
#### **GET /items** | ||
|
||
Retrieve a list of all items. | ||
|
||
**Response:** | ||
|
||
```json | ||
[ | ||
{ | ||
"_id": "675c299a308f20c14cc6420c", | ||
"name": "Sting", | ||
"type": "Weapon", | ||
"owner": "675c299a308f20c14cc641fa" | ||
} | ||
] | ||
``` | ||
|
||
--- | ||
|
||
## **Error Handling** | ||
|
||
All endpoints return standard HTTP status codes with an error message if something goes wrong. | ||
|
||
**Example Error Response:** | ||
|
||
```json | ||
{ | ||
"error": "Validation error", | ||
"details": [ | ||
{ | ||
"msg": "Name is required.", | ||
"param": "name", | ||
"location": "body" | ||
} | ||
] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import express from "express"; | ||
import listEndpoints from "express-list-endpoints"; | ||
import cors from "cors"; | ||
import { worldRoutes } from "./routes/world.routes.js"; | ||
import { characterRoutes } from "./routes/character.routes.js"; | ||
import { questRoutes } from "./routes/quest.routes.js"; | ||
import { itemRoutes } from "./routes/item.routes.js"; | ||
import { checkDbConnection } from "./middleware/dbConnection.js"; | ||
|
||
export const app = express(); | ||
|
||
// Middleware | ||
app.use(cors()); | ||
app.use(express.json()); | ||
app.use(checkDbConnection); | ||
|
||
// Routes | ||
app.use("/worlds", worldRoutes); | ||
app.use("/characters", characterRoutes); | ||
app.use("/quests", questRoutes); | ||
app.use("/items", itemRoutes); | ||
|
||
// API documentation | ||
app.get("/", (req, res) => { | ||
res.json(listEndpoints(app)); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import mongoose from "mongoose"; | ||
|
||
export const connectDatabase = async () => { | ||
const mongoUrl = process.env.MONGO_URL; | ||
// const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/fantasy-world"; | ||
|
||
try { | ||
await mongoose.connect(mongoUrl); | ||
console.log("Database connected successfully!"); | ||
} catch (error) { | ||
console.error("Database connection failed:", error); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Character } from "../models/character.model.js"; | ||
|
||
export const getCharacters = async (req, res) => { | ||
try { | ||
// Extract query params | ||
const { homeWorld, item } = req.query; | ||
|
||
const filter = {}; | ||
if (homeWorld) filter.homeWorld = homeWorld; | ||
if (item) filter.item = item; | ||
|
||
const characters = await Character.find(filter) | ||
.populate("homeWorld") | ||
.populate("quests") | ||
.populate("item"); | ||
res.status(200).json(characters); | ||
} catch (error) { | ||
res.status(500).json({ error: "Failed to fetch characters" }); | ||
} | ||
}; | ||
|
||
export const createCharacter = async (req, res) => { | ||
try { | ||
// Validate required fields | ||
const { name, role, homeWorld } = req.body; | ||
|
||
// Collect missing fields dynamically | ||
const missingFields = []; | ||
if (!name) missingFields.push("name"); | ||
if (!role) missingFields.push("role"); | ||
if (!homeWorld) missingFields.push("homeWorld"); | ||
|
||
// If there are missing fields, return a 400 error | ||
if (missingFields.length > 0) { | ||
return res.status(400).json({ | ||
error: `Missing required fields: ${missingFields.join(", ")}`, | ||
}); | ||
} | ||
|
||
// Create and save the character | ||
const character = new Character(req.body); | ||
await character.save(); | ||
res.status(201).json(character); | ||
} catch (error) { | ||
// Check for validation errors from Mongoose | ||
if (error.name === "ValidationError") { | ||
const errors = Object.values(error.errors).map((err) => err.message); | ||
return res | ||
.status(400) | ||
.json({ error: "Validation error", details: errors }); | ||
} | ||
|
||
// Check for MongoDB duplicate key errors | ||
if (error.code === 11000) { | ||
return res | ||
.status(400) | ||
.json({ error: "Duplicate key error", details: error.keyValue }); | ||
} | ||
|
||
// General server error | ||
res | ||
.status(500) | ||
.json({ error: "Internal server error", details: error.message }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Item } from "../models/item.model.js"; | ||
|
||
export const getItems = async (req, res) => { | ||
try { | ||
const items = await Item.find().populate("owner"); | ||
res.status(200).json(items); | ||
} catch (error) { | ||
res.status(500).json({ error: "Failed to fetch items" }); | ||
} | ||
}; | ||
|
||
export const createItem = async (req, res) => { | ||
try { | ||
const item = new Item(req.body); | ||
await item.save(); | ||
res.status(201).json(item); | ||
} catch (error) { | ||
res.status(400).json({ error: "Failed to create item" }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Quest } from "../models/quest.model.js"; | ||
|
||
export const getQuests = async (req, res) => { | ||
try { | ||
const quests = await Quest.find().populate("assignedTo"); | ||
res.status(200).json(quests); | ||
} catch (error) { | ||
res.status(500).json({ error: "Failed to fetch quests" }); | ||
} | ||
}; | ||
|
||
export const createQuest = async (req, res) => { | ||
try { | ||
const quest = new Quest(req.body); | ||
await quest.save(); | ||
res.status(201).json(quest); | ||
} catch (error) { | ||
res.status(400).json({ error: "Failed to create quest" }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { World } from "../models/world.model.js"; | ||
|
||
export const getWorlds = async (req, res) => { | ||
try { | ||
const worlds = await World.find(); | ||
res.status(200).json(worlds); | ||
} catch (error) { | ||
res.status(500).json({ error: "Failed to fetch worlds" }); | ||
} | ||
}; | ||
|
||
export const createWorld = async (req, res) => { | ||
try { | ||
const world = new World(req.body); | ||
await world.save(); | ||
res.status(201).json(world); | ||
} catch (error) { | ||
res.status(400).json({ error: "Failed to create world" }); | ||
} | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this tip ⭐