[Serverless] Refactoring: Using Ports and Adapters pattern to refactor code

The original code:

createGroup.ts:

  

getGroups.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import * as AWS from "aws-sdk";
import {
  APIGatewayProxyEvent,
  APIGatewayProxyHandler,
  APIGatewayProxyResult,
} from "aws-lambda";
 
const docClient = new AWS.DynamoDB.DocumentClient();
const groupTables = process.env.GROUPS_TABLE;
 
export const handler: APIGatewayProxyHandler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  console.log("Processing event: ", event);
  const result = await docClient
    .scan({
      TableName: groupTables,
    })
    .promise();
 
  const items = result.Items;
 
  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
    body: JSON.stringify({
      items,
    }),
  };
};

 

Tow entry functions both contains busniess logic code and data access code (dynamoDB). 

 

What we want is:

Entry function --> Busniess logic code --> Data access layer

First, create interfaces for both Reqest & Model:

requests/CreateGroupRequest.ts:

export interface CreateGroupRequest {
  name: string;
  description: string;
}

models/Group.ts:

export interface Group {
  id: string;
  name: string;
  description: string;
  userId: string;
}

 

Then create data access layer code, it mainly handle all the dynamoDB operations.

dataAccess/groupAccess.ts:

复制代码
import * as AWS from "aws-sdk";
import { DocumentClient } from "aws-sdk/clients/dynamodb";

import {Group} from '../models/Group'

export class GroupAccess {
    constructor(
        private readonly docClient: DocumentClient = new AWS.DynamoDB.DocumentClient(),
        private readonly groupsTable = process.env.GROUPS_TABLE
    ) {

    }

    async getAllGroups(): Promise<Group[]> {
        console.log('Getting all groups');

        const result = await this.docClient.scan({
            TableName: this.groupsTable,
        }).promise()

        const items = result.Items;

        return items as Group[];
    }

    async createGroup(group: Group): Promise<Group> {
        console.log('Creating a group with id', group.id)

        await this.docClient.put({
            TableName: this.groupsTable,
            Item: group
        }).promise();

        return group;
    }
}
复制代码

 

Then create busniessLogic layer, it mainly talk to data access layer and passing and returning the data.

busniessLogic/groups.ts:

复制代码
import * as uuid from "uuid";

import { Group } from "../models/Group";
import { GroupAccess } from "../dataAccess/groupAccess";
import { CreateGroupRequest } from "../requests/CreateGroupRequest";
import { getUserId } from "../auth/utils";

const groupAccess = new GroupAccess();

export async function getAllGroups(): Promise<Group[]> {
  return groupAccess.getAllGroups();
}

export async function createGroup(
  createGroupRequest: CreateGroupRequest,
  jwtToken: string
) {
  const itemId = uuid.v4();
  const userId = getUserId(jwtToken);

  return await groupAccess.createGroup({
    id: itemId,
    userId: userId,
    name: createGroupRequest.name,
    description: createGroupRequest.description,
  });
}
复制代码

 

Lastly, entry function will just talk to busniess layer code:

createGroup.ts:

复制代码
import "source-map-support/register";
import {
  APIGatewayProxyEvent,
  APIGatewayProxyHandler,
  APIGatewayProxyResult,
} from "aws-lambda";
import { createGroup } from "../../busniessLogic/groups";
import { CreateGroupRequest } from "../../requests/CreateGroupRequest";

export const handler: APIGatewayProxyHandler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  console.log("Processing event: ", event);

  const newGroup: CreateGroupRequest = JSON.parse(event.body);
  const authorization = event.headers.Authorization;
  const splits = authorization.split(" ");
  const jwtToken = splits[1];

  const newItem = await createGroup(newGroup, jwtToken);

  return {
    statusCode: 201,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
    body: JSON.stringify({
      newItem,
    }),
  };
};
复制代码

 

getGroups.ts:

复制代码
import {
  APIGatewayProxyEvent,
  APIGatewayProxyHandler,
  APIGatewayProxyResult,
} from "aws-lambda";
import { getAllGroups } from "src/busniessLogic/groups";

export const handler: APIGatewayProxyHandler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  console.log("Processing event: ", event);
  const items = await getAllGroups();

  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
    body: JSON.stringify({
      items,
    }),
  };
};
复制代码

 

posted @   Zhentiw  阅读(83)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2016-05-27 [RxJS] Transformation operators: delay and delayWhen
2016-05-27 [RxJS] Transformation operator: buffer, bufferCount, bufferTime
2016-05-27 [RxJS] Transformation operator: scan
2016-05-27 [PWA] Keynote: Progressive Web Apps across all frameworks
2016-05-27 [PWA] Add web app to your Home Screen
点击右上角即可分享
微信分享提示