由于项目需要,我不得不快速掌握go语言来帮助我进行项目的开发。时间紧迫到我来不及去了解语言的特性就直接项目上手了。我决定就先熟悉一个主流的go框架和go语言的一些日常用法,之后就得滑着这只破船摇摇晃晃上路了。
1 基础命令
就说几个用的多的,配环境就不说了,我就说说我的理解,可能很不专业:
go init mod [example] # 初始化一个go包
go get [package] # 拉取一个go模块,类似python的pip install
go mod tidy # 模块对齐,快速拉取所有需要的模块
我感觉有了这三个命令就可以勉勉强强上路了哈哈哈哈[狗头]。
2 gin框架
直接代码上手了,不管他里面做了什么。这是一个golang很常用的基础框架。
2.1 启动http服务
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run()
}
2.2 RESTFUL API
RESTful API是利用HTTP请求访问或使用数据的应用程序接口(API)的体系结构样式。它基于表示性状态转移(REST)的原则,是一种Web服务开发中经常使用的体系结构样式和通信方式。RESTful API的主要特点包括:
- 资源(Resources):以URL的形式表示应用程序中的资源,如/users表示用户资源。
- 统一接口(Uniform Interface):使用HTTP方法(GET、POST、PUT、DELETE)对资源进行操作,并使用HTTP状态码和响应内容来表示操作的结果。
- 无状态(Stateless):每个请求都是独立的,服务器不会在请求之间保留任何状态信息。
- 可缓存(Cacheable):对于不经常变化的资源,可以启用缓存提高性能。
- 分层系统(Layered System):可以通过代理服务器等中间件实现系统的扩展性和安全性。
RESTful API的优点包括:
- 轻量级:使用HTTP协议进行通信,使用简单的数据格式进行数据交换。
- 易于扩展:使用标准的HTTP方法和数据格式,可以很容易地扩展和修改API。
- 易于缓存:使用标准的HTTP协议,可以使用缓存技术来提高性能和可扩展性。
- 易于测试:通过浏览器或其他工具可以访问和测试API。
RESTful API在多个领域有广泛应用,包括电商领域的商品展示、购物车管理、订单处理等;社交网络领域的用户管理、好友关系及消息推送等功能;物联网领域的设备管理、数据采集和远程控制;以及移动应用的数据同步、用户认证和推送消息等功能。
总的来说,RESTful API为Web服务和应用程序提供了一种高效、可扩展且易于理解的通信方式,是构建现代化Web应用的重要组成部分。
2.2.1 Method
func main() {
r := gin.Default()
r.GET("/someGet", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "get",
})
})
r.POST("/somePost", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "post",
})
})
r.PUT("/somePut", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "put",
})
})
r.DELETE("/someDelete", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "delete",
})
})
r.PATCH("/somePatch", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "patch",
})
})
r.HEAD("/someHead", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "head",
})
})
r.OPTIONS("/someOpt", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "options",
})
})
r.Run(":3000")
}
2.3 参数传递和获取
2.3.1 路径携带参数
func main() {
router := gin.Default()
router.GET("/user/:name", func(ctx *gin.Context) {
name := ctx.Param("name")
ctx.String(http.StatusOK, "Hello %s", name)
})
router.GET("/user/:name/*action", func(ctx *gin.Context) {
name := ctx.Param("name")
action := ctx.Param("action")
message := name + "is" + action
ctx.String(http.StatusOK, "Hello %s", message)
})
router.POST("/user/:name/*action", func(ctx *gin.Context) {
b := ctx.FullPath() == "/user/:name/*action"
ctx.String(http.StatusOK, "%t", b)
})
router.GET("user/groups", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "The acailable groups are [...]")
})
router.Run(":3000")
}
2.3.2 Querystring参数
func main() {
router := gin.Default()
router.GET("/welcome", func(ctx *gin.Context) {
firstname := ctx.DefaultQuery("firstname", "Guest")
lastname := ctx.Query("lastname")
ctx.Request.URL.Query().Get("lastname")
ctx.String(http.StatusOK, "Hello %s %s", firstname, lastname)
})
router.Run(":3000")
}
2.3.3 Form表单
func main() {
router := gin.Default()
router.POST("/form_post", func(ctx *gin.Context) {
message := ctx.PostForm("message")
lenn := ctx.DefaultPostForm("lenn", "anonymous")
ctx.JSON(http.StatusOK, gin.H{
"status": "posted",
"message": message,
"lenn": lenn,
})
})
router.Run(":3000")
}
2.3.4 文件上传
func main() {
router := gin.Default()
router.MaxMultipartMemory = 8 << 20
router.POST("/upload", func(ctx *gin.Context) {
file, _ := ctx.FormFile("file")
log.Println(file.Filename)
ctx.SaveUploadedFile(file, "/home/lennlouis/")
ctx.String(http.StatusOK, fmt.Sprintf("'%s' upload!", file.Filename))
})
router.Run(":3000")
}
2.3.4.1 单文件上传
func main() {
router := gin.Default()
router.MaxMultipartMemory = 8 << 20
router.POST("/upload", func(ctx *gin.Context) {
file, _ := ctx.FormFile("file")
log.Println(file.Filename)
ctx.SaveUploadedFile(file, "/home/lennlouis/")
ctx.String(http.StatusOK, fmt.Sprint("'%s' upload!", file.Filename))
})
router.Run(":8000")
}
2.3.4.2 多文件上传
func main() {
router := gin.Default()
router.MaxMultipartMemory = 8 << 20
router.POST("/upload", func(ctx *gin.Context) {
form, _ := ctx.MultipartForm()
files := form.File["upload[]"]
for _, file := range files {
log.Println(file.Filename)
ctx.SaveUploadedFile(file, "/home/lennlouis/")
}
ctx.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
})
router.Run(":8000")
}
2.4 路由(路由分组)
func loginEndpoint(c *gin.Context) {
fmt.Println(c.Request.URL)
}
func submitEndpoint(c *gin.Context) {
fmt.Println(c.Request.URL)
}
func readEndpoint(c *gin.Context) {
fmt.Println(c.Request.URL)
}
func main() {
router := gin.Default()
v1 := router.Group("/v1")
{
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}
v2 := router.Group("/v2")
{
v2.POST("/login", loginEndpoint)
v2.POST("/submit", submitEndpoint)
v2.POST("/read", readEndpoint)
}
router.Run(":8000")
}
2.5 中间件
2.5.1 中间件的使用
2.5.2 自定义recover中间件
2.6 日志
2.6.1 写入到文件
func main() {
gin.DisableConsoleColor()
f, _ := os.Create("gin.log")
gin.DefaultWriter = io.MultiWriter(f)
router := gin.Default()
router.GET("/ping", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "pong")
})
router.Run(":8000")
}
2.6.2 自定义格式
func main() {
router := gin.New()
router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string { // your custom format
return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
param.ClientIP,
param.TimeStamp.Format(time.RFC1123),
param.Method,
param.Path,
param.Request.Proto,
param.StatusCode,
param.Latency,
param.Request.UserAgent(),
param.ErrorMessage,
)
}))
router.Use(gin.Recovery())
router.GET("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "pong")
})
router.Run(":8080")
}
2.7 模型绑定和验证
2.7.1 JSON
2.7.2 Query String
type Person struct {
Name string `form:"name`
Address string `form:"address"`
}
func main() {
router := gin.Default()
router.Any("/testing", startPage)
router.Run(":8000")
}
func startPage(c *gin.Context) {
var person Person
if c.ShouldBindQuery(&person) == nil {
log.Println("====== Only Bind By Query String ======")
log.Println(person.Name)
log.Println(person.Address)
}
c.String(http.StatusOK, "Success")
}
2.7.3 QueryString or PostData
2.7.4 Bind Url
2.7.5 Bind Header
2.8 Protobuf
-
安装编译器
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
-
生成代码
protoc -I=$SRC_DIR --go_opt=paths=source_relative --go_out=$DST_DIR $SRC_DIR/helloworld.proto
grpc
持续更新