ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-05-27 02:05:46  阅读:143  来源: 互联网

标签:Serverless APIGatewayProxyHandler code const .. pattern export import event


The original code:

createGroup.ts:

import { v4 as uuidv4 } from "uuid";
import "source-map-support/register";
import * as AWS from "aws-sdk";
import {
  APIGatewayProxyEvent,
  APIGatewayProxyHandler,
  APIGatewayProxyResult,
} from "aws-lambda";
import { getUserId } from "../../auth/utils";

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 itemId = uuidv4();

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

  const newItem = {
    id: itemId,
    userId: getUserId(jwtToken),
    ...parsedBody,
  };

  await docClient
    .put({
      TableName: groupTables,
      Item: newItem,
    })
    .promise();

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

  

getGroups.ts:

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,
    }),
  };
};

 

标签:Serverless,APIGatewayProxyHandler,code,const,..,pattern,export,import,event
来源: https://www.cnblogs.com/Answer1215/p/14815707.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有