Skip to content

Commit

Permalink
refactor(anni): generic api handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
jannis-baum committed Jul 3, 2022
1 parent 6a5e82a commit e8a93a3
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 94 deletions.
72 changes: 72 additions & 0 deletions annotation-interface/common/api-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import mongoose from 'mongoose';
import { NextApiRequest, NextApiResponse } from 'next';

import dbConnect from '../database/helpers/connect';

type ApiMethodHandlers = {
[key: string]: () => Promise<void>;
};

export const handleApiMethods = async (
req: NextApiRequest,
res: NextApiResponse,
methodHandlers: ApiMethodHandlers,
): Promise<void> => {
const { method } = req;
try {
if (!method) throw new Error('Method not defined');
const handler = methodHandlers[method];
if (!handler) throw new Error('Method not supported');
await handler();
} catch (error) {
/* eslint-disable no-console */
console.error(error);
res.status(400).json({ success: false });
}
};

export const createApi = async (
/* eslint-disable @typescript-eslint/no-explicit-any */
model: mongoose.Model<any>,
req: NextApiRequest,
res: NextApiResponse,
additionalMethodHandlers: ApiMethodHandlers | undefined = undefined,
): Promise<void> => {
await handleApiMethods(req, res, {
POST: async () => {
await dbConnect();
const doc = await model.create(req.body);
res.status(201).json({ doc });
},
...additionalMethodHandlers,
});
};

export const updateDeleteApi = async (
model: mongoose.Model<any>,
req: NextApiRequest,
res: NextApiResponse,
additionalMethodHandlers: ApiMethodHandlers | undefined = undefined,
): Promise<void> => {
const {
query: { id },
} = req;
await handleApiMethods(req, res, {
PUT: async () => {
await dbConnect();
const doc = await model
.findByIdAndUpdate(id, req.body, {
new: true,
runValidators: true,
})
.orFail();
res.status(200).json({ brick: doc });
},
DELETE: async () => {
await dbConnect();
await model.deleteOne({ _id: id }).orFail();
res.status(200).json({ success: true });
},
...additionalMethodHandlers,
});
};
35 changes: 4 additions & 31 deletions annotation-interface/pages/api/bricks/[id].ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,9 @@
import { NextApiHandler } from 'next';

import dbConnect from '../../../database/helpers/connect';
import { updateDeleteApi } from '../../../common/api-helpers';
import TextBrick from '../../../database/models/TextBrick';

const brickApi: NextApiHandler = async (req, res) => {
const {
query: { id },
method,
} = req;
await dbConnect();
const api: NextApiHandler = async (req, res) =>
await updateDeleteApi(TextBrick!, req, res);

try {
switch (method) {
case 'PUT':
const brick = await TextBrick!
.findByIdAndUpdate(id, req.body, {
new: true,
runValidators: true,
})
.orFail();
res.status(200).json({ brick });
return;
case 'DELETE':
await TextBrick!.deleteOne({ _id: id }).orFail();
res.status(200).json({ success: true });
return;
default:
throw new Error();
}
} catch {
res.status(400).json({ success: false });
}
};

export default brickApi;
export default api;
23 changes: 4 additions & 19 deletions annotation-interface/pages/api/bricks/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
import { NextApiHandler } from 'next';

import dbConnect from '../../../database/helpers/connect';
import { createApi } from '../../../common/api-helpers';
import TextBrick from '../../../database/models/TextBrick';

const brickApi: NextApiHandler = async (req, res) => {
const { method } = req;
await dbConnect();
const api: NextApiHandler = async (req, res) =>
await createApi(TextBrick!, req, res);

try {
switch (method) {
case 'POST':
const brick = await TextBrick!.create(req.body);
res.status(201).json({ brick });
return;
default:
throw new Error();
}
} catch (error) {
res.status(400).json({ success: false });
}
};

export default brickApi;
export default api;
79 changes: 35 additions & 44 deletions annotation-interface/pages/api/server-update.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,46 @@
import axios from 'axios';
import { NextApiHandler } from 'next';

import { handleApiMethods } from '../../common/api-helpers';

export type FetchDate = Date | null;
export type FetchTarget = 'all' | 'guidelines';
export interface LastUpdatesDto {
medications: FetchDate;
guidelines: FetchDate;
}

const serverUpdateApi: NextApiHandler = async (req, res) => {
const { method } = req;
try {
switch (method) {
case 'GET':
const [medicationsRes, guidelinesRes] = await Promise.all([
axios.get<FetchDate>(
`http://${process.env.AS_API}/medications/last_update`,
),
axios.get<FetchDate>(
`http://${process.env.AS_API}/guidelines/last_update`,
),
]);
const lastUpdates: LastUpdatesDto = {
medications: medicationsRes.data,
guidelines: guidelinesRes.data,
};
res.status(200).json(lastUpdates);
return;

case 'POST':
const target = req.body.target as FetchTarget;
switch (target) {
case 'all':
await axios.post(`http://${process.env.AS_API}/init`);
break;
case 'guidelines':
await axios.post(
`http://${process.env.AS_API}/guidelines`,
);
break;
default:
throw new Error();
}
res.status(201).json({ success: true });
return;
default:
throw new Error();
}
} catch {
res.status(400).json({ success: false });
}
};
const api: NextApiHandler = async (req, res) =>
await handleApiMethods(req, res, {
GET: async () => {
const [medicationsRes, guidelinesRes] = await Promise.all([
axios.get<FetchDate>(
`http://${process.env.AS_API}/medications/last_update`,
),
axios.get<FetchDate>(
`http://${process.env.AS_API}/guidelines/last_update`,
),
]);
const lastUpdates: LastUpdatesDto = {
medications: medicationsRes.data,
guidelines: guidelinesRes.data,
};
res.status(200).json(lastUpdates);
},
POST: async () => {
const target = req.body.target as FetchTarget;
switch (target) {
case 'all':
await axios.post(`http://${process.env.AS_API}/init`);
break;
case 'guidelines':
await axios.post(`http://${process.env.AS_API}/guidelines`);
break;
default:
throw new Error();
}
res.status(201).json({ success: true });
},
});

export default serverUpdateApi;
export default api;

0 comments on commit e8a93a3

Please sign in to comment.