Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,已经发布了1.0版本。具有快速灵活,容错方便等特点。其实对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错。框架更像是一些常用函数或者工具的集合。借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范。
什么是 API
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数或者接口,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无须访问源码,或理解内部工作机制的细节。
要实现一个 API 服务器,首先要考虑两个方面:API 风格和媒体类型。Go 语言中常用的 API 风格是 RPC 和 REST,常用的媒体类型是 JSON、XML 和 Protobuf。在 Go API 开发中常用的组合是 gRPC + Protobuf 和 REST + JSON,本次我们使用gin作为api服务的构建框架。
加载路由,并启动 HTTP 服务
main.go 中的 main() 函数是 Go 程序的入口函数,在 main() 函数中主要做一些配置文件解析、程序初始化和路由加载之类的事情,最终调用 http.ListenAndServe() 在指定端口启动一个 HTTP 服务器。本小节是一个简单的 HTTP 服务器,仅初始化一个 Gin 实例,加载路由并启动 HTTP 服务器。
开发环境搭建
Go 有多种安装方式,比如 Go 源码安装、Go 标准包安装、第三方工具(yum、apt-get 等)安装。本小册 API 运行在 Linux 服务器上,选择通过标准包来安装 Go 编译环境。Go 提供了每个平台打好包的一键安装,这些包默认会安装到如下目录:/usr/local/go。当然你可以改变它们的安装位置,但是改变之后你必须在你的环境变量中设置如下两个环境变量:
GOROOT:GOROOT 就是 Go 的安装路径
GOPATH:GOPATH 是作为编译后二进制的存放目的地和 import 包时的搜索路径
假定你想要安装 Go 的目录为 $GO_INSTALL_DIR,后面替换为相应的目录路径,安装步骤如下。
下载安装包
安装包下载地址为 golang.org,如果打不开可以使用这个地址:golang.google.cn。
Linux 版本选择 goxxxxx.linux-amd64.tar.gz 格式的安装包,这里在 Linux 服务器上直接用 wget 命令下载:
$ wget https://dl.google.com/go/go1.10.2.linux-amd64.tar.gz
设置安装目录
$ export GO_INSTALL_DIR=$HOME
这里我们安装到用户主目录下。
解压 Go 安装包
$ tar -xvzf go1.10.2.linux-amd64.tar.gz -C $GO_INSTALL_DI
设置环境变量
$ export GO_INSTALL_DIR=$HOME
$ export GOROOT=$GO_INSTALL_DIR/go
$ export GOPATH=$HOME/ginserver
$ export PATH=$GOPATH/bin:$PATH:$GO_INSTALL_DIR/go/bin
如果不想每次登录系统都设置一次环境变量,可以将上面 4 行追加到 $HOME/.bashrc 文件中。
执行 go version 检查 Go 是否成功安装
$ go version
go version go1.10.2 linux/amd64
看到 go version 命令输出 go 版本号 go1.10.2 linux/amd64,说明 go 命令安装成功。
创建 $GOPATH/src 目录, $GOPATH/src是 Go 源码存放的目录,所以在正式开始编码前要先确保 $GOPATH/src 目录存在,执行命令:
$ mkdir -p $GOPATH/src
加载路由,并启动 HTTP 服务
main.go 中的 main() 函数是 Go 程序的入口函数,在 main() 函数中主要做一些配置文件解析、程序初始化和路由加载之类的事情,最终调用 http.ListenAndServe() 在指定端口启动一个 HTTP 服务器。本小节是一个简单的 HTTP 服务器,仅初始化一个 Gin 实例,加载路由并启动 HTTP 服务器。
编写入口函数,编写 main() 函数,main.go 代码:
package main
import (
"runtime"
"com.api.com/router"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
routers := router.InitRouter()
routers.Run(":8080")
}
加载路由 src/com.api.com/router/router.go
.........
// InitRouter 定义路由及函数
func InitRouter() *gin.Engine {
router := gin.Default()
load(
// Cores.
router,
// Middlwares.
middleware.Logging(),
)
//router.GET("/video/getAddressByFileId", http.GetAddressByFileID)
return router
}
自定义recovery捕获错误
gin.Recovery():在处理某些请求时可能因为程序 bug 或者其他异常情况导致程序 panic,这时候为了不影响下一次请求的调用,需要通过 gin.Recovery()来恢复 API 服务器
`````
type recovery struct {
//out optional output to log any panics
}
func (r recovery) Serve(ctx *gin.Context) {
defer func() {
if err := recover(); err != nil {
fmt.Println("recover from panic", err.(error),string(debug.Stack()))
errJson, _:= json.Marshal(ctx.Request.URL.Query())