Go
概述
Go 运行时利用编译型语言天然的性能优势,提供高效的后端运行能力,支持标准库
net/http 及 Gin、Echo、Fiber、Chi 等主流 Web 框架,适合构建高性能 API 服务。
优势
高性能运行时:编译型语言天然的性能优势,启动快、内存占用低。
全栈开发体验:无需分离前后端项目,可在同一项目中完成开发和部署。
路由即服务:Handler 模式下,通过文件系统定义 API 路由,像管理前端页面一样管理后端逻辑。
框架自由选择:支持 Gin、Echo、Fiber、Chi 主流 Web 框架,也支持纯标准库
net/http。零配置构建:自动检测框架、自动处理路由映射、自动交叉编译,无需手动配置。
开发模式
Go 函数提供两种开发模式,可根据项目需求选择其中一种模式,不能混合使用:
模式 | 适用场景 | 路由方式 | 框架依赖 |
Handler 模式 | 简单 API、Serverless 风格 | 文件系统路由(文件即路由) | 无(纯标准库) |
Framework 模式 | 完整 Web 应用、RESTful API | 框架内置路由 | Gin / Echo / Fiber 等 |
快速开始
Handler 模式 — 示例
在项目的
./cloud-functions/ 目录下新建 hello.go:// ./cloud-functions/hello.gopackage handlerimport ("encoding/json""net/http")func Handler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "application/json")json.NewEncoder(w).Encode(map[string]string{"message": "Hello from Go Functions on EdgeOne Pages!",})}
说明:
Framework 模式 — Gin 框架示例
零配置、开箱即用:Framework 模式的核心理念是直接使用框架原生写法,无需任何适配代码。只需按照框架官方文档正常编写代码,平台会在构建时自动完成端口适配、路径映射等所有适配工作。
// ./cloud-functions/api.gopackage mainimport ("net/http""github.com/gin-gonic/gin")func main() {r := gin.Default()// REST API v1 groupv1 := r.Group("/v1"){v1.GET("/hello", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "Hello from Gin on EdgeOne Pages!",})})users := v1.Group("/users"){users.GET("", listUsersHandler)users.GET("/:id", getUserHandler)users.POST("", createUserHandler)}}r.Run(":9000")}
说明:
入口文件名
api.go 决定了前端访问需要加 /api 前缀,如果入口文件名为 index.go,则无需额外前缀。
路由
Go 函数在 handler 模式下基于
/cloud-functions 目录结构生成访问路由。您可在项目仓库 /cloud-functions 目录下创建任意层级的子目录,参考下述示例。...cloud-functions├── index.go├── hello-pages.go├── helloworld.go├── api├── users├── list.go├── geo.go├── [id].go├── visit├── index.go├── [[default]].go...
上述目录文件结构,经 EdgeOne Pages 平台构建后将生成以下路由。这些路由将 Pages URL 映射到
/cloud-functions 文件,当客户端访问 URL 时将触发对应的文件代码被运行:文件路径 | 路由 |
/cloud-functions/index.go | example.com/ |
/cloud-functions/hello-pages.go | example.com/hello-pages |
/cloud-functions/helloworld.go | example.com/helloworld |
/cloud-functions/api/users/list.go | example.com/api/users/list |
/cloud-functions/api/users/geo.go | example.com/api/users/geo |
/cloud-functions/api/users/[id].go | example.com/api/users/1024 |
/cloud-functions/api/visit/index.go | example.com/api/visit |
/cloud-functions/api/[[default]].go | example.com/api/books/list、example.com/api/books/1024、example.com/api/... |
说明:
路由尾部斜杠 / 是可选的。/hello-pages 和 /hello-pages/ 将被路由到 /cloud-functions/hello-pages.go。
如果 Go 函数路由跟静态资源路由冲突,客户端请求将优先被路由到静态资源。
路由大小写敏感,/helloworld 将被路由到 /cloud-functions/helloworld.go,不能被路由到 /cloud-functions/HelloWorld.go
动态路由
Cloud Functions 支持动态路由,上述示例中一级动态路径 /cloud-functions/api/users/[id].go,多级动态路径 /cloud-functions/api/[[default]].go。参考下述用法:
文件路径 | 路由 | 匹配 |
/cloud-functions/api/users/[id].go | example.com/api/users/1024 | 是 |
| example.com/api/users/vip/1024 | 否 |
| example.com/api/vip/1024 | 否 |
/cloud-functions/api/[[default]].go | example.com/api/books/list | 是 |
| example.com/api/1024 | 是 |
| example.com/v2/vip/1024 | 否 |
框架路由
Framework 模式下,路由完全由框架自身管理,你只需按照框架的原生路由写法正常注册即可。平台不会分析或干预框架内部的路由定义,而是生成一条 catch-all 规则,将匹配到的所有请求转发给 Go 服务。
入口文件名决定 URL 前缀:
入口文件名 | URL 前缀 | 前端调用路径示例 | 框架内部路由 |
index.go | /(无前缀) | /v1/hello | /v1/hello |
main.go | /main | /main/v1/hello | /v1/hello |
api.go | /api | /api/v1/hello | /v1/hello |
说明:
当入口文件不是 index.go 时,前端访问需要加文件名前缀,但框架内部路由不需要改动,请求到达框架时前缀已被剥离,你的框架代码始终保持原生写法,无需感知平台的路径映射。
Function Handlers
使用 Function Handlers 可为 Pages 创建自定义请求处理程序,以及定义 RESTful API 实现全栈应用。Handler 模式下,每个
.go 文件需导出一个符合 http.HandlerFunc 签名的函数。基本用法
Handler 函数接收
http.ResponseWriter 和 *http.Request 两个参数,通过标准库即可处理各类 HTTP 请求:// ./cloud-functions/api/hello.gopackage handlerimport ("net/http")func Handler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "text/plain")w.Write([]byte("Hello, world!"))}
处理多种请求方法
通过
r.Method 判断请求方法,用 switch 实现不同方法的处理逻辑:// ./cloud-functions/api/users/index.gopackage handlerimport ("encoding/json""io""net/http")func Handler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "application/json")switch r.Method {case http.MethodGet:json.NewEncoder(w).Encode(map[string]string{"message": "Hello World"})case http.MethodPost:body, err := io.ReadAll(r.Body)if err != nil {http.Error(w, "Failed to read body", http.StatusBadRequest)return}defer r.Body.Close()var data map[string]interface{}json.Unmarshal(body, &data)w.WriteHeader(http.StatusCreated)json.NewEncoder(w).Encode(map[string]interface{}{"message": "Created", "data": data})case http.MethodDelete:w.WriteHeader(http.StatusNoContent)default:http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)}}
Handler 函数参数说明
Handler 函数的两个参数提供了完整的请求和响应操作能力:
参数/属性 | 类型 | 描述 |
r.URL.Path | string | 请求路径 |
r.URL.Query() | url.Values | 查询参数 |
r.Method | string | HTTP 请求方法(GET、POST 等) |
r.Header | http.Header | 请求头 |
r.Body | io.ReadCloser | 请求体输入流 |
w.Header() | http.Header | 设置响应头 |
w.WriteHeader(code) | method | 发送 HTTP 状态码 |
w.Write([]byte) | method | 写入响应体 |
获取查询参数
// ./cloud-functions/api/search.gopackage handlerimport ("encoding/json""net/http")func Handler(w http.ResponseWriter, r *http.Request) {// 解析查询参数query := r.URL.Query()name := query.Get("name")if name == "" {name = "Guest"}w.Header().Set("Content-Type", "application/json")json.NewEncoder(w).Encode(map[string]string{"hello": name,})}
依赖管理
Go Modules
Go 函数使用标准的 Go Modules 进行依赖管理。在
cloud-functions 目录下需包含 go.mod 文件:cloud-functions/├── go.mod├── go.sum├── hello.go└── api/└── index.go
初始化模块
如果尚未创建
go.mod,可在 cloud-functions 目录下执行:cd cloud-functionsgo mod init my-project
添加依赖
使用
go get 添加第三方依赖:go get github.com/gin-gonic/gingo get github.com/go-chi/chi/v5
或直接在代码中引入后执行
go mod tidy,自动检测并安装所需依赖:go mod tidy
go.mod 示例
module my-projectgo 1.26require (github.com/gin-gonic/gin v1.10.0)
说明:
构建时平台会自动执行交叉编译(
GOOS=linux GOARCH=amd64),无需手动配置编译目标。本地开发时使用本地 Go 环境即可正常调试。
示例模板
Go Handler 模板:
使用 Gin 框架:
使用 Echo 框架:
使用 Chi 框架:
