Skip to content

Commit

Permalink
feat: support apigw base64 encode (#46)
Browse files Browse the repository at this point in the history
* feat: support apigw base64 encode

* docs: update upload.md

* test: fix
  • Loading branch information
yugasun authored Jan 26, 2021
1 parent 9814c9a commit d18d9b7
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 150 deletions.
122 changes: 0 additions & 122 deletions README.en.md

This file was deleted.

6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

# 腾讯云 Koa 组件

简体中文 | [English](https://github.com/serverless-components/tencent-koa/tree/master/README.en.md)

## 简介

使用腾讯云 Koa 组件,可快速的在腾讯云创建,配置和管理一个 [Koa 框架](https://koajs.com/) 服务。
Expand Down Expand Up @@ -152,9 +150,9 @@ module.exports = app

这样应用部署到云函数后,在函数服务逻辑执行前,会先执行 `slsInitialize()` 函数,来初始化数据库连接。

### 还支持哪些组件?
## 文件上传

可以在 [Serverless Components](https://github.com/serverless/components) repo 中查询更多组件的信息。
[文件上传教程](https://github.com/serverless-components/tencent-koa/tree/master/docs/upload.md)

## License

Expand Down
6 changes: 3 additions & 3 deletions __tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const credentials = {
// get serverless construct sdk
const sdk = getServerlessSdk(instanceYaml.org)

it('should successfully deploy koa app', async () => {
it('deploy koa app by template', async () => {
const instance = await sdk.deploy(instanceYaml, credentials)
expect(instance).toBeDefined()
expect(instance.instanceName).toEqual(instanceYaml.name)
Expand All @@ -39,7 +39,7 @@ it('should successfully deploy koa app', async () => {
expect(instance.outputs.apigw.environment).toEqual(instanceYaml.inputs.apigatewayConf.environment)
})

it('should successfully update source code', async () => {
it('deploy with src code', async () => {
const srcPath = path.join(__dirname, '..', 'example')
execSync('npm install', { cwd: srcPath })
instanceYaml.inputs.src = srcPath
Expand All @@ -51,7 +51,7 @@ it('should successfully update source code', async () => {
expect(instance.outputs.templateUrl).not.toBeDefined()
})

it('should successfully remove koa app', async () => {
it('remove koa app', async () => {
await sdk.remove(instanceYaml, credentials)
result = await sdk.getInstance(instanceYaml.org, instanceYaml.stage, instanceYaml.app, instanceYaml.name)

Expand Down
23 changes: 10 additions & 13 deletions docs/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
>
> 例如,如果该组件名称是 `test_name`, ·且只部署于一个地域,则可以通过 `${output:${stage}:${app}:test_name.apigw.url}` 在别的组件中获取该组件的 API 网关的 `url`
| 名称 | 类型 | 描述 |
| :---------- | :-------------: | :----------------------------------------------------- | ---------------- |
| templateUrl | string | 未提供代码时的模板代码 url |
| region | string | 地域信息(只有一个地域时才提供) |
| scf | [`FunctionOutput | Record<string,FunctionOutput>`](#云函数输出-`FunctionOutput`) | 云函数输出信息 |
| apigw | [`ApigwOutput | Record<string:ApigwOutput>`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 |
| 名称 | 类型 | 描述 |
| :---------- | :------------------------------------------------------------------------------: | :------------------------------- |
| templateUrl | string | 未提供代码时的模板代码 url |
| region | string | 地域信息(只有一个地域时才提供) |
| scf | [`FunctionOutput | Record<string,FunctionOutput>`](#云函数输出-`FunctionOutput`) | 云函数输出信息 |
| apigw | [`ApigwOutput | Record<string:ApigwOutput>`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 |

## 云函数输出 `FunctionOutput`

Expand All @@ -25,30 +25,27 @@
## API 网关输出 `ApigwOutput`

| 名称 | 类型 | 描述 |
| :------------ | :------------------------------------------------------------------: | :------------------------- | ------- | -------- |
| :------------ | :------------------------------------------------------------------: | :------------------------- |
| serviceId | string | API 网关 ID |
| subDomain | string | API 网关子域名 |
| enviroment | `"release" | "prepub" | "test"` | API 网关 |
| enviroment | `"release" | "prepub" | "test"` | API 网关 |
| url | string | API 网关对外的完整 URL |
| traffic | number (0~1) | 将多少流量导向该云函数 |
| customDomains | [CustomDomain[]](#API-网关自定义域名输出-`ApigwOutput.CustomDomain`) | API 网关自定义域名输出列表 |

## API 网关自定义域名输出 `ApigwOutput.CustomDomain`

| 名称 | 类型 | 描述 |
| :--------------- | :----------------------------------------------------------------: | :------------------------- | ---------- |
| :--------------- | :----------------------------------------------------------------: | :------------------------- |
| domain | string | 自定义域名 |
| certificateId | string | 域名证书 ID |
| isDefaultMapping | boolean | 该自定义域名是否为默认域名 |
| pathMappingSet | [PathMapping[]](#-API-网关域名映射规则-`CustomDomain.PathMapping`) | 该域名的路径映射规则列表 |
| protocols | `"http" | "https"` | 启用的协议 |


| protocols | `"http" | "https"` | 启用的协议 |

## API 网关域名映射规则 `CustomDomain.PathMapping`

| 名称 | 类型 | 描述 |
| :--------- | :----: | :--------------- |
| path | string | 路径 |
| enviroment | string | 路径映射到的环境 |

31 changes: 31 additions & 0 deletions docs/upload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## 文件上传说明

项目中如果涉及到文件上传,需要依赖 API 网关提供的 [Base64 编码能力](https://cloud.tencent.com/document/product/628/51799),使用时只需要 `serverless.yml` 中配置 `isBase64Encoded``true`,如下:

```yaml
app: appDemo
stage: dev
component: koa
name: koaDemo

inputs:
# 省略...
apigatewayConf:
isBase64Encoded: true
# 省略...
# 省略...
```

当前 API 网关支持上传最大文件大小为 `2M`,如果文件过大,请修改为前端直传对象存储方案。

## Base64 示例

此 Github 项目的 `example` 目录下存在模板文件:

- [sls.upload.js](../example/sls.upload.js)

开发者可根据个人项目需要参考修改,使用时需要复制文件名为 `sls.js`

文件中实现了文件上传接口 `POST /upload`,如果要支持文件上传,需要安装 `@koajs/multer``multer` 包。

同时需要在 `serverless.yml``apigatewayConf` 中配置 `isBase64Encoded``true`
4 changes: 2 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"author": "yugasun",
"license": "MIT",
"dependencies": {
"koa": "^2.11.0",
"koa-router": "^8.0.8",
"@koa/router": "^10.0.0",
"koa": "^2.13.1",
"koa-sendfile": "^2.0.1"
}
}
1 change: 0 additions & 1 deletion example/serverless.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
org: orgDemo
app: appDemo
stage: dev
component: koa
Expand Down
14 changes: 11 additions & 3 deletions example/sls.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
const Koa = require('koa')
const KoaRouter = require('koa-router')
const KoaRouter = require('@koa/router')
const sendFile = require('koa-sendfile')
const path = require('path')

const app = new Koa()
const router = new KoaRouter()
const isServerless = process.env.SERVERLESS
const PORT = 3000

// Routes
router.get(`/*`, async (ctx) => {
router.get(`/`, async (ctx) => {
await sendFile(ctx, path.join(__dirname, 'index.html'))
})

app.use(router.allowedMethods()).use(router.routes())

// don't forget to export!
module.exports = app
if (isServerless) {
module.exports = app
} else {
app.listen(PORT, () => {
console.log(`Server start on http://localhost:${PORT}`)
})
}
30 changes: 30 additions & 0 deletions example/sls.upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const Koa = require('koa')
const KoaRouter = require('@koa/router')
const multer = require('@koa/multer')
const sendFile = require('koa-sendfile')
const path = require('path')

const isServerless = process.env.SERVERLESS
const app = new Koa()
const router = new KoaRouter()
const upload = multer({ dest: isServerless ? '/tmp/upload' : './upload' })

router.get(`/`, async (ctx) => {
await sendFile(ctx, path.join(__dirname, 'index.html'))
})
router.post('/upload', upload.single('file'), (ctx) => {
ctx.body = {
success: true,
data: ctx.file
}
})

app.use(router.routes()).use(router.allowedMethods())

if (isServerless) {
module.exports = app
} else {
app.listen(3000, () => {
console.log(`Server start on http://localhost:3000`)
})
}
2 changes: 1 addition & 1 deletion serverless.component.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: koa
version: 0.3.2
version: 0.4.0
author: 'Tencent Cloud, Inc.'
org: 'Tencent Cloud, Inc.'
description: Deploy a serverless Koa.js application onto Tencent SCF and API Gateway.
Expand Down
2 changes: 1 addition & 1 deletion src/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"download": "^8.0.0",
"tencent-component-toolkit": "^1.20.6",
"tencent-component-toolkit": "1.20.10",
"type": "^2.1.0"
}
}
3 changes: 3 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ const prepareInputs = async (instance, credentials, inputs = {}) => {
serviceTimeout: tempApigwConf.serviceTimeout,
method: 'ANY',
apiName: tempApigwConf.apiName || 'index',
isBase64Encoded: tempApigwConf.isBase64Encoded,
isBase64Trigger: tempApigwConf.isBase64Trigger,
base64EncodedTriggerRules: tempApigwConf.base64EncodedTriggerRules,
function: {
isIntegratedResponse: true,
functionName: functionConf.name,
Expand Down

0 comments on commit d18d9b7

Please sign in to comment.