【Gin】Web框架开发快速入门

本文目录

  • 一、使用go.work创建工作区
  • 二、gin框架快速上手
    • [2.1 简单的请求实现](#2.1 简单的请求实现)
    • [2.2 URI](#2.2 URI)
    • [2.3 分组路由](#2.3 分组路由)
    • [2.4 Get请求参数获取](#2.4 Get请求参数获取)
    • [2.5 Post请求参数](#2.5 Post请求参数)
    • [2.6 响应](#2.6 响应)

一、使用go.work创建工作区

依次输入下面命令,初始化工程。

cpp 复制代码
mkdir ginlearn
cd .\ginlearn\
mkdir helloworld
go work init
cd helloworld
go mod init test.com/helloworld
cd ..
go work use ./helloworld

go work 工作区是一个目录结构,它允许开发者在同一个项目中管理多个模块(go mod)。工作区的核心是一个 go.work 文件,这个文件定义了工作区中包含的模块及其依赖关系。

首先ginlearn 的目录,作为工作区的根目录。在 ginlearn 目录下创建了一个子目录 helloworld,用于存放一个模块。在当前目录(ginlearn)下初始化一个 go work 工作区,会在当前目录下生成一个 go.work 文件,该文件用于定义工作区中包含的模块。

然后进入 helloworld 目录。使用 go mod init 初始化一个 Go 模块,模块路径为 test.com/helloworld。在 helloworld 目录下生成一个 go.mod 文件,用于管理该模块的依赖。使用 go work use 命令将 helloworld 模块添加到工作区中。

工作区的作用如下:在 ginlearn 工作区中,可以直接运行 go build 或 go run,而无需进入具体的模块目录。当多个模块依赖相同的包时,go work 会自动优化依赖的下载和缓存,避免重复下载,也就是共享依赖。

二、gin框架快速上手

2.1 简单的请求实现

使用命令go get -u github.com/gin-gonic/gin安装gin框架。

可以看到gin.go中的default返回的是一个引擎的引用。

编写下面的代码,跑起来一个简单的gin应用。

go 复制代码
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/hello", func(ctx *gin.Context) {
		//json需要返回两个数据,一个code,一个obj any泛型,也就是任意类型
		ctx.JSON(200, gin.H{
			"message": "你好,这是第一个gin应用",
		})
	})
	r.Run()
}

gin中有一个H用法,就是一个map,string是键,值可以是任意。

通过post工具可以访问到结果。

常用的请求方法有:

go 复制代码
	r.GET("/get", func(ctx *gin.Context) {
		ctx.JSON(200, "get")
	})
	r.POST("/post", func(ctx *gin.Context) {
		ctx.JSON(200, "post")
	})
	r.DELETE("/delete", func(ctx *gin.Context) {
		ctx.JSON(200, "delete")
	})
	r.PUT("/put", func(ctx *gin.Context) {
		ctx.JSON(200, "put")
	})

也有支持所有的方法。

go 复制代码
r.Any("/any", func(ctx *gin.Context) {
		ctx.JSON(200, "any")
	})

2.2 URI

路径参数可以通过下面方式进行获取。

go 复制代码
r.POST("/user/find/:id", func(ctx *gin.Context) {
		param := ctx.Param("id")
		ctx.JSON(200, param)
	})

也有对应的模糊匹配的功能。

go 复制代码
r.POST("/user/*path", func(ctx *gin.Context) {
		param := ctx.Param("path")
		ctx.JSON(200, param)
})

实现效果如下。

2.3 分组路由

在进行开发的时候,往往需要进行模块的划分,比如用户模块,以user开发,商品模块,以goods开头。

go 复制代码
   ug := r.Group("/user")
	{
		ug.GET("find", func(ctx *gin.Context) {
			ctx.JSON(200, "user find")
		})
		ug.POST("save", func(ctx *gin.Context) {
			ctx.JSON(200, "user save")
		})
	}
	gg := r.Group("/goods")
	{
		gg.GET("find", func(ctx *gin.Context) {
			ctx.JSON(200, "goods find")
		})
		gg.POST("save", func(ctx *gin.Context) {
			ctx.JSON(200, "goods save")
		})
	}

2.4 Get请求参数获取

当请求路径为Requet: http://localhost:8080/user/save?id=11&name=zhangsan 的时候,可以通过下面的方式获取路径参数。

go 复制代码
	r.GET("/user/save", func(ctx *gin.Context) {
		id := ctx.Param("id")
		name := ctx.Query("name")
		ctx.JSON(200, gin.H{
			"id":   id,
			"name": name,
		})
	})

另外可以通过GetQuery来判断参数是否存在。

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		id, ok := ctx.GetQuery("id")
		address, aok := ctx.GetQuery("address")
		ctx.JSON(200, gin.H{
			"id":      id,
			"idok":    ok,
			"address": address,
			"aok":     aok,
		})
	})

同样的,也可以根据类型获取。

go 复制代码
type User struct{
	Id int64 `form:"id"`
	Name string `form:"name"`
	Address string `form:"address" binding:"required"`  
	//必填项如果某个必填字段(如 Address)没有提供,ShouldBindQuery 会返回一个错误。
}
r.GET("/user/save", func(ctx *gin.Context) {
		var user User
		err := ctx.ShouldBindQuery(&user)
		if err != nil {
			log.Println(err)
		}
		ctx.JSON(200, user)
	})

当多个请求参数名一样的时候,需要进行数组参数获取,比如:http://localhost:8080/user/save?address=Beijing&address=shanghai

可以使用下面的代码进行获取。

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		address := ctx.QueryArray("address")
		ctx.JSON(200, address)
	})
go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		address, ok := ctx.GetQueryArray("address")
		fmt.Println(ok)
		ctx.JSON(200, address)
	})

如果使用结构体绑定,需要在结构体中定义对应参数是数组,比如Address []string 来定义。

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		var user User
		err := ctx.ShouldBindQuery(&user)
		fmt.Println(err)
		ctx.JSON(200, user)
	})

当请求是map参数的时候,http://localhost:8080/user/save?addressMap[home]=Beijing&addressMap[company]=shanghai,更改为对应的QueryMap即可。

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		addressMap := ctx.QueryMap("addressMap")
		addressMap, _ := ctx.GetQueryMap("addressMap")
		ctx.JSON(200, addressMap)
	})

2.5 Post请求参数

Post一般是表单参数和json参数。

go 复制代码
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.POST("/user/save", func(ctx *gin.Context) {
		id := ctx.PostForm("id")
		name := ctx.PostForm("name")
		address := ctx.PostFormArray("address")
		addressMap := ctx.PostFormMap("addressMap")
		ctx.JSON(200, gin.H{
			"id":         id,
			"name":       name,
			"address":    address,
			"addressMap": addressMap,
		})
	})
	r.Run(":9091")
}

对于Json格式的Post请求,可以通过下面的方式进行获取。

go 复制代码
package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

type User struct {
	Id         int64             `json:"id"`
	Name       string            `json:"name"`
	Address    []string          `json:"address" binding:"required"`
	AddressMap map[string]string `json:"addressMap"`
}

func main() {
	r := gin.Default()
	r.POST("/user/save", func(ctx *gin.Context) {
		var user User
		err := ctx.ShouldBindJSON(&user)
		fmt.Println(err)
		ctx.JSON(200, user)
	})
	r.Run(":9091")
}

2.6 响应

字符串响应方式:

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "this is a %s", "ms string response")
	})

Json响应方式:

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		ctx.JSON(http.StatusOK, gin.H{
			"success": true,
		})
	})

文件格式响应方式:

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		//ctx.File("./1.png")
		ctx.FileAttachment("./1.png", "2.png")
	})

设置HTTP响应头

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		ctx.Header("test", "headertest")
	})

重定向

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		ctx.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
	})

YAML方式

go 复制代码
r.GET("/user/save", func(ctx *gin.Context) {
		ctx.YAML(200, gin.H{"name": "ms", "age": 19})
})
相关推荐
19岁开始学习8 小时前
Go学习-入门
开发语言·学习·golang
一小路一8 小时前
Go Web 开发基础:从入门到实战
服务器·前端·后端·面试·golang
LeonNo119 小时前
Gentleman:优雅的Go语言HTTP客户端工具包
开发语言·http·golang
程序无涯海9 小时前
【Go入门篇】第一章:从 Java/Python 开发者的视角入门go语言
java·python·golang·教程·编程语言
Golinie12 小时前
【Go | 从0实现简单分布式缓存】-1:LRU缓存淘汰策略与单机并发缓存
分布式·缓存·golang
秦宇升13 小时前
netcore 启用gzip压缩及缓存
web
DavidSoCool17 小时前
go执行java -jar 完成DSA私钥解析
java·golang·jar
老狼伙计1 天前
Golang深度学习
开发语言·golang
云熙涵2 天前
C#语言的物联网
开发语言·后端·golang
Golinie2 天前
【Go | 从0实现简单分布式缓存】-2:HTTP服务端与一致性哈希
分布式·缓存·golang