@fastcar/cli 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +259 -21
- package/bin/cli.js +202 -32
- package/package.json +3 -3
- package/skills/fastcar-database/SKILL.md +374 -0
- package/skills/fastcar-framework/SKILL.md +661 -0
- package/skills/fastcar-framework/assets/project-template/package.json +24 -0
- package/skills/fastcar-framework/assets/project-template/resource/application.yml +14 -0
- package/skills/fastcar-framework/assets/project-template/src/app.ts +18 -0
- package/skills/fastcar-framework/assets/project-template/src/component/StartupRunner.ts +15 -0
- package/skills/fastcar-framework/assets/project-template/src/controller/HelloController.ts +21 -0
- package/skills/fastcar-framework/assets/project-template/src/service/HelloService.ts +12 -0
- package/skills/fastcar-framework/assets/project-template/tsconfig.json +21 -0
- package/skills/fastcar-framework/references/api-reference.md +353 -0
- package/skills/fastcar-rpc-microservices/SKILL.md +311 -0
- package/skills/fastcar-serverless/SKILL.md +211 -0
- package/skills/fastcar-toolkit/SKILL.md +282 -0
- package/src/init.js +615 -201
- package/src/pack.js +204 -0
- package/src/reverse.js +204 -0
- package/src/skill-targets.js +74 -0
- package/src/skill.js +362 -0
- package/src/templates.json +32 -0
- package/src/utils.js +51 -66
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastcar-rpc-microservices
|
|
3
|
+
description: FastCar RPC 与微服务开发指南。Use when working with FastCar framework for: (1) Building RPC servers and clients with @fastcar/rpc, (2) Using WebSocket/SocketIO/MQTT/gRPC for service communication, (3) Setting up microservices architecture (center/connector/chat/web/base), (4) Configuring RPC endpoints, authentication, retry policies, (5) Using protobuf with RPC.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FastCar RPC & Microservices
|
|
7
|
+
|
|
8
|
+
FastCar RPC 模块提供基于多种协议(WS、SocketIO、MQTT、gRPC)的远程调用能力,并支持构建 center / connector / chat / web / base 多服务微服务架构。
|
|
9
|
+
|
|
10
|
+
## RPC 核心概念
|
|
11
|
+
|
|
12
|
+
### 开启 RPC
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { Application } from "@fastcar/core/annotation";
|
|
16
|
+
import { EnableRPC } from "@fastcar/rpc/annotation";
|
|
17
|
+
|
|
18
|
+
@Application
|
|
19
|
+
@EnableRPC
|
|
20
|
+
class APP {}
|
|
21
|
+
export default new APP();
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 服务端配置
|
|
25
|
+
|
|
26
|
+
通过 `ApplicationSetting` 注入 RPC 服务器列表配置类:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { Application, ApplicationSetting } from "@fastcar/core/annotation";
|
|
30
|
+
import { EnableRPC } from "@fastcar/rpc/annotation";
|
|
31
|
+
import RpcServerList from "./RpcServerList";
|
|
32
|
+
|
|
33
|
+
@Application
|
|
34
|
+
@EnableRPC
|
|
35
|
+
@ApplicationSetting(RpcServerList)
|
|
36
|
+
class APP {}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`RpcServerList.ts` 示例:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { SocketEnum } from "@fastcar/rpc/constant/SocketEnum";
|
|
43
|
+
import { Protocol } from "@fastcar/server";
|
|
44
|
+
import { CodeProtocolEnum } from "@fastcar/rpc/types/CodeProtocolEnum";
|
|
45
|
+
import * as path from "path";
|
|
46
|
+
|
|
47
|
+
export default {
|
|
48
|
+
rpc: {
|
|
49
|
+
list: [
|
|
50
|
+
{ id: "rpc-1", type: SocketEnum.WS, server: { port: 1238 }, serviceType: "rpc" },
|
|
51
|
+
{ id: "rpc-2", type: SocketEnum.SocketIO, server: { port: 1235 }, serviceType: "rpc" },
|
|
52
|
+
{ id: "rpc-3", type: SocketEnum.MQTT, server: { port: 1236, protocol: Protocol.net }, serviceType: "rpc" },
|
|
53
|
+
{
|
|
54
|
+
id: "rpc-4",
|
|
55
|
+
type: SocketEnum.MQTT,
|
|
56
|
+
server: { port: 1239, protocol: Protocol.https, ssl: { key: "./ssl/server.key", cert: "./ssl/server.crt" } },
|
|
57
|
+
serviceType: "rpc",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "rpc-5",
|
|
61
|
+
type: SocketEnum.Grpc,
|
|
62
|
+
server: { port: 1240, ssl: { ca: path.join(__dirname, "cert/ca.crt"), key: "cert/server.key", cert: "cert/server.crt" } },
|
|
63
|
+
serviceType: "rpc",
|
|
64
|
+
codeProtocol: CodeProtocolEnum.PROTOBUF,
|
|
65
|
+
extra: { checkClientCertificate: true },
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
支持的协议类型:
|
|
73
|
+
- `SocketEnum.WS`:WebSocket
|
|
74
|
+
- `SocketEnum.SocketIO`:Socket.IO
|
|
75
|
+
- `SocketEnum.MQTT`:MQTT
|
|
76
|
+
- `SocketEnum.Grpc`:gRPC
|
|
77
|
+
|
|
78
|
+
### 安全认证
|
|
79
|
+
|
|
80
|
+
在服务端配置 `secure`:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
{
|
|
84
|
+
id: "rpc-auth",
|
|
85
|
+
type: SocketEnum.WS,
|
|
86
|
+
server: { port: 1238 },
|
|
87
|
+
serviceType: "rpc",
|
|
88
|
+
secure: { username: "user", password: "123456" },
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### RPC 控制器
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { Controller } from "@fastcar/core/annotation";
|
|
96
|
+
import { RPC, RPCMethod, RPCMiddleware } from "@fastcar/rpc/annotation";
|
|
97
|
+
|
|
98
|
+
@Controller
|
|
99
|
+
@RPC("/hello")
|
|
100
|
+
class HelloController {
|
|
101
|
+
@RPCMethod
|
|
102
|
+
async index() {
|
|
103
|
+
return { message: "Hello RPC" };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@RPCMethod("/detail")
|
|
107
|
+
async detail(data: any) {
|
|
108
|
+
return { data };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## RPC 客户端
|
|
114
|
+
|
|
115
|
+
### 基础客户端
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { RpcClient } from "@fastcar/rpc";
|
|
119
|
+
import { SocketEnum } from "@fastcar/rpc/constant/SocketEnum";
|
|
120
|
+
import RpcAsyncService from "@fastcar/rpc/service/RpcAsyncService";
|
|
121
|
+
|
|
122
|
+
class NotifyHandle implements RpcAsyncService {
|
|
123
|
+
async handleMsg(url: string, data: Object): Promise<void | Object> {
|
|
124
|
+
console.log("收到服务端消息", url, data);
|
|
125
|
+
return { url, data: "来自客户端的应答" };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const client = new RpcClient(
|
|
130
|
+
{
|
|
131
|
+
url: "ws://localhost:1238",
|
|
132
|
+
type: SocketEnum.WS,
|
|
133
|
+
secure: { username: "user", password: "123456" },
|
|
134
|
+
},
|
|
135
|
+
new NotifyHandle()
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
await client.start();
|
|
139
|
+
const result = await client.request("/hello");
|
|
140
|
+
console.log(result);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 断线重连与重试策略
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
const client = new RpcClient(
|
|
147
|
+
{
|
|
148
|
+
url: "mqtt://localhost:1236",
|
|
149
|
+
type: SocketEnum.MQTT,
|
|
150
|
+
retryCount: 3, // 错误重试次数
|
|
151
|
+
retryInterval: 1000, // 重试间隔(毫秒)
|
|
152
|
+
timeout: 3000, // 请求超时(毫秒)
|
|
153
|
+
maxMsgNum: 10000, // 最大消息并发数
|
|
154
|
+
disconnectInterval: 1000, // 断线重连间隔
|
|
155
|
+
},
|
|
156
|
+
new NotifyHandle()
|
|
157
|
+
);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### SSL 连接
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
const client = new RpcClient(
|
|
164
|
+
{
|
|
165
|
+
url: "wss://localhost:1239",
|
|
166
|
+
type: SocketEnum.MQTT,
|
|
167
|
+
extra: { rejectUnauthorized: false },
|
|
168
|
+
},
|
|
169
|
+
new NotifyHandle()
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Protobuf 调用
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { RpcClient } from "@fastcar/rpc";
|
|
177
|
+
import { SocketEnum } from "@fastcar/rpc/constant/SocketEnum";
|
|
178
|
+
import { CodeProtocolEnum } from "@fastcar/rpc/types/CodeProtocolEnum";
|
|
179
|
+
import { ClientRequestStatic } from "@fastcar/rpc/service/rpc/RequestStatic";
|
|
180
|
+
import * as path from "path";
|
|
181
|
+
|
|
182
|
+
const client = new RpcClient(
|
|
183
|
+
{
|
|
184
|
+
url: "local.dev.com:1240",
|
|
185
|
+
type: SocketEnum.Grpc,
|
|
186
|
+
codeProtocol: CodeProtocolEnum.PROTOBUF,
|
|
187
|
+
ssl: {
|
|
188
|
+
ca: path.join(__dirname, "cert/ca.crt"),
|
|
189
|
+
key: path.join(__dirname, "cert/client.key"),
|
|
190
|
+
cert: path.join(__dirname, "cert/client.crt"),
|
|
191
|
+
},
|
|
192
|
+
extra: {
|
|
193
|
+
options: {
|
|
194
|
+
"grpc.ssl_target_name_override": "example",
|
|
195
|
+
"grpc.default_authority": "example",
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
new NotifyHandle(),
|
|
200
|
+
{ retryCount: 0 }
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
client.addProtoBuf({
|
|
204
|
+
root: {
|
|
205
|
+
protoPath: path.join(__dirname, "proto/hello.proto"),
|
|
206
|
+
service: "HelloPBController",
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await client.start();
|
|
211
|
+
|
|
212
|
+
const res = await ClientRequestStatic<{ message: string }, { code: number; data: string }>({
|
|
213
|
+
url: "/pbhello",
|
|
214
|
+
data: { message: "来自客户端的pb调用" },
|
|
215
|
+
client,
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## 微服务架构
|
|
220
|
+
|
|
221
|
+
FastCar 微服务模板将系统拆分为以下服务模块:
|
|
222
|
+
|
|
223
|
+
| 模块 | 职责 |
|
|
224
|
+
|------|------|
|
|
225
|
+
| center | 服务中心,提供服务注册与发现 |
|
|
226
|
+
| connector | 连接器服务,处理客户端连接(通常标记 `front: true`) |
|
|
227
|
+
| chat | 聊天服务,处理实时消息 |
|
|
228
|
+
| web | Web 服务,提供 HTTP 接口 |
|
|
229
|
+
| base | 基础服务,提供公共功能 |
|
|
230
|
+
|
|
231
|
+
### 微服务配置示例
|
|
232
|
+
|
|
233
|
+
```yaml
|
|
234
|
+
settings:
|
|
235
|
+
microservices:
|
|
236
|
+
center:
|
|
237
|
+
token: "nW0tT4bZ6qM7mF7wD2rT2pR9dT7gK3hZ"
|
|
238
|
+
servers:
|
|
239
|
+
- host: "localhost"
|
|
240
|
+
clusters: 1
|
|
241
|
+
list:
|
|
242
|
+
- type: "ws"
|
|
243
|
+
server: { port: 60000 }
|
|
244
|
+
timeout: 0
|
|
245
|
+
connectionLimit: 1
|
|
246
|
+
disconnectInterval: 1000
|
|
247
|
+
retry: { retryCount: 3, retryInterval: 3000, timeout: 30000, maxMsgNum: 10000, increase: true }
|
|
248
|
+
connector:
|
|
249
|
+
token: "x3TGsWC9uloZu235LA07eAiJ61nQ1A5f"
|
|
250
|
+
servers:
|
|
251
|
+
- host: "localhost"
|
|
252
|
+
clusters: 1
|
|
253
|
+
list:
|
|
254
|
+
- front: true
|
|
255
|
+
type: "ws"
|
|
256
|
+
server: { port: 60100 }
|
|
257
|
+
chat:
|
|
258
|
+
token: "go0kbkNM3wQ4e2Vgo0kbkNM3wQ4e2V"
|
|
259
|
+
servers:
|
|
260
|
+
- host: "localhost"
|
|
261
|
+
clusters: 1
|
|
262
|
+
list:
|
|
263
|
+
- type: "ws"
|
|
264
|
+
server: { port: 60200 }
|
|
265
|
+
web:
|
|
266
|
+
token: "go0kbkNM3wQ4e2Vgo0kbkNM3wQ4e2V"
|
|
267
|
+
koa:
|
|
268
|
+
koaBodyParser:
|
|
269
|
+
enableTypes: ["json", "form", "text"]
|
|
270
|
+
servers:
|
|
271
|
+
- host: "localhost"
|
|
272
|
+
clusters: 1
|
|
273
|
+
list:
|
|
274
|
+
- type: "http"
|
|
275
|
+
server: { port: 8080 }
|
|
276
|
+
- type: "ws"
|
|
277
|
+
server: { port: 60300 }
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 配置项说明
|
|
281
|
+
|
|
282
|
+
- `token`:服务间通信鉴权令牌
|
|
283
|
+
- `clusters`:集群实例数,`serviceId` 和端口号自动递增
|
|
284
|
+
- `front: true`:标记为面向客户端的前置节点
|
|
285
|
+
- `timeout`:连接超时(毫秒),`0` 表示永不超时
|
|
286
|
+
- `connectionLimit`:最大连接数限制
|
|
287
|
+
- `disconnectInterval`:断线重连间隔
|
|
288
|
+
- `retry`:重试策略(`retryCount`, `retryInterval`, `timeout`, `maxMsgNum`, `increase`)
|
|
289
|
+
|
|
290
|
+
## 完整模块列表
|
|
291
|
+
|
|
292
|
+
| 模块 | 安装命令 | 用途 |
|
|
293
|
+
|------|----------|------|
|
|
294
|
+
| @fastcar/rpc | `npm i @fastcar/rpc @fastcar/server` | RPC 通信 |
|
|
295
|
+
| @fastcar/server | `npm i @fastcar/server` | 服务器统一管理 |
|
|
296
|
+
|
|
297
|
+
## 快速开始
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# RPC 项目
|
|
301
|
+
mkdir my-rpc-app && cd my-rpc-app
|
|
302
|
+
fastcar-cli init rpc
|
|
303
|
+
npm install
|
|
304
|
+
npm run debug
|
|
305
|
+
|
|
306
|
+
# Microservices 项目
|
|
307
|
+
mkdir my-ms-app && cd my-ms-app
|
|
308
|
+
fastcar-cli init microservices
|
|
309
|
+
npm install
|
|
310
|
+
npm run start-node
|
|
311
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastcar-serverless
|
|
3
|
+
description: FastCar Serverless 开发指南。Use when working with FastCar framework for: (1) Building serverless functions for Aliyun FC, Tencent SCF, or AWS Lambda, (2) Using @ServerlessApp, @Handler, @HttpTrigger, @TimerTrigger, @EventTrigger decorators, (3) Local development and debugging of serverless applications, (4) Integrating Koa middleware in serverless environments.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FastCar Serverless
|
|
7
|
+
|
|
8
|
+
FastCar Serverless 框架支持将 FastCar 应用部署到阿里云函数计算(FC)、腾讯云云函数(SCF)和 AWS Lambda,同时提供本地开发调试能力。
|
|
9
|
+
|
|
10
|
+
## 核心装饰器
|
|
11
|
+
|
|
12
|
+
### @ServerlessApp
|
|
13
|
+
|
|
14
|
+
定义 Serverless 应用入口,可显式声明依赖组件和初始化逻辑。
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { ServerlessApp, Service, Handler, HttpTrigger, TimerTrigger, EventTrigger } from "@fastcar/serverless";
|
|
18
|
+
|
|
19
|
+
@Service
|
|
20
|
+
class OrderService {
|
|
21
|
+
async createOrder(data: any) {
|
|
22
|
+
return { orderId: Date.now(), ...data };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@ServerlessApp({
|
|
27
|
+
name: "order-service",
|
|
28
|
+
version: "1.0.0",
|
|
29
|
+
components: [OrderService],
|
|
30
|
+
init: async (app) => {
|
|
31
|
+
console.log("Order service initializing...");
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
class OrderApp {
|
|
35
|
+
@HttpTrigger({ path: "/orders", method: "POST" })
|
|
36
|
+
@Handler()
|
|
37
|
+
async createOrder(event: any, context: any) {
|
|
38
|
+
const orderService = (this as any).app.getFastCarApp().getComponentByName("OrderService") as OrderService;
|
|
39
|
+
const order = await orderService.createOrder(event.body);
|
|
40
|
+
return {
|
|
41
|
+
statusCode: 200,
|
|
42
|
+
headers: { "Content-Type": "application/json" },
|
|
43
|
+
body: { success: true, data: order },
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@HttpTrigger({ path: "/orders/:id", method: "GET" })
|
|
48
|
+
@Handler()
|
|
49
|
+
async getOrder(event: any, context: any) {
|
|
50
|
+
return {
|
|
51
|
+
statusCode: 200,
|
|
52
|
+
body: { orderId: event.params?.id },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@TimerTrigger({ cron: "0 0 * * * *" })
|
|
57
|
+
@Handler()
|
|
58
|
+
async hourlyReport(event: any, context: any) {
|
|
59
|
+
console.log(`[${context.requestId}] Generating hourly report`);
|
|
60
|
+
return { success: true };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@EventTrigger({ eventSource: "oss" })
|
|
64
|
+
@Handler()
|
|
65
|
+
async handleFileUpload(event: any, context: any) {
|
|
66
|
+
console.log(`[${context.requestId}] Processing file upload event`);
|
|
67
|
+
return { success: true };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const orderApp = new OrderApp();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 触发器类型
|
|
75
|
+
|
|
76
|
+
| 装饰器 | 用途 | 示例 |
|
|
77
|
+
|--------|------|------|
|
|
78
|
+
| `@HttpTrigger` | HTTP API 触发 | `@HttpTrigger({ path: "/api", method: "GET" })` |
|
|
79
|
+
| `@TimerTrigger` | 定时触发 | `@TimerTrigger({ cron: "0 0 * * * *" })` |
|
|
80
|
+
| `@EventTrigger` | 事件触发(OSS/COS 上传等) | `@EventTrigger({ eventSource: "oss" })` |
|
|
81
|
+
| `@Handler` | 标记处理方法 | `@Handler()` |
|
|
82
|
+
|
|
83
|
+
## 本地开发调试
|
|
84
|
+
|
|
85
|
+
使用 `ServerlessApplication` + `startLocalDev` 在本地启动开发服务器:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import {
|
|
89
|
+
ServerlessApplication,
|
|
90
|
+
ServerlessContext,
|
|
91
|
+
HttpTrigger,
|
|
92
|
+
Handler,
|
|
93
|
+
Service,
|
|
94
|
+
Controller,
|
|
95
|
+
Autowired,
|
|
96
|
+
LoggerMiddleware,
|
|
97
|
+
CorsMiddleware,
|
|
98
|
+
ErrorMiddleware,
|
|
99
|
+
} from "@fastcar/serverless";
|
|
100
|
+
import { startLocalDev } from "@fastcar/serverless/local";
|
|
101
|
+
|
|
102
|
+
@Service
|
|
103
|
+
class UserService {
|
|
104
|
+
private users = [
|
|
105
|
+
{ id: "1", name: "张三" },
|
|
106
|
+
{ id: "2", name: "李四" },
|
|
107
|
+
];
|
|
108
|
+
findAll() { return this.users; }
|
|
109
|
+
findById(id: string) { return this.users.find(u => u.id === id); }
|
|
110
|
+
create(user: any) {
|
|
111
|
+
const newUser = { id: String(Date.now()), ...user };
|
|
112
|
+
this.users.push(newUser);
|
|
113
|
+
return newUser;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@Controller
|
|
118
|
+
class UserController {
|
|
119
|
+
@Autowired
|
|
120
|
+
private userService!: UserService;
|
|
121
|
+
|
|
122
|
+
@HttpTrigger({ path: "/users", method: "GET" })
|
|
123
|
+
@Handler()
|
|
124
|
+
async listUsers(ctx: ServerlessContext) {
|
|
125
|
+
ctx.json({ code: 0, data: this.userService.findAll(), requestId: ctx.requestId });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@HttpTrigger({ path: "/users/:id", method: "GET" })
|
|
129
|
+
@Handler()
|
|
130
|
+
async getUser(ctx: ServerlessContext) {
|
|
131
|
+
const user = this.userService.findById(ctx.params.id);
|
|
132
|
+
if (!user) ctx.throw(404, "User not found");
|
|
133
|
+
ctx.json({ code: 0, data: user });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@HttpTrigger({ path: "/users", method: "POST" })
|
|
137
|
+
@Handler()
|
|
138
|
+
async createUser(ctx: ServerlessContext) {
|
|
139
|
+
const user = this.userService.create(ctx.bodyData);
|
|
140
|
+
ctx.status = 201;
|
|
141
|
+
ctx.json({ code: 0, data: user });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function main() {
|
|
146
|
+
const app = new ServerlessApplication();
|
|
147
|
+
app.register(UserController, UserService);
|
|
148
|
+
app.use(ErrorMiddleware({ includeStack: true }));
|
|
149
|
+
app.use(LoggerMiddleware({ logQuery: true }));
|
|
150
|
+
app.use(CorsMiddleware({ origin: "*" }));
|
|
151
|
+
|
|
152
|
+
await startLocalDev(app, {
|
|
153
|
+
port: 3000,
|
|
154
|
+
host: "127.0.0.1",
|
|
155
|
+
onStart: () => {
|
|
156
|
+
console.log("Serverless local dev server running at http://127.0.0.1:3000");
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
main().catch(console.error);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 云平台适配器
|
|
165
|
+
|
|
166
|
+
### 阿里云 FC
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { createFCAdapter } from "@fastcar/serverless";
|
|
170
|
+
export const handler = createFCAdapter((orderApp as any).app);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 腾讯云 SCF
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { createSCFAdapter } from "@fastcar/serverless";
|
|
177
|
+
export const main_handler = createSCFAdapter((orderApp as any).app);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### AWS Lambda
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { createLambdaAdapter } from "@fastcar/serverless";
|
|
184
|
+
export const handler = createLambdaAdapter((orderApp as any).app);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## 常用中间件
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { LoggerMiddleware, CorsMiddleware, ErrorMiddleware } from "@fastcar/serverless";
|
|
191
|
+
|
|
192
|
+
app.use(ErrorMiddleware({ includeStack: true }));
|
|
193
|
+
app.use(LoggerMiddleware({ logQuery: true }));
|
|
194
|
+
app.use(CorsMiddleware({ origin: "*" }));
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## 完整模块列表
|
|
198
|
+
|
|
199
|
+
| 模块 | 安装命令 | 用途 |
|
|
200
|
+
|------|----------|------|
|
|
201
|
+
| @fastcar/serverless | `npm i @fastcar/serverless` | Serverless 框架 |
|
|
202
|
+
|
|
203
|
+
## 快速开始
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# 安装依赖
|
|
207
|
+
npm i @fastcar/core @fastcar/serverless
|
|
208
|
+
|
|
209
|
+
# 本地开发
|
|
210
|
+
npx ts-node serverless-app.ts
|
|
211
|
+
```
|