refactoring controller responses (in progress)

This commit is contained in:
Mikayla Dobson
2022-12-12 20:07:09 -06:00
parent 362cf752d0
commit d2b06ced7a
6 changed files with 83 additions and 44 deletions

View File

@@ -1,14 +1,14 @@
import createError from "http-errors";
import { IRecipe } from "../schemas"; import { IRecipe } from "../schemas";
import { Recipe } from "../models/recipe"; import { Recipe } from "../models/recipe";
import ControllerResponse from "../util/ControllerResponse";
const RecipeInstance = new Recipe(); const RecipeInstance = new Recipe();
export default class RecipeCtl { export default class RecipeCtl {
async getOne(id: string) { async getOne(id: string) {
try { try {
const result = await RecipeInstance.getOneByID(id); const result = await RecipeInstance.getOneByID(id);
if (!result) throw createError('404', "Recipe not found"); const ok = result !== null;
return result; return new ControllerResponse(ok, (ok ? 200 : 404), (ok ? result : "No recipe found with this ID"));
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }
@@ -17,8 +17,8 @@ export default class RecipeCtl {
async getAllAuthored(id: string) { async getAllAuthored(id: string) {
try { try {
const result = await RecipeInstance.getAllAuthored(id); const result = await RecipeInstance.getAllAuthored(id);
if (!result) throw createError('404', "No recipes found"); const ok = result !== null;
return result; return new ControllerResponse(ok, (ok ? 200 : 404), (ok ? result : "No recipes found authored by user with this ID"));
} catch (e: any) { } catch (e: any) {
throw new Error(e); throw new Error(e);
} }
@@ -35,8 +35,8 @@ export default class RecipeCtl {
async updateOne(id: string, data: IRecipe) { async updateOne(id: string, data: IRecipe) {
try { try {
const result = await RecipeInstance.updateOneByID(id, data); const result = await RecipeInstance.updateOneByID(id, data);
if (!result) throw createError('400', "Bad request"); const ok = result !== null;
return result; return new ControllerResponse(ok, (ok ? 200 : 400), (ok ? result : "Something went wrong"));
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }
@@ -45,8 +45,8 @@ export default class RecipeCtl {
async post(userid: string, data: IRecipe) { async post(userid: string, data: IRecipe) {
try { try {
const result = await RecipeInstance.post(userid, data); const result = await RecipeInstance.post(userid, data);
if (!result) throw createError('400', "Bad request"); const ok = result !== null;
return result; return new ControllerResponse(ok, (ok ? 201 : 400), (ok ? result : "Something went wrong"));
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }

View File

@@ -1,24 +1,31 @@
import createError from 'http-errors';
import { IUser } from '../schemas'; import { IUser } from '../schemas';
import { User } from "../models/user"; import { User } from "../models/user";
import ControllerResponse from '../util/ControllerResponse';
const UserInstance = new User(); const UserInstance = new User();
export default class UserCtl { export default class UserCtl {
ok?: boolean
code?: number
async getAll() { async getAll() {
try { try {
const users = await UserInstance.getAllUsers(); const users = await UserInstance.getAllUsers();
if (!users) throw createError(404, "No users found"); const ok = users.length > 0;
return users; const code = ok ? 200 : 404;
const data = ok ? users : "No users found.";
return new ControllerResponse(ok, code, data)
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }
} }
async post(data: IUser) { async post(body: IUser) {
try { try {
const response = await UserInstance.post(data); const response = await UserInstance.post(body);
// if (!response) throw createError(400, "Bad request"); const ok: boolean = response !== null;
return response; const code = ok ? 201 : 400
const data = ok ? response : "Bad request"
return new ControllerResponse(ok, code, data);
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }
@@ -27,18 +34,22 @@ export default class UserCtl {
async getOne(id: number | string) { async getOne(id: number | string) {
try { try {
const user = await UserInstance.getOneByID(id); const user = await UserInstance.getOneByID(id);
if (!user) throw createError(404, "User not found"); const ok: boolean = user !== null;
return user; const code = ok ? 200 : 404;
const data = ok ? user : "User by this ID not found";
return new ControllerResponse(ok, code, data);
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }
} }
async updateOne(id: number | string, data: IUser) { async updateOne(id: number | string, body: IUser) {
try { try {
const result = await UserInstance.updateOneByID(id, data); const result = await UserInstance.updateOneByID(id, body);
if (!result) throw createError(400, "Bad request"); const ok = result !== null;
return result; const code = ok ? 200 : 400;
const data = ok ? result : "Update unsuccessful"
return new ControllerResponse(ok, code, data);
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }
@@ -47,8 +58,10 @@ export default class UserCtl {
async getFriends(id: number | string) { async getFriends(id: number | string) {
try { try {
const result = await UserInstance.getFriends(id); const result = await UserInstance.getFriends(id);
if (!result) return createError(404, "You have no friends"); const ok = result !== null
return result; const code = ok ? 200 : 404;
const data = ok ? result : "No friends found"
return new ControllerResponse(ok, code, data);
} catch (e: any) { } catch (e: any) {
throw new Error(e); throw new Error(e);
} }
@@ -57,8 +70,7 @@ export default class UserCtl {
async getFriendshipByID(id: number | string, userid: number | string) { async getFriendshipByID(id: number | string, userid: number | string) {
try { try {
const { ok, code, result } = await UserInstance.getFriendshipByID(id, userid); const { ok, code, result } = await UserInstance.getFriendshipByID(id, userid);
if (ok) return result; return new ControllerResponse(ok, code, result);
throw createError(code, result);
} catch (e: any) { } catch (e: any) {
throw new Error(e); throw new Error(e);
} }
@@ -67,8 +79,7 @@ export default class UserCtl {
async getPendingFriendRequests(senderid: string | number) { async getPendingFriendRequests(senderid: string | number) {
try { try {
const { ok, code, result } = await UserInstance.getPendingFriendRequests(senderid); const { ok, code, result } = await UserInstance.getPendingFriendRequests(senderid);
if (ok) return result; return new ControllerResponse(ok, code, result);
throw createError(code, result);
} catch (e: any) { } catch (e: any) {
throw new Error(e); throw new Error(e);
} }
@@ -77,8 +88,10 @@ export default class UserCtl {
async addFriendship(userid: number | string, targetid: number | string) { async addFriendship(userid: number | string, targetid: number | string) {
try { try {
const result = await UserInstance.addFriendship(userid, targetid); const result = await UserInstance.addFriendship(userid, targetid);
if (!result) throw createError(400, "something went wrong"); const ok = result !== null;
return result; const code = ok ? 201 : 400;
const data = ok ? result : "Something went wrong"
return new ControllerResponse(ok, code, data);
} catch (e: any) { } catch (e: any) {
throw new Error(e); throw new Error(e);
} }
@@ -87,8 +100,7 @@ export default class UserCtl {
async updateFriendship(id: number | string, userid: number | string, data: { active: boolean, pending: boolean, dateterminated?: string }) { async updateFriendship(id: number | string, userid: number | string, data: { active: boolean, pending: boolean, dateterminated?: string }) {
try { try {
const { ok, code, result } = await UserInstance.updateFriendship(id, userid, data); const { ok, code, result } = await UserInstance.updateFriendship(id, userid, data);
if (ok) return result; return new ControllerResponse(ok, code, result);
throw createError(code, result);
} catch (e: any) { } catch (e: any) {
throw new Error(e); throw new Error(e);
} }

View File

@@ -11,7 +11,7 @@ export class User {
const statement = `SELECT * FROM recipin.appusers`; const statement = `SELECT * FROM recipin.appusers`;
const result = await pool.query(statement); const result = await pool.query(statement);
if (result.rows.length) return result.rows; if (result.rows.length) return result.rows;
return null; return [];
} catch (error: any) { } catch (error: any) {
throw new Error(error); throw new Error(error);
} }

View File

@@ -1,6 +1,7 @@
import { Express, Router } from 'express'; import { Express, Router } from 'express';
import UserCtl from '../controllers/UserCtl'; import UserCtl from '../controllers/UserCtl';
import { IUser } from '../schemas'; import { IUser } from '../schemas';
import { CtlResponse } from '../util/types';
const router = Router(); const router = Router();
const userCtl = new UserCtl(); const userCtl = new UserCtl();
@@ -9,23 +10,27 @@ export const userRoute = (app: Express) => {
// get all users // get all users
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
const data = await userCtl.getAll(); const result: CtlResponse<IUser | string> = await userCtl.getAll();
res.status(200).send(data); res.status(result.code).send(result.data);
}) })
// get, put by id // get, put by id
router.get('/:userid', async (req, res, next) => { router.get('/:userid', async (req, res, next) => {
const { userid } = req.params; const { userid } = req.params;
try { try {
const result: IUser = await userCtl.getOne(userid); const result: CtlResponse<IUser | string> = await userCtl.getOne(userid);
const { email, id, firstname, lastname, handle } = result; if (result.ok) {
res.status(200).send({ const { email, id, firstname, lastname, handle } = result.data as IUser;
id: id, res.status(result.code).send({
email: email, id: id,
firstname: firstname, email: email,
lastname: lastname, firstname: firstname,
handle: handle lastname: lastname,
}); handle: handle
});
} else {
res.status(result.code).send(result.data as string);
}
} catch(e) { } catch(e) {
next(e); next(e);
} }

View File

@@ -0,0 +1,17 @@
import { CtlResponse } from "./types";
export default class ControllerResponse<T> implements CtlResponse<T> {
ok: boolean
code: number
data: T | T[] | string
constructor(ok: boolean, code: number, data: T | T[] | string) {
this.ok = ok
this.code = code
this.data = data
}
send() {
return { ok: this.ok, code: this.code, data: this.data }
}
}

5
server/util/types.ts Normal file
View File

@@ -0,0 +1,5 @@
export interface CtlResponse<T> {
ok: boolean
code: number
data: T | T[] | string
}