【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})
})
相关推荐
ttwuai1 小时前
Go 后台定时任务启停不生效怎么办?先查调度同步链路
开发语言·后端·golang
运维开发笔记1 小时前
3.1 Go if 语句学习笔记
golang
行者-全栈开发20 小时前
美团后端开发面试题全集(2026最新版):HashMap、JVM、MySQL、Redis高频考点深度解析
jvm·hashmap·java面试题·后端开发·redis缓存·mysql索引·面经汇总
进击的程序猿~21 小时前
Go Interface源码深度解析指南
开发语言·后端·golang
—Qeyser1 天前
Sponge 脚手架快速创建后端API及接口使用完整教程
golang
不爱洗脚的小滕1 天前
【Golang】Go 语言实现高可用、用户态感知与多端广播的服务端 SSE 架构
开发语言·架构·golang
报错小能手1 天前
Go 简介
开发语言·后端·golang
美味蛋炒饭.2 天前
Git 版本控制(下)
开发语言·git·学习·总结·后端开发
golang学习记2 天前
Go 项目使用docker compose的正确方式
开发语言·docker·golang