【问题标题】:Serverless Typescript Rest API with Typeorm and Express.js带有 Typeorm 和 Express.js 的无服务器 Typescript Rest API
【发布时间】:2021-04-04 17:28:53
【问题描述】:

我是 Node.js 的新手。 目前我有一个在 Heroku 中工作的基于微服务架构的系统,我的目标是使用 Serverless 和 Typescript 将我们的基础设施更改为 AWS Lambda,同时从 Sequelize 切换到 TypeORM 并继续使用 express.js 作为 Restful API 框架。

我试图让所有这些东西一起工作,最终当对我的服务运行基本的 GET 请求时(使用 sls 离线运行),我收到Cannot Get /documents

我确定问题出在app.ts。 路线是空的,但我不知道如何解决。

我尝试了许多其他选项,但这个选项似乎与数据库配合得很好,它甚至自动迁移了我的实体并在我的数据库中正确创建了表。

任何提示或指导将不胜感激。

我的代码:

//serverless.ts

import type { Serverless } from 'serverless/aws';

const serverlessConfiguration: Serverless = {
  service: {
    name: 'iod-typeorm-test',
    // app and org for use with dashboard.serverless.com
    // app: your-app-name,
    // org: your-org-name,
  },
  frameworkVersion: '2',
  custom: {
    webpack: {
      webpackConfig: './webpack.config.js',
      includeModules: true
    }
  },
  // Add the serverless-webpack plugin
  plugins: ['serverless-webpack','serverless-offline'],
  provider: {
    name: 'aws',
    profile: '01iod',
    region: 'eu-central-1',
    runtime: 'nodejs12.x',
    apiGateway: {
      minimumCompressionSize: 1024,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
    },
  },
  functions: {
    hello: {
      handler: 'handler.hello',
      events: [
        {
          http: {
            method: 'get',
            path: '/documents',
          }
        },
        {
          http: {
            method: 'post',
            path: '/documents',
          }
        }
      ]
    }
  }
}

module.exports = serverlessConfiguration;
//ormconfig.json
{
   "type": "postgres",
   "host": "localhost",
   "port": 5432,
   "username": "root",
   "password": "password",
   "database": "myService",
   "synchronize": true,
   "logging": true,
   "uuidExtension": true,
   "keepConnectionAlive": true,
   "entities": [
      "src/entity/**/*.ts"
   ],
   "migrations": [
      "src/migration/**/*.ts"
   ],
   "subscribers": [
      "src/subscriber/**/*.ts"
   ],
   "cli": {
      "entitiesDir": "src/entity",
      "migrationsDir": "src/migration",
      "subscribersDir": "src/subscriber"
   }
}
//handler.ts
import "reflect-metadata";
import { createServer, proxy } from 'aws-serverless-express';
import { Context } from 'aws-lambda';
import { configureApp } from './app';

const binaryMimeTypes: string[] = [
  'application/json'
];
const app = configureApp();
const server = createServer(app, undefined, binaryMimeTypes);

export const hello = (event: any, context: Context) =>
  proxy(server, event, context);
//app.ts
import * as express from 'express';
import { json, urlencoded } from 'body-parser';
import * as cors from 'cors';
import { eventContext } from 'aws-serverless-express/middleware';
import {createConnection} from "typeorm";
import {Routes} from "./src/routes/routes"
import {Request, Response} from "express";
import * as bodyParser from "body-parser";

export function configureApp() {
  const app = express();

  createConnection().then(async connection => {

    app.use(cors());
    app.use(json());
    app.use(urlencoded({ extended: true }));
    app.use(eventContext());

    // create express app
    app.use(bodyParser.json());
  
    // register express routes from defined application routes
    Routes.forEach(route => {
        (app as any)[route.method](route.route, (req: Request, res: Response, next: Function) => {
            const result = (new (route.controller as any))[route.action](req, res, next);
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);
  
            } else if (result !== null && result !== undefined) {
                res.json(result);
            }
        });
    });

    if (!connection.isConnected) {
      connection = await connection.connect();
    }

  }).catch(error => console.log(error));
  

  return app;
}
//./src/routes/routes
import {DocumentController} from "../controller/DosumentsController";

export const Routes = [{
    method: "get",
    route: "/documents",
    controller: DocumentController,
    action: "all"
}, {
    method: "get",
    route: "/documents/:id",
    controller: DocumentController,
    action: "one"
}, {
    method: "post",
    route: "/documents",
    controller: DocumentController,
    action: "save"
}];

【问题讨论】:

    标签: typescript express aws-lambda serverless-framework typeorm


    【解决方案1】:

    我实际上遇到了同样的问题,我花了很长时间才解决。问题是您需要在每次 lambda 调用开始时初始化数据库。在您的情况下,您的 configureApp 方法返回一个承诺,在启动服务器之前不会等待。

    我不完全确定使用无服务器 AWS 的解决方案,但您应该能够执行以下操作:

    export const hello = async (event: any, context: Context) => {
      const app = await configureApp()
      const server = createServer(app, undefined, binaryMimeTypes);
      proxy(server, event, context);
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 2019-12-08
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多