注意
⚠️ ,fc-http 暂时 不支持FC3.0。
此模块可以方便的将传统的 web 框架使用 Nodejs runtime 的形式运行在阿里云函数计算。
将nodejs应用部署在函数计算FC上,一般有下面几种方式
Nodejs运行环境(简称Nodejs Runtime
)支持Nodejs6到Nodejs14的版本,用于只需要提供入口函数如下:
function(request, response, context) {}
当有请求触发的时候,函数计算平台会调用这个方法,启动您的应用进行处理,参考示例
Custom Runtime
是自定义运行环境,您可以自定义应用的启动脚本bootstrap
进行启动web服务器。很方便的将您的应用快速迁移到函数计算平台,参考示例
使用Custom Container
方式,开发者需要提前准备好镜像。这样能够实现最大的灵活性。
从灵活性来看
Custom Container
>Custom Runtime
>Nodejs Runtime
从性能来看
Nodejs Runtime
>Custom Runtime
>Custom Container
而且 Nodejs Runtime
还有以下优点:
- 版本支持到
nodejs14
,Custom Runtime
默认环境是nodejs10
,否则需要将nodejs的二进制包,上传到当前的运行环境 - 日志输出友好,相比
Custom Runtime
在高级查询
更具有可读性 - 支持layer层,提取公共依赖。
FC-http目前已经支持主流Nodejs框架快速接入,并提供模版示例。通过执行指令 如:s init express-app
快速体验。
- Express:
s init express-app
- Koa:
s init koa-app
- Hapi:
s init hapi-app
- Egg:
s init egg-app
- nest:
s init nest-app
- nuxt:
s init nuxt-app
- thinkjs:
s init thinkjs-app
- Connect:
s init connect-app
- Sails
- Fastify
- Restify
- Polka
- Loopback
$ npm i @serverless-devs/fc-http
- 基本示例
const serverless = require('@serverless-devs/fc-http');
const express = require('express')
const app = express()
app.get('/user', (req, res) => {
res.send('hello user!')
})
app.get('/', (req, res) => {
res.send('Hello World!')
})
exports.handler = serverless(app)
更多例子见 examples
下面例子中,req
参数可以获取一些有用的信息
app.get('/user', (req, res) => {
res.send('hello user!')
})
字段名 | 类型 | 示例 | 描述 |
---|---|---|---|
method | String | GET | HTTP请求方法 |
path | String | /api | HTTP请求方法 |
headers | Object类型 | {'content-type': 'text/plain','x-forwarded-proto': 'https' } | 存放来自HTTP客户端的键值对。 |
queries | Object类型 | {name:'age'} | 存放来自HTTP路径中的查询部分的键值对,值的类型可以为字符串或数组。 |
clientIP | String类型 | '42.120.75.232' | 客户端的IP地址。 |
fcRequest | Object类型 | 详情参考 | FC原始的 request参数 |
fcContext | Object类型 | 详情参考 | FC原始的 context参数 |
fc-http 接受第二个参数options,它可以配置:
-
basePath:无服务器应用程序的基本路径/挂载点。如果您希望使用多个 Lambda 来表示应用程序的不同部分,则很有用。
-
配置前
app.get("/new", (ctx) => {
res.send('Hello World!')
})
exports.handler = serverless(app);
[GET] http://localhost/api/new -> 404
- 配置后
app.get("/new", (ctx) => {
res.send('Hello World!')
})
exports.handler = serverless(app, {
basePath: '/api'
});
[GET] http://localhost/api/new -> 200
在 FC 中,上面的示例也适用于:
https://xxx.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/dk-http-demo/api/new -> 200
- request:请求的转换,在它被发送到应用程序之前
- response:响应的转换,在返回给 Lambda 之前
转换是要分配的函数(req|res、事件、上下文)或对象。
您可以在请求通过您的应用程序之前对其进行转换。
您可以在响应返回之后,在发送之前对其进行转换:
一些例子
exports.handler = serverless(app, {
request: {
key: 'value'
},
response(res) {
res.foo = 'bar';
}
})
exports.handler = serverless(app, {
request(request, event, context) {
request.context = event.requestContext;
},
async response(response, event, context) {
// the return value is always ignored
return new Promise(resolve => {
// override a property of the response, this will affect the response
response.statusCode = 420;
// delay your responses by 300ms!
setTimeout(() => {
// this value has no effect on the response
resolve('banana');
}, 300);
});
}
})
二进制模式检测查看BINARY_CONTENT_TYPES环境变量,或者您可以指定类型数组,或自定义函数:
// turn off any attempt to base64 encode responses -- probably Not Going To Work At All
serverless(app, {
binary: false
});
// this is the default, look at content-encoding vs. gzip, deflate and content-type against process.env.BINARY_CONTENT_TYPES
serverless(app, {
binary: true
});
// set the types yourself - just like BINARY_CONTENT_TYPES but using an array you pass in, rather than an environment varaible
serverless(app, {
binary: ['application/json', 'image/*']
});
// your own custom callback
serverless(app, {
binary(headers) {
return ...
}
});
- Serverless Devs 工具:
- 阿里云函数计算组件:
- 钉钉交流群:33947367