diff --git a/README.en.md b/README.en.md deleted file mode 100644 index e25e79f..0000000 --- a/README.en.md +++ /dev/null @@ -1,122 +0,0 @@ -[![Serverless Koa Tencent Cloud](https://img.serverlesscloud.cn/20191226/1577361724216-koajs_width.png)](http://serverless.com) - -# Tencent Koa Serverless Component - -[简体中文](https://github.com/serverless-components/tencent-koa/tree/master/README.md) | English - -## Introduction - -Easily deploy [koa](https://koajs.com/) applications to Tencent Cloud's serverless infrastructure using this Serverless Framework Component. Your application will auto-scale, never charge you for idle time, and require little-to-zero administration. - -## Content - -1. [Install](#1-install) -2. [Create](#2-create) -3. [Configure](#3-configure) -4. [Deploy](#4-deploy) -5. [Remove](#5-remove) - -### 1. Install - -```bash -$ npm install -g serverless -``` - -### 2. Create - -Just create `serverless.yml` and `.env` files - -```bash -$ touch .env # your Tencent API Keys -$ touch sls.js -$ touch serverless.yml -``` - -Add the access keys of a [Tencent CAM Role](https://console.cloud.tencent.com/cam/capi) with `AdministratorAccess` in the `.env` file, using this format: - -``` -# .env -TENCENT_SECRET_ID=123 -TENCENT_SECRET_KEY=123 -``` - -- If you don't have a Tencent Cloud account, you could [sign up](https://intl.cloud.tencent.com/register) first. - -Initialize a new NPM package and install koa: - -```bash -# then keep hitting enter -$ npm init - -# install koa -$ npm i --save koa -``` - -create your koa app in `sls.js`: - -```js -const koa = require('koa') -const app = new koa() - -app.use(async (ctx, next) => { - if (ctx.path !== '/') return next() - ctx.body = 'Hello from Koa' -}) - -// set binary types -// app.binaryTypes = [*/*]; - -// don't forget to export! -module.exports = app -``` - -### 3. Configure - -```yml -# serverless.yml - -org: orgDemo # (optional) serverless dashboard org. default is the first org you created during signup. -app: appDemo # (optional) serverless dashboard app. default is the same as the name property. -stage: dev # (optional) serverless dashboard stage. default is dev. -component: koa # (required) name of the component. In that case, it's koa. -name: koaDemo # (required) name of your koa component instance. - -inputs: - src: - src: ./ # (optional) path to the source folder. default is a hello world app. - exclude: - - .env - region: ap-guangzhou - runtime: Nodejs10.15 - apigatewayConf: - protocols: - - http - - https - environment: release -``` - -- [Click here to view the configuration document](https://github.com/serverless-components/tencent-koa/tree/master/docs/configure.md) - -### 4. Deploy - -``` -$ sls deploy -``` - -You can now visit the output URL in the browser, and you should see the koa response. - -### 5. Remove - -``` -$ sls remove -``` - -### New to Components? - -Checkout the [Serverless Components](https://github.com/serverless/components) repo for more information. - -## License - -MIT License - -Copyright (c) 2020 Tencent Cloud, Inc. diff --git a/README.md b/README.md index 7bc7f87..75e9ea4 100755 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ # 腾讯云 Koa 组件 -简体中文 | [English](https://github.com/serverless-components/tencent-koa/tree/master/README.en.md) - ## 简介 使用腾讯云 Koa 组件,可快速的在腾讯云创建,配置和管理一个 [Koa 框架](https://koajs.com/) 服务。 @@ -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 diff --git a/__tests__/index.test.js b/__tests__/index.test.js index 47d78f7..fc084d8 100644 --- a/__tests__/index.test.js +++ b/__tests__/index.test.js @@ -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) @@ -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 @@ -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) diff --git a/docs/output.md b/docs/output.md index fe9568c..984f457 100644 --- a/docs/output.md +++ b/docs/output.md @@ -4,12 +4,12 @@ > > 例如,如果该组件名称是 `test_name`, ·且只部署于一个地域,则可以通过 `${output:${stage}:${app}:test_name.apigw.url}` 在别的组件中获取该组件的 API 网关的 `url`。 -| 名称 | 类型 | 描述 | -| :---------- | :-------------: | :----------------------------------------------------- | ---------------- | -| templateUrl | string | 未提供代码时的模板代码 url | -| region | string | 地域信息(只有一个地域时才提供) | -| scf | [`FunctionOutput | Record`](#云函数输出-`FunctionOutput`) | 云函数输出信息 | -| apigw | [`ApigwOutput | Record`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 | +| 名称 | 类型 | 描述 | +| :---------- | :------------------------------------------------------------------------------: | :------------------------------- | +| templateUrl | string | 未提供代码时的模板代码 url | +| region | string | 地域信息(只有一个地域时才提供) | +| scf | [`FunctionOutput | Record`](#云函数输出-`FunctionOutput`) | 云函数输出信息 | +| apigw | [`ApigwOutput | Record`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 | ## 云函数输出 `FunctionOutput` @@ -25,10 +25,10 @@ ## 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 网关自定义域名输出列表 | @@ -36,14 +36,12 @@ ## API 网关自定义域名输出 `ApigwOutput.CustomDomain` | 名称 | 类型 | 描述 | -| :--------------- | :----------------------------------------------------------------: | :------------------------- | ---------- | +| :--------------- | :----------------------------------------------------------------: | :------------------------- | | domain | string | 自定义域名 | | certificateId | string | 域名证书 ID | | isDefaultMapping | boolean | 该自定义域名是否为默认域名 | | pathMappingSet | [PathMapping[]](#-API-网关域名映射规则-`CustomDomain.PathMapping`) | 该域名的路径映射规则列表 | -| protocols | `"http" | "https"` | 启用的协议 | - - +| protocols | `"http" | "https"` | 启用的协议 | ## API 网关域名映射规则 `CustomDomain.PathMapping` @@ -51,4 +49,3 @@ | :--------- | :----: | :--------------- | | path | string | 路径 | | enviroment | string | 路径映射到的环境 | - diff --git a/docs/upload.md b/docs/upload.md new file mode 100644 index 0000000..7872339 --- /dev/null +++ b/docs/upload.md @@ -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`。 diff --git a/example/package.json b/example/package.json index b9e6dd1..a2bf973 100644 --- a/example/package.json +++ b/example/package.json @@ -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" } } diff --git a/example/serverless.yml b/example/serverless.yml index 77cb91f..d8bd465 100644 --- a/example/serverless.yml +++ b/example/serverless.yml @@ -1,4 +1,3 @@ -org: orgDemo app: appDemo stage: dev component: koa diff --git a/example/sls.js b/example/sls.js index 884083d..28688a4 100644 --- a/example/sls.js +++ b/example/sls.js @@ -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}`) + }) +} diff --git a/example/sls.upload.js b/example/sls.upload.js new file mode 100644 index 0000000..7e57b1b --- /dev/null +++ b/example/sls.upload.js @@ -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`) + }) +} diff --git a/serverless.component.yml b/serverless.component.yml index b6ce4e7..8112e5a 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -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. diff --git a/src/package.json b/src/package.json index c8e5d3f..737548c 100644 --- a/src/package.json +++ b/src/package.json @@ -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" } } diff --git a/src/utils.js b/src/utils.js index 72c30b5..b8b6b6d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -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,