引言
存在每日必做但不想动手去做的事情,所以只好委托云函数每日自动触发执行
基础
目前scf支持的 Golang 版本为1.8及其以上,对于我这个刷版狂魔,从1.8
升到 1.14.3
这不是问题,舍 GOPATH
得 Go Modules
也不是问题。
在使用 Golang 开发云函数时,需要确保 main
函数位于 package main
中。在 main
函数中,通过使用 github.com/tencentyun/scf-go-lib/cloudfunction
包中的 Start
函数,启动实际处理业务的入口函数。
一个小案例:
package main
import (
"context"
"fmt"
"github.com/tencentyun/scf-go-lib/cloudfunction"
)
// 入口函数
func Run(ctx context.Context) (string, error) {
fmt.Println("Hello world")
return "OK", nil
}
//执行入口
func main() {
cloudfunction.Start(Run)
}
打包编译
Go环境的云函数,仅支持 zip 包上传,这有点气,开发体验感是和 vercel
无法比拟的,作为资深白嫖用户,要不是 vercel
免费用户资源调度受限,并且国内无CDN加速,我可能早就投保 vercel
了。
一直以来我均用我的老旧双核四线程的 Fedora
机器上进行开发,也不觉得不够用。敲击 Linux
命令行也是轻车熟路
# bash
GOOS=linux GOARCH=amd64 go build -o main main.go
zip main.zip main
当然,在windows下进行开发,基本的环境变量配置还是懂的
# cmd
set GOOS=linux
set GOARCH=amd64
go build -o main main.go
# powershell
$env:GOOS=linux
$env:GOARCH=amd64
go build -o main main.go
使用右击压缩工具对输出的二进制文件进行打包,二进制文件需要在 zip 包根目录,后上传到scf中。
入口函数
入口函数是通过 cloudfunction.Start
来启动的函数,官方给的入口函数带参形式如下
func hello()
func hello(ctx context.Context)
func hello(event DefineEvent)
func hello(ctx context.Context, event DefineEvent)
在带有2个入参时,需要确定 context
参数在前,自定义参数在后。
入参
官方提供的 event
只是一种自定义参数的形式,对于需要通过API来进行触发的请求,我们需要借助 github.com/tencentyun/scf-go-lib/events
来帮我们完成,这里正是走自己需要记录的。
events
下包含 events.APIGatewayRequest
该数据结构定义如下
// APIGatewayRequest represents an API gateway request
type APIGatewayRequest struct {
Headers map[string]string `json:"headers"`
Method string `json:"httpMethod"`
Path string `json:"path"`
QueryString APIGatewayQueryString `json:"queryString"`
Body string `json:"body"`
Context APIGatewayRequestContext `json:"requestContext"`
// the following fields are ignored
// HeaderParameters interface{} `json:"headerParameters"`
// PathParameters interface{} `json:"pathParameters"`
// QueryStringParameters interface{} `json:"queryStringParameters"`
}
可知,当我们入参使用该结构体,即可接收到请求的对于数据。
同样的,events
下包含 events.APIGatewayResponse
该数据结构定义如下
// APIGatewayResponse represents an API gateway response
type APIGatewayResponse struct {
IsBase64Encoded bool `json:"isBase64Encoded"`
StatusCode int `json:"statusCode"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
}
返回值返回此数据结构,即可返回一个API响应。
实例:
// Run 执行
func Run(ctx context.Context, event events.APIGatewayRequest) (resp events.APIGatewayResponse, err error) {
// 返回body中的内容
var body = struct {
Code int `json:"code"`
Message interface{} `json:"message"`
}{}
//整体API响应 保证CORS跨域
resp = events.APIGatewayResponse{
IsBase64Encoded: false,
Headers: map[string]string{"Content-Type": "application/json", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*"},
}
// 检测 post/get 等请求参数 tel 是否缺失 (是一个二维数组 即 key:[value...])
// 检测 headers 参数 SecretKey 是否缺失
// 检测 body 传递的 json数据 是否缺失
if event.QueryString["tel"] != nil && event.Headers["SecretKey"] != "" && event.Body != "" {
body.Code = 200
body.Message = "参数齐全!"
ret, _ := json.Marshal(body)
resp.Body = string(ret)
resp.StatusCode = body.Code
return //返回
}
body.Code = 400
body.Message = "error:参数缺失"
ret, _ := json.Marshal(body)
resp.Body = string(ret)
resp.StatusCode = body.Code
return
}
func main() {
cloudfunction.Start(Run)
}
需要说明的是 post/get
参数在 APIGatewayRequest
中均通过 QueryString
获取。若传参 json
数据,则通过 body
接收。
前端的请求可能如此来传递 json数据
//header头部设置
let header = {
'Content-Type': 'application/json',
'SecretKey': 'Cloud_Dev_Bad',
}
let data = {
bj: "北京",
sh: "上海",
}
//查询是否存在该手机记录
await this.$api.post('https://API_ADDRESS/release/api?tel=1380000000', data, {
headers: header
}).then(response => {
//成功
}).catch(error => {
//失败
})
暂时写到这里吧!