zoukankan      html  css  js  c++  java
  • 2gin路由

    一 基本路由

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func funcPost(c *gin.Context)  {
    	c.String(http.StatusOK, "post请求")
    }
    func main() {
    	r := gin.Default()
    	r.GET("/", func(c *gin.Context) {
    		c.String(http.StatusOK, "hello word")
    	})
    	r.POST("/",funcPost)
    	//r.DELETE()
    	//r.PUT()
    	//r.OPTIONS()
    	
    	//监听端口默认为8080
    	r.Run(":8000")
    }
    
    

    二 API参数

    • 可以通过Context的Param方法来获取API参数
    • localhost:8000/xxx/zhangsan
    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"strings"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/user/:name/*action", func(c *gin.Context) {
    		name := c.Param("name")
    		action := c.Param("action")
    		fmt.Println(action)
    		//把字符串开头/截取掉
    		action = strings.Trim(action, "/")
    		fmt.Println(action)
    		c.String(http.StatusOK, name+" is "+action)
    	})
    	//默认为监听8080端口
    	r.Run(":8000")
    }
    
    

    image-20200915183717884

    三 URL参数

    • URL参数可以通过DefaultQuery()或Query()方法获取
    • DefaultQuery()若参数不存在,返回默认值,Query()若不存在,返回空串
    • API http://localhost:8080/user?name=lqz
    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/user", func(c *gin.Context) {
    		//指定默认值
    		//http://localhost:8080/user 才会打印出来默认的值
    		//name := c.DefaultQuery("name", "世界")
    		name := c.Query("name")
    		c.String(http.StatusOK, fmt.Sprintf("hello %s", name))
    	})
    	r.Run()
    }
    

    不传递参数输出的结果:

    image-20200915184112118

    传递参数输出的结果:

    image-20200915184144289

    四 表单参数

    • 表单传输为post请求,http常见的传输格式为四种:
      • application/json
      • application/x-www-form-urlencoded
      • application/xml
      • multipart/form-data
    • 表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencoded或from-data格式的参数
    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.POST("/form", func(c *gin.Context) {
    		username := c.PostForm("username")
    		password := c.PostForm("password")
    		// c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))
    		c.String(http.StatusOK, fmt.Sprintf("用户名:%s,密码:%s", username, password))
    	})
    	r.Run()
    }
    

    image-20200915193412744

    五 上传单个文件

    • multipart/form-data格式用于文件上传
    • gin文件上传与原生的net/http方法类似,不同在于gin把原生的request封装到c.Request中
    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	//限制上传最大尺寸
    	r.MaxMultipartMemory = 8 << 20
    	r.POST("/upload", func(c *gin.Context) {
    		file, err := c.FormFile("file")
    		if err != nil {
    			c.String(500, "上传图片出错")
    		}
    		c.SaveUploadedFile(file, file.Filename)
    		c.String(http.StatusOK, file.Filename)
    	})
    	r.Run()
    }
    

    image-20200915193608644

    六 上传多个文件

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    // gin的helloWorld
    
    func main() {
    	// 1.创建路由
    	// 默认使用了2个中间件Logger(), Recovery()
    	r := gin.Default()
    	// 限制表单上传大小 8MB,默认为32MB
    	r.MaxMultipartMemory = 8 << 20
    	r.POST("/upload", func(c *gin.Context) {
    		form, err := c.MultipartForm()
    		if err != nil {
    			c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))
    		}
    		// 获取所有图片
    		files := form.File["files"]
    		// 遍历所有图片
    		for _, file := range files {
    			// 逐个存
    			if err := c.SaveUploadedFile(file, file.Filename); err != nil {
    				c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))
    				return
    			}
    		}
    		c.String(200, fmt.Sprintf("upload ok %d files", len(files)))
    	})
    	//默认端口号是8080
    	r.Run(":8000")
    }
    

    image-20200915194131055

    七 routes group

    routes group是为了管理一些相同的URL

    package main
    
    import (
       "fmt"
       "github.com/gin-gonic/gin"
    )
    
    // gin的helloWorld
    
    func main() {
       // 1.创建路由
       r := gin.Default()
       // 路由组1 ,处理GET请求
       v1 := r.Group("/v1")
       // {} 是书写规范,不写也开业
       {
          v1.GET("/login", login)
          v1.GET("submit", submit) //  /不写也可以
       } 
       v2 := r.Group("/v2")
    
       v2.POST("/login", login)
       v2.POST("/submit", submit)
    
       r.Run(":8000")
    }
    
    func login(c *gin.Context) {
       name := c.DefaultQuery("name", "lqz")
       c.String(200, fmt.Sprintf("hello %s\n", name))
    }
    
    func submit(c *gin.Context) {
       name := c.DefaultQuery("name", "egon")
       c.String(200, fmt.Sprintf("hello %s\n", name))
    }
    

    测试

    get请求:127.0.0.1:8000/v1/login
    get请求:127.0.0.1:8000/v1/submit
    
    post请求:127.0.0.1:8000/v1/login
    post请求:127.0.0.1:8000/v1/submit
    

    八 路由拆分与注册

    8.1 基本路由注册

    适用于路由比较少的简单项目

    package main
    
    import (
       "net/http"
    
       "github.com/gin-gonic/gin"
    )
    
    func helloHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "message": "Hello world!",
       })
    }
    
    func main() {
       r := gin.Default()
       r.GET("/hello", helloHandler)
       r.Run()
    }
    

    8.2 路由拆分成单独文件或包

    当项目的规模增大后就不太适合继续在项目的main.go文件中去实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包

    8.2.1 拆分到单独文件中

    routers.go

    package main
    import (
       "net/http"
    
       "github.com/gin-gonic/gin"
    )
    
    func helloHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "msg": "www.liuqingzheng.top",
       })
    }
    func testHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "status":100,
          "msg": "hello world",
       })
    }
    
    func initRouter() *gin.Engine {
       r := gin.Default()
       r.GET("/hello", helloHandler)
       r.GET("/test", testHandler)
       return r
    }
    
    

    main.go

    package main
    
    func main() {
       r := initRouter()
       r.Run()
    }
    
    //访问
    //http://127.0.0.1:8080/test
    http://127.0.0.1:8080/hello
    
    

    目录结构

    image-20200915230640851

    8.2.2 拆分到包中

    routers/routers.go需要注意此时initRouter需要改成首字母大写:

    package routers
    import (
       "net/http"
    
       "github.com/gin-gonic/gin"
    )
    
    func helloHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "msg": "www.liuqingzheng.top",
       })
    }
    func testHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "status":100,
          "msg": "hello world",
       })
    }
    
    func InitRouter() *gin.Engine {
       r := gin.Default()
       r.GET("/hello", helloHandler)
       r.GET("/test", testHandler)
       return r
    }
    
    

    main.go

    package main
    
    import "gin_test/routers"
    
    func main() {
       r := routers.InitRouter()
       r.Run()
    }
    
    

    目录结构

    image-20200915231146634

    8.3 路由拆分成多个文件

    单独的一个routers文件或包已经满足不了我们的需求了

    目录结构

    image-20200915232150667

    routers/goods.go

    package routers
    
    import (
       "github.com/gin-gonic/gin"
       "net/http"
    )
    
    func LoadGoodsRouters(e *gin.Engine)  {
       e.GET("/good", goodHandler)
       e.GET("/goodlist", goodlistHandler)
       e.GET("/updategood", updategoodHandler)
    }
    func goodHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "msg": "www.liuqingzheng.top",
       })
    }
    
    func goodlistHandler(c *gin.Context) {
       c.String(http.StatusOK, "goodlistHandler")
    }
    func updategoodHandler(c *gin.Context) {
       c.String(http.StatusOK, "updategoodHandler")
    }
    
    

    routers/order.go

    package routers
    
    import (
       "github.com/gin-gonic/gin"
       "net/http"
    )
    
    func LoadOrderRouters(e *gin.Engine)  {
       e.GET("/order", orderHandler)
       e.GET("/orderlist", orderlistHandler)
       e.GET("/updateorder", updateorderHandler)
    }
    func orderHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "msg": "www.liuqingzheng.top",
       })
    }
    
    func orderlistHandler(c *gin.Context) {
       c.String(http.StatusOK, "orderlistHandler")
    }
    func updateorderHandler(c *gin.Context) {
       c.String(http.StatusOK, "updateorderHandler")
    }
    
    

    routers/user.go

    package routers
    
    import (
       "github.com/gin-gonic/gin"
       "net/http"
    )
    
    func LoadUserRouters(e *gin.Engine)  {
       e.GET("/user", userHandler)
       e.GET("/userlist", userlistHandler)
       e.GET("/updateuser", updateuserHandler)
    }
    func userHandler(c *gin.Context) {
       c.JSON(http.StatusOK, gin.H{
          "msg": "www.liuqingzheng.top",
       })
    }
    
    func userlistHandler(c *gin.Context) {
       c.String(http.StatusOK, "userlistHandler")
    }
    func updateuserHandler(c *gin.Context) {
       c.String(http.StatusOK, "updateuserHandler")
    }
    
    

    main.go

    package main
    
    import (
       "gin_test/routers"
       "github.com/gin-gonic/gin"
    )
    
    func main() {
       r := gin.Default()
       routers.LoadGoodsRouters(r)
       routers.LoadOrderRouters(r)
       routers.LoadUserRouters(r)
       r.Run()
    }
    
    

    8.4 路由拆分到不同的APP

    有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。

    因此我们在项目目录下单独定义一个app目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。大致目录结构如下:

    image-20200915233649087

    app01/shop/handler.go

    package shop
    
    
    import (
       "github.com/gin-gonic/gin"
       "net/http"
    )
    
    func shopHandler(c *gin.Context)  {
       c.String(http.StatusOK, "shopHandler")
    }
    
    func shopInfoHandler(c *gin.Context)  {
       c.String(http.StatusOK, "shopInfoHandler")
    }
    
    

    app01/shop/router.go

    package shop
    
    import "github.com/gin-gonic/gin"
    
    func Routers(e *gin.Engine) {
       e.GET("/shop", shopHandler)
       e.GET("/shopinfo", shopInfoHandler)
    }
    
    

    app01/user/handler.go

    package user
    
    import (
       "github.com/gin-gonic/gin"
       "net/http"
    )
    
    func userHandler(c *gin.Context)  {
       c.String(http.StatusOK, "userHandler")
    }
    
    func userInfoHandler(c *gin.Context)  {
       c.String(http.StatusOK, "userInfoHandler")
    }
    
    

    app01/user/router.go

    package user
    
    
    import "github.com/gin-gonic/gin"
    
    func Routers(e *gin.Engine) {
       e.GET("/user", userHandler)
       e.GET("/userinfo", userInfoHandler)
    }
    
    

    routers/routers.go

    package routers
    
    import "github.com/gin-gonic/gin"
    
    type Option func(engine *gin.Engine)
    var options=[]Option{}
    //注册app的路由配置
    func Include(opts ...Option)  {
       options=append(options,opts...)
    }
    //初始化
    func  Init()*gin.Engine  {
       r:=gin.New()
       for _,opt:=range options{
          opt(r)
       }
       return r
    }
    
    

    main.go

    package main
    
    import (
       "gin_test/app01/shop"
       "gin_test/app01/user"
       "gin_test/routers"
    )
    
    func main() {
       routers.Include(shop.Routers,user.Routers)
       r:=routers.Init()
       r.Run()
    }
    
    
  • 相关阅读:
    unnitest简单场景应用
    接口基础之request
    docker常用命令
    管理之心理学
    管理团队挑战和提升
    如何留下核心成员
    管理之面试技巧
    复杂接口请求怎样写http请求
    gitlab使用(一)
    不使用AutoLayout快速兼容适配iPhone6/6 Plus
  • 原文地址:https://www.cnblogs.com/Henry121/p/15627422.html
Copyright © 2011-2022 走看看