Skip to content

Commit

Permalink
Refactored API Routes into Separate Files (#263)
Browse files Browse the repository at this point in the history
* finished refactoring api routes

* fixed a problem

* fixed problems

* Updated File Names
  • Loading branch information
Kavipatel0 authored Sep 10, 2024
1 parent 63a600e commit 6ed72c8
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 179 deletions.
183 changes: 4 additions & 179 deletions server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Mailgun from "mailgun.js";
import { messagesCollection } from "./utilities/firebaseInit";
import { calculateDistanceInMeters } from "./actions/calculateDistance";
import { scheduleCron } from "./actions/deleter";
import mainRouter from "./routes/mainRouteHandler";

const { createServer } = require("http");
const { Server } = require("socket.io");
Expand Down Expand Up @@ -156,194 +157,18 @@ app.get("/", (req, res) => {
res.send("Echologator API");
});

app.get("/users", async (req, res) => {
let query = "";
try {
if (req.query.lat && req.query.lon && req.query.radius) {
// Looks up all users close to a geographic location extended by a radius (in meters).
query = "?lat&lon&radius";

const lat = Number(req.query.lat);
const lon = Number(req.query.lon);
const radius = Number(req.query.radius);
app.use(mainRouter);

const userIds = await findNearbyUsers(lat, lon, radius);
res.json(userIds);
} else if (req.query.userId) {
query = "?userId";
const userId = req.query.userId;
if (typeof userId != "string") throw Error(" [userId] is not a string.");

const user = await getConnectedUser(userId);
if (user) {
res.json(user);
} else {
// getConnectedUserDisplayName() will return false is an error is thrown, and print it to console.
throw Error("getConnectedUser() failed.");
}
}
} catch (error) {
console.error(
`[EXP] Error returning request <GET /users${query}>:\n`,
error.message
);
res.json(`Operation <GET /users${query}> failed.`);
}
});

app.post("/users", async (req, res) => {
try {
const status = await createUser({
uid: req.body.uid,
socketId: req.body.socketId,
displayName: req.body.displayName,
userIcon: {
foregroundImage: req.body.userIcon.foregroundImage,
backgroundImage: req.body.userIcon.backgroundImage,
},
location: {
lat: Number(req.body.location.lat),
lon: Number(req.body.location.lon),
geohash: req.body.location.geohash,
},
});
if (status === false) throw new Error("Error creating user: ");
res.json("Operation <POST /user> was handled successfully.");
console.log("[EXP] Request <POST /users> returned successfully.");
} catch (error) {
console.error(
"[EXP] Error returning request <POST /users>:\n",
error.message
);
res.json(`Operation <POST /user> failed.`);
}
});

app.put("/users", async (req, res) => {
let query = "";
try {
if (req.query.userId && req.query.toggleConnection) {
// Note: toggleConnection should be assigned 'true', but it at least needs to contain any value. We don't perform a check on this parameter for this reason.
query = "?userId&toggleConnection";
const userId = req.query.userId;
if (typeof userId != "string") throw Error(" [userId] is not a string.");

const success = await toggleUserConnectionStatus(userId);
if (!success) throw Error(" toggleUserConnectionStatus() failed.");
} else if (req.query.userId && req.query.lat && req.query.lon) {
query = "?userId&lat&lon";
const userId = req.query.userId;
const lat = Number(req.query.lat);
const lon = Number(req.query.lon);
if (typeof userId != "string") throw Error(" [userId] is not a string.");
if (typeof lat != "number") throw Error(" [lat] is not a number.");
if (typeof lon != "number") throw Error(" [lon] is not a number.");

const success = await updateUserLocation(userId, lat, lon);
if (!success) throw Error(" toggleUserConnectionStatus() failed.");
} else if (req.query.userId && req.query.displayName) {
query = "?userId&displayName";
const userId = req.query.userId;
if (typeof userId != "string") throw Error(" [userId] is not a string.");
const displayName = req.query.displayName;
if (typeof displayName != "string")
throw Error(" [displayName] is not a string.");

const success = await updateUserDisplayName(userId, displayName);
if (!success) throw Error("updateDisplayName() failed.");
}
console.log(`[EXP] Request <PUT /users${query}> returned successfully.`);
res.json(`Operation <PUT /users${query}> was handled successfully.`);
} catch (error) {
console.error(
`[EXP] Error returning request <PUT /users${query}>:\n`,
error.message
);
res.json(`Operation <PUT /user${query}> failed.`);
}
});

app.delete("/users", async (req, res) => {
let query = "";
try {
query = "?userId";
const userId = req.query.userId;
if (typeof userId != "string") throw Error(" [userId] is not a string.");

const success = await deleteConnectedUserByUID(userId);
if (!success) throw Error(" deleteUserById() failed.");

console.log(`[EXP] Request <DELETE /users${query}> returned successfully.`);
res.json(`Operation <DELETE /users${query}> was handled successfully.`);
} catch (error) {
console.error(
`[EXP] Error returning request <DELETE /users${query}>:\n`,
error.message
);
res.json(`Operation <DELETE /user${query}> failed.`);
}
});

app.post("/verify", async (req, res) => {
let query = "";
try {
if (req.query.email) {
query = "?email";
const email = req.query.email;
const mailgun = new Mailgun(FormData);
const mg = mailgun.client({
username: "api",
key: process.env.MAILGUN_API_KEY || "key-yourkeyhere",
});
const data = {
from: "Mailgun Sandbox <[email protected]>",
to: email,
subject: "Verify your email for echologator",
template: "app email verification",
};
const verifyEmailResponse = await mg.messages.create(
"sandboxf8629624c26849cf8546cd0bc01ee862.mailgun.org",
data
);
console.log(`[EXP] Request <POST /verify${query}>returned successfully.`);
res.json(verifyEmailResponse);
}
} catch (error) {
console.error(
`[EXP] Error returning request <POST /verify${query}>:\n`,
error
);
res.json(`Operation <POST /verify${query}> failed.`);
}
});

// Error handling
app.get("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {GET}");
res.status(404);
});

app.post("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {POST}");
res.status(404);
});

app.put("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {PUT}");
res.status(404);
});

app.delete("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {DELETE}");
res.status(404);
});

app.listen(express_port, () => {
return console.log(
`[EXP] Listening for requests at http://localhost:${express_port}.`
);
});



//Remove the comments if you want to use the deleter !!!!!!
//scheduleCron(); // Begin searching and collecting Garbage (old messages)

Expand Down
10 changes: 10 additions & 0 deletions server/src/routes/auth/authRouteHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Router } from "express";
import authEmailRoute from "./email";

const authRouter = Router();


authRouter.use(authEmailRoute);


export default authRouter;
39 changes: 39 additions & 0 deletions server/src/routes/auth/email.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Router } from "express";
import Mailgun from "mailgun.js";

const authEmailRoute = Router();

authEmailRoute.post("/verify", async (req, res) => {
let query = "";
try {
if (req.query.email) {
query = "?email";
const email = req.query.email;
const mailgun = new Mailgun(FormData);
const mg = mailgun.client({
username: "api",
key: process.env.MAILGUN_API_KEY || "key-yourkeyhere",
});
const data = {
from: "Mailgun Sandbox <[email protected]>",
to: email,
subject: "Verify your email for echologator",
template: "app email verification",
};
const verifyEmailResponse = await mg.messages.create(
"sandboxf8629624c26849cf8546cd0bc01ee862.mailgun.org",
data
);
console.log(`[EXP] Request <POST /verify${query}>returned successfully.`);
res.json(verifyEmailResponse);
}
} catch (error) {
console.error(
`[EXP] Error returning request <POST /verify${query}>:\n`,
error
);
res.json(`Operation <POST /verify${query}> failed.`);
}
});

export default authEmailRoute;
27 changes: 27 additions & 0 deletions server/src/routes/error/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Router } from "express";

const errorRouter = Router();


// Error handling
errorRouter.get("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {GET}");
res.status(404);
});

errorRouter.post("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {POST}");
res.status(404);
});

errorRouter.put("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {PUT}");
res.status(404);
});

errorRouter.delete("*", (req, res) => {
res.json("404: Path could not be found! COULD NOT {DELETE}");
res.status(404);
});

export default errorRouter;
12 changes: 12 additions & 0 deletions server/src/routes/mainRouteHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Router } from "express";
import authRouter from "./auth/authRouteHandler";
import userRouter from "./user/userRouteHandler";
import errorRouter from "./error/error";

const mainRouter = Router();

mainRouter.use(authRouter);
mainRouter.use(userRouter);
mainRouter.use(errorRouter);

export default mainRouter;
34 changes: 34 additions & 0 deletions server/src/routes/user/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Router } from "express";
import { createUser } from "../../actions/createConnectedUser";

const createUserRoute = Router();

createUserRoute.post("/users", async (req, res) => {
try {
const status = await createUser({
uid: req.body.uid,
socketId: req.body.socketId,
displayName: req.body.displayName,
userIcon: {
foregroundImage: req.body.userIcon.foregroundImage,
backgroundImage: req.body.userIcon.backgroundImage,
},
location: {
lat: Number(req.body.location.lat),
lon: Number(req.body.location.lon),
geohash: req.body.location.geohash,
},
});
if (status === false) throw new Error("Error creating user: ");
res.json("Operation <POST /user> was handled successfully.");
console.log("[EXP] Request <POST /users> returned successfully.");
} catch (error) {
console.error(
"[EXP] Error returning request <POST /users>:\n",
error.message
);
res.json(`Operation <POST /user> failed.`);
}
});

export default createUserRoute;
27 changes: 27 additions & 0 deletions server/src/routes/user/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Router } from "express";
import { deleteConnectedUserByUID } from "../../actions/deleteConnectedUser";

const deleteUserRoute = Router();

deleteUserRoute.post("/users", async (req, res) => {
let query = "";
try {
query = "?userId";
const userId = req.query.userId;
if (typeof userId != "string") throw Error(" [userId] is not a string.");

const success = await deleteConnectedUserByUID(userId);
if (!success) throw Error(" deleteUserById() failed.");

console.log(`[EXP] Request <DELETE /users${query}> returned successfully.`);
res.json(`Operation <DELETE /users${query}> was handled successfully.`);
} catch (error) {
console.error(
`[EXP] Error returning request <DELETE /users${query}>:\n`,
error.message
);
res.json(`Operation <DELETE /user${query}> failed.`);
}
});

export default deleteUserRoute;
Loading

0 comments on commit 6ed72c8

Please sign in to comment.