快速上手golang(持续更新)

发布于:2024-06-30 ⋅ 阅读:(150) ⋅ 点赞:(0)

由于项目需要,我不得不快速掌握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的主要特点包括:

  1. 资源(Resources):以URL的形式表示应用程序中的资源,如/users表示用户资源。
  2. 统一接口(Uniform Interface):使用HTTP方法(GET、POST、PUT、DELETE)对资源进行操作,并使用HTTP状态码和响应内容来表示操作的结果。
  3. 无状态(Stateless):每个请求都是独立的,服务器不会在请求之间保留任何状态信息。
  4. 可缓存(Cacheable):对于不经常变化的资源,可以启用缓存提高性能。
  5. 分层系统(Layered System):可以通过代理服务器等中间件实现系统的扩展性和安全性。

RESTful API的优点包括:

  1. 轻量级:使用HTTP协议进行通信,使用简单的数据格式进行数据交换。
  2. 易于扩展:使用标准的HTTP方法和数据格式,可以很容易地扩展和修改API。
  3. 易于缓存:使用标准的HTTP协议,可以使用缓存技术来提高性能和可扩展性。
  4. 易于测试:通过浏览器或其他工具可以访问和测试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

  1. 安装编译器

    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    
  2. 生成代码

    protoc -I=$SRC_DIR --go_opt=paths=source_relative --go_out=$DST_DIR $SRC_DIR/helloworld.proto
    

grpc

持续更新


网站公告

今日签到

点亮在社区的每一天
去签到