自定义运行环境
自定义运行环境可参考已有环境
主要操作如下
- 为类
Startup
的propotype
增加一个函数,用于处理相关环境参数 - 每次请求都创建一个
Context
对象,执行await this.invoke(ctx)
并将Context
对象传入this.invoke
函数 - 中间件返回后,解析
Context
对象和Request
对象,并设置请求返回
伪代码
伪代码如下
import { Context, Startup } from "@halsp/core";
declare module "@halsp/core" {
interface Startup {
useCustom(): this;
listen(): void;
}
}
Startup.prototype.useCustom = function () {
// do something
this.listen = function () {
// request event
xxxEvent.on("message", async () => {
const ctx = new Context();
const res = await this["invoke"](ctx);
return setResult(ctx, event);
});
};
return this;
};
new Startup()
.useCustom()
.use((ctx) => {
ctx.res.ok("OK");
})
// ...
.listen();
分析 lambda
以 @halsp/lambda
为例,分析其的大致实现
useLambda 函数
在 Startup.prototype 上增加函数 startup.useLambda
,调用此函数以支持 Lambda 环境
在函数中声明使用 Http 环境 startup.useHttp()
,并为 startup 实例创建方法 startup.run
run 函数
每次网络请求,都会调用 startup.run()
函数
该函数简单来说就三步操作
- 根据 lambda 的参数
event
和context
解析请求内容,并创建 Context 对象 - 执行
this.invoke(ctx)
,这一步将执行各个中间件,是 halsp 的核心部分 - 格式化返回内容
函数代码如下
import { Startup, Dict } from "@halsp/core";
Startup.prototype.useLambda = function () {
return this.useHttp().extend("run", async (event: Dict, context: Dict) => {
const ctx = this.createContext(event, context);
await this["invoke"](ctx);
return await getStruct(ctx);
});
};
创建 Context
Context
构造函数接收 Request
对象,因此需要先创建 Request
对象
- 新建一个
Request
对象new Request()
- 解析 lambda 的参数
event
和context
,设置Request
对象的请求参数 - 新建一个
Context
对象new Context(req)
格式化返回内容
在 this.invoke
执行完毕后,Context
和 Request
对象已经在各个中间件被更新
然后需要解析 Context
和 Request
对象并返回符合 lambda 要求的结果
export interface ResponseStruct {
readonly isBase64Encoded: boolean;
readonly statusCode: number;
readonly status: number;
readonly headers: HeadersDict;
readonly body: any;
}
body
取自res.body
- 由于云函数不支持返回二进制,因此需要判断
res.body
是否二进制(Buffer / Stream)。如果res.body
是二进制,需要将body
用base64
转换,并设置isBase64Encoded
为true
statusCode
和status
相同,直接取自res.status
,写两个是为了兼容更多云函数headers
直接取自res.headers
使用
在 index.ts 中
import "@halsp/lambda";
const startup = new Startup().useLambda();
export const main = async (event, context) => await startup.run(event, context);
贡献
欢迎将自定义运行环境发布至 npm
供其他人使用