feat: Update serverless configuration and refactor API handlers to improve error handling and response structure

This commit is contained in:
2024-11-23 08:42:31 +02:00
parent f57d963453
commit 59c0c97252
12 changed files with 62 additions and 29 deletions

View File

@@ -10,8 +10,9 @@ provider:
runtime: nodejs20.x runtime: nodejs20.x
environment: environment:
SLS_REGION: ${self:provider.region} SLS_REGION: ${self:provider.region}
TASKER_TASK_TABLE_NAME: ${ssm:/tasker/dynamodb/project-table-name} API_BASE_URL: ${ssm:/tasker/api/base-url}
TASKER_PROJECT_TABLE_NAME: ${ssm:/tasker/dynamodb/task-table-name} TASKER_TASK_TABLE_NAME: ${ssm:/tasker/dynamodb/task-table-name}
TASKER_PROJECT_TABLE_NAME: ${ssm:/tasker/dynamodb/project-table-name}
TASKER_USER_TABLE_NAME: ${ssm:/tasker/dynamodb/user-table-name} TASKER_USER_TABLE_NAME: ${ssm:/tasker/dynamodb/user-table-name}
TASKER_TASK_EXTRA_TABLE_NAME: ${ssm:/tasker/dynamodb/task-extra-table-name} TASKER_TASK_EXTRA_TABLE_NAME: ${ssm:/tasker/dynamodb/task-extra-table-name}
TASKER_TEAM_TABLE_NAME: ${ssm:/tasker/dynamodb/team-table-name} TASKER_TEAM_TABLE_NAME: ${ssm:/tasker/dynamodb/team-table-name}
@@ -32,6 +33,11 @@ provider:
"arn:aws:dynamodb:${self:provider.region}:*:table/tasker-*", "arn:aws:dynamodb:${self:provider.region}:*:table/tasker-*",
"arn:aws:dynamodb:${self:provider.region}:*:table/tasker-*/*", "arn:aws:dynamodb:${self:provider.region}:*:table/tasker-*/*",
] ]
- Effect: Allow
Action:
- execute-api:Invoke
Resource:
- "arn:aws:execute-api:${self:provider.region}:*:*/*/POST/users"
functions: functions:
postSignUp: postSignUp:
@@ -52,6 +58,7 @@ functions:
path: users path: users
method: post method: post
cors: true cors: true
authorizer: aws_iam
# POST /projects # POST /projects
createProject: createProject:
handler: src/handlers/createProject.handler handler: src/handlers/createProject.handler

View File

@@ -9,7 +9,8 @@ const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client); const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { name, description, startDate, endDate } = event.body; const { name, description, startDate, endDate } = JSON.parse(event.body);
try { try {
const newProject = { const newProject = {
category: "projects", category: "projects",
@@ -28,12 +29,14 @@ export const handler = async (event: any): Promise<any> => {
await docClient.put(params); await docClient.put(params);
return { return {
status: 201, statusCode: 201,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newProject), body: JSON.stringify(newProject),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error creating project: ${error.message}`, message: `Error creating project: ${error.message}`,
}), }),

View File

@@ -21,7 +21,7 @@ export const handler = async (event: any): Promise<any> => {
projectId, projectId,
authorUserId, authorUserId,
assignedUserId, assignedUserId,
} = event.body; } = JSON.parse(event.body);
try { try {
const newTask = { const newTask = {
category: "tasks", category: "tasks",
@@ -47,12 +47,14 @@ export const handler = async (event: any): Promise<any> => {
await docClient.put(params); await docClient.put(params);
return { return {
status: 201, statusCode: 201,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newTask), body: JSON.stringify(newTask),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error creating task: ${error.message}`, message: `Error creating task: ${error.message}`,
}), }),

View File

@@ -10,7 +10,7 @@ const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client); const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { username, cognitoId } = event.body; const { username, cognitoId } = JSON.parse(event.body);
const teamId = fetchRandomTeamId(); const teamId = fetchRandomTeamId();
try { try {
@@ -31,12 +31,14 @@ export const handler = async (event: any): Promise<any> => {
await docClient.put(params); await docClient.put(params);
return { return {
status: 201, statusCode: 201,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newUser), body: JSON.stringify(newUser),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error creating user: ${error.message}`, message: `Error creating user: ${error.message}`,
}), }),

View File

@@ -20,12 +20,14 @@ export const handler = async (event: any): Promise<any> => {
const projects = await docClient.query(params); const projects = await docClient.query(params);
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(projects.Items), body: JSON.stringify(projects.Items),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error retrieving projects: ${error.message}`, message: `Error retrieving projects: ${error.message}`,
}), }),

View File

@@ -53,12 +53,14 @@ export const handler = async (event: any): Promise<any> => {
); );
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(tasksWithDetails), body: JSON.stringify(tasksWithDetails),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error retrieving tasks: ${error.message}`, message: `Error retrieving tasks: ${error.message}`,
}), }),

View File

@@ -40,12 +40,14 @@ export const handler = async (event: any): Promise<any> => {
); );
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(teamsWithUsernames), body: JSON.stringify(teamsWithUsernames),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error retrieving teams: ${error.message}`, message: `Error retrieving teams: ${error.message}`,
}), }),

View File

@@ -22,12 +22,14 @@ export const handler = async (event: any): Promise<any> => {
const user = await docClient.query(params); const user = await docClient.query(params);
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(user.Items?.[0] || {}), body: JSON.stringify(user.Items?.[0] || {}),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error retrieving user: ${error.message}`, message: `Error retrieving user: ${error.message}`,
}), }),

View File

@@ -18,12 +18,14 @@ export const handler = async (event: any): Promise<any> => {
const userTasks = [...authorTasks, ...assigneeTasks]; const userTasks = [...authorTasks, ...assigneeTasks];
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(userTasks), body: JSON.stringify(userTasks),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error retrieving tasks for user: ${error.message}`, message: `Error retrieving tasks for user: ${error.message}`,
}), }),

View File

@@ -20,12 +20,14 @@ export const handler = async (event: any): Promise<any> => {
const users = await docClient.query(params); const users = await docClient.query(params);
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(users.Items), body: JSON.stringify(users.Items),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error retrieving users: ${error.message}`, message: `Error retrieving users: ${error.message}`,
}), }),

View File

@@ -1,4 +1,7 @@
import https from "https"; import https from "https";
import path from "path";
const API_BASE_URL = process.env.API_BASE_URL || "";
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const postData = JSON.stringify({ const postData = JSON.stringify({
@@ -8,9 +11,11 @@ export const handler = async (event: any): Promise<any> => {
}); });
const options = { const options = {
hostname: process.env.API_URL, hostname: API_BASE_URL ? new URL(API_BASE_URL).hostname : "",
port: 443, port: 443,
path: "/users", path: API_BASE_URL
? path.join(new URL(API_BASE_URL).pathname, "/users")
: "",
method: "POST", method: "POST",
headers: { headers: {
"Content-category": "application/json", "Content-category": "application/json",
@@ -18,7 +23,7 @@ export const handler = async (event: any): Promise<any> => {
}, },
}; };
const responseBody = new Promise((resolve, reject) => { const responseBody = await new Promise((resolve, reject) => {
const req = https.request(options, (res) => { const req = https.request(options, (res) => {
res.setEncoding("utf8"); res.setEncoding("utf8");
let responseBody = ""; let responseBody = "";

View File

@@ -9,7 +9,7 @@ const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { taskId } = event.pathParameters; const { taskId } = event.pathParameters;
const { status } = event.body; const { status } = JSON.parse(event.body);
try { try {
const params: UpdateCommandInput = { const params: UpdateCommandInput = {
TableName: TASKER_TASK_TABLE_NAME, TableName: TASKER_TASK_TABLE_NAME,
@@ -30,12 +30,14 @@ export const handler = async (event: any): Promise<any> => {
const updatedTask = await docClient.update(params); const updatedTask = await docClient.update(params);
return { return {
status: 200, statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(updatedTask.Attributes), body: JSON.stringify(updatedTask.Attributes),
}; };
} catch (error: any) { } catch (error: any) {
return { return {
status: 500, statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
message: `Error updating task: ${error.message}`, message: `Error updating task: ${error.message}`,
}), }),