Generic api for any entity
This commit is contained in:
22
web/lib/models/bookmarks.js
Normal file
22
web/lib/models/bookmarks.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import Ajv from "ajv";
|
||||||
|
import addFormats from "ajv-formats";
|
||||||
|
|
||||||
|
const ajv = new Ajv();
|
||||||
|
addFormats(ajv);
|
||||||
|
|
||||||
|
const validateId = ajv.compile({
|
||||||
|
type: "string",
|
||||||
|
minLength: 1,
|
||||||
|
maxLength: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const validatePostBody = ajv.compile({
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
title: { type: "string" },
|
||||||
|
url: { type: "string", format: "uri" },
|
||||||
|
},
|
||||||
|
required: ["title", "url"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export { validateId, validatePostBody };
|
||||||
3
web/lib/models/index.js
Normal file
3
web/lib/models/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
bookmarks: require("./bookmarks"),
|
||||||
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import db from "../../../../lib/db";
|
import db from "../../../../lib/db";
|
||||||
import { withErrorHandling, withSession } from "../../../../lib/apiHelpers";
|
import { withErrorHandling, withSession } from "../../../../lib/apiHelpers";
|
||||||
|
import models from "../../../../lib/models";
|
||||||
|
|
||||||
const handler = withErrorHandling(
|
const handler = withErrorHandling(
|
||||||
withSession(async (req, res, session) => {
|
withSession(async (req, res, session) => {
|
||||||
@@ -8,19 +9,27 @@ const handler = withErrorHandling(
|
|||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case "GET":
|
case "GET":
|
||||||
await getBookmark(req, res, user);
|
await getEntity(req, res, user);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res.setHeader("Allow", ["GET", "POST"]);
|
res.setHeader("Allow", ["GET"]);
|
||||||
res.status(405).end(`Method ${method} Not Allowed`);
|
res.status(405).end(`Method ${method} Not Allowed`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const getBookmark = async (req, res, user) => {
|
const getEntity = async (req, res, user) => {
|
||||||
const { bookmarkId } = req.query;
|
const { entityName, entityId } = req.query;
|
||||||
|
|
||||||
if (!bookmarkId) {
|
if (!models[entityName]) {
|
||||||
|
res.status(404).end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var model = models[entityName];
|
||||||
|
|
||||||
|
if (!model.validateId(entityId)) {
|
||||||
|
console.warn(model.validateId.errors);
|
||||||
res.status(404).end();
|
res.status(404).end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -30,14 +39,14 @@ const getBookmark = async (req, res, user) => {
|
|||||||
KeyConditionExpression: "hk = :hk AND sk = :sk",
|
KeyConditionExpression: "hk = :hk AND sk = :sk",
|
||||||
ExpressionAttributeValues: {
|
ExpressionAttributeValues: {
|
||||||
":hk": `user#${user.sub}`,
|
":hk": `user#${user.sub}`,
|
||||||
":sk": `bookmark#${bookmarkId}`,
|
":sk": `${entityName}#${entityId}`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let bookmarks = await db.query(params).promise();
|
let entities = await db.query(params).promise();
|
||||||
|
|
||||||
if (bookmarks.Items.length == 1) {
|
if (entities.Items.length == 1) {
|
||||||
res.status(200).json(bookmarks.Items[0]);
|
res.status(200).json(entities.Items[0]);
|
||||||
} else {
|
} else {
|
||||||
res.status(404).end();
|
res.status(404).end();
|
||||||
}
|
}
|
||||||
75
web/pages/api/v1/[entityName]/index.js
Normal file
75
web/pages/api/v1/[entityName]/index.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import db from "../../../../lib/db";
|
||||||
|
import { withErrorHandling, withSession } from "../../../../lib/apiHelpers";
|
||||||
|
import models from "../../../../lib/models";
|
||||||
|
|
||||||
|
const handler = withErrorHandling(
|
||||||
|
withSession(async (req, res, session) => {
|
||||||
|
const { method } = req;
|
||||||
|
const { user } = session;
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case "GET":
|
||||||
|
await getEntities(req, res, user);
|
||||||
|
break;
|
||||||
|
case "POST":
|
||||||
|
await createEntity(req, res, user);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res.setHeader("Allow", ["GET", "POST"]);
|
||||||
|
res.status(405).end(`Method ${method} Not Allowed`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const getEntities = async (req, res, user) => {
|
||||||
|
const { entityName } = req.query;
|
||||||
|
|
||||||
|
if (!models[entityName]) {
|
||||||
|
res.status(404).end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
TableName: process.env.FMN_DYNAMODB_TABLENAME,
|
||||||
|
KeyConditionExpression: "hk = :hk AND begins_with(sk, :sk)",
|
||||||
|
ExpressionAttributeValues: {
|
||||||
|
":hk": `user#${user.sub}`,
|
||||||
|
":sk": `${entityName}#`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let entities = await db.query(params).promise();
|
||||||
|
res.status(200).json(entities.Items);
|
||||||
|
};
|
||||||
|
|
||||||
|
const createEntity = async (req, res, user) => {
|
||||||
|
const { entityName } = req.query;
|
||||||
|
|
||||||
|
if (!models[entityName]) {
|
||||||
|
res.status(404).end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var model = models[entityName];
|
||||||
|
|
||||||
|
if (!model.validatePostBody(req.body)) {
|
||||||
|
console.warn(validatePostBody.errors);
|
||||||
|
res.status(400).json(validatePostBody.errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
TableName: process.env.FMN_DYNAMODB_TABLENAME,
|
||||||
|
Item: {
|
||||||
|
hk: `user#${user.sub}`,
|
||||||
|
sk: `${entityName}#${"abc"}`,
|
||||||
|
title: req.body.title,
|
||||||
|
url: req.body.url,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await db.put(params).promise();
|
||||||
|
res.status(200).json(params.Item);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default handler;
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
import Ajv from "ajv";
|
|
||||||
import addFormats from "ajv-formats";
|
|
||||||
|
|
||||||
import db from "../../../lib/db";
|
|
||||||
import { withErrorHandling, withSession } from "../../../lib/apiHelpers";
|
|
||||||
|
|
||||||
const handler = withErrorHandling(
|
|
||||||
withSession(async (req, res, session) => {
|
|
||||||
const { method } = req;
|
|
||||||
const { user } = session;
|
|
||||||
|
|
||||||
switch (method) {
|
|
||||||
case "GET":
|
|
||||||
await getBookmarks(req, res, user);
|
|
||||||
break;
|
|
||||||
case "POST":
|
|
||||||
await createBookmark(req, res, user);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res.setHeader("Allow", ["GET", "POST"]);
|
|
||||||
res.status(405).end(`Method ${method} Not Allowed`);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const ajv = new Ajv();
|
|
||||||
addFormats(ajv);
|
|
||||||
|
|
||||||
const getBookmarks = async (req, res, user) => {
|
|
||||||
const params = {
|
|
||||||
TableName: process.env.FMN_DYNAMODB_TABLENAME,
|
|
||||||
KeyConditionExpression: "hk = :hk AND begins_with(sk, :sk)",
|
|
||||||
ExpressionAttributeValues: {
|
|
||||||
":hk": `user#${user.sub}`,
|
|
||||||
":sk": "bookmark#",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let bookmarks = await db.query(params).promise();
|
|
||||||
res.status(200).json(bookmarks.Items);
|
|
||||||
};
|
|
||||||
|
|
||||||
const createBookmarkSchema = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
title: { type: "string" },
|
|
||||||
url: { type: "string", format: "uri" },
|
|
||||||
},
|
|
||||||
required: ["title", "url"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const validateCreateBookmarkSchema = ajv.compile(createBookmarkSchema);
|
|
||||||
|
|
||||||
const createBookmark = async (req, res, user) => {
|
|
||||||
if (!validateCreateBookmarkSchema(req.body)) {
|
|
||||||
console.warn(validateCreateBookmarkSchema.errors);
|
|
||||||
res.status(400).json(validateCreateBookmarkSchema.errors);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
TableName: process.env.FMN_DYNAMODB_TABLENAME,
|
|
||||||
Item: {
|
|
||||||
hk: `user#${user.sub}`,
|
|
||||||
sk: `bookmark#${"abc"}`,
|
|
||||||
title: req.body.title,
|
|
||||||
url: req.body.url,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
await db.put(params).promise();
|
|
||||||
res.status(200).json(params.Item);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default handler;
|
|
||||||
Reference in New Issue
Block a user