Go语言学习路

Gin框架路由

2021-08-13  本文已影响0人  TZX_0710

介绍

  • Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点
  • 对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错
  • 借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范

安装

1.安装Gin
go get -u github.com/gin-gonic/gin
2.引入包
import "github.com/gin-gonic/gin"
3.(可选)导入net/http。例如,如果使用常量,则需要这样做http.StatusOK。
import "net/http"

//示例
package main
import ("github.com/gin-gonic/gin")
func main(){
 //创建路由
 r:=gin.Default()
 r.GET("/",func(c *gin.Context){
     c.String(http.StatusOK,"hello world")
 })
}
//监听端口
//如果不指定端口则默认为8080
c.run(":80")

基本路由

gin框架中采用的路由库是基于httprouter做的

package main
import(
"net/http"
"github.com/gin-gonic/gin"
)
func main(){
 r:=gin.Default()
 r.GET("/",func(c *gin.Context){
     c.String(http.StatusOK,"hello word")
 })
 r.POST("/delUser",DelUser)
 //监听80端口
 r.run(":8000")
}

API参数

可以通过Context的Param方法来获取API参数

package main
import(
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
func main(){
r:=gin.Default()
r.GET("/user/:name/*action",func(c *gin.Context){
  name:=c.Param("name")
  action:=c.Param("acion")
  //截取
  action=strings.Trim(action,"/")
  c.String(http.StatusOK,name+"is"+action)
})
//默认监听8080端口
c.Run(":8080")
}

URL参数

URL参数可以通过DefaultQuery()Query()方法获取

DefaultQuery()若参数不存在,则返回默认值,Query()若不存在则返回空字符串

package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main(){
 r:=gin.Default()
 r.GET("/user",func(c *gin.Context){
     name:= c.DefaultQuery("name","Nice")
     c.String(http.StatusOK,fmt.Sprintf("%s",name))
 })
 c.Run(":8000")
}

表单参数

表单传输为post请求,http常见的传输格式为四种

  • application/json
  • application/x-www-form-urlencoded
  • application/xml
  • multipart/form-data

表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencoded或form-data格式的参数

package main
import(
    "fmt"
  "net/http"
    "github.com/gin-gonic/gin"
)
func main(){
    r:=gin.Default()
    r.POST("form",func(c *gin.Context){
        types:=c.DefaultPostForm("type","post")
        username:=c.PostForm("userName")
        password:=c.PostForm("pwd")
        c.String(http.StatusOk,fmt.Sprintf("%v",username)
    })
        c.Run(":8000")
}

单个文件

  • multipart/form-data格式用于文件上传

  • gin文件上传与原生的net/http方法类似,不同于在gin把原生的request封装到c.Request中

package main
import (
  "github.com/gin-gonic/gin"
)
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)
        }
    })
    c.Run(":800")
}

上传多个文件

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

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")
}

routees group

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

package main
import (
"github.com/gin-gonic/gin"
"net/http"
"fmt"
)
func main(){
    r:=gin.Default()
}

路由的拆分与注册

  1. 基本的路由注册 适用于路由条目较少的简单下面或者项目demo
package main

import (
    "net/http"

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

func helloHandler(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{
        "message": "Hello www.topgoer.com!",
    })
}

func main() {
    r := gin.Default()
    r.GET("/topgoer", helloHandler)
    if err := r.Run(); err != nil {
        fmt.Println("startup service failed, err:%v\n", err)
    }
}
  1. 路由拆分成单独的文件或包

当项目的规模增大后就不太适合继续在项目的main.go文件中去实现注册的相关逻辑,所以更加偏向于抽出路由模块的代码出来,形成单独一个文件

package router

import "github.com/gin-gonic/gin"
import (
  "net/http"
)

func helloHandler(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{
      "message": "Hello www.topgoer.com",
  })
}

// SetupRouter 配置路由信息
func SetupRouter() *gin.Engine {
  r := gin.Default()
  r.GET("/topgoer", helloHandler)
  return r
}

package main

import (
  "fmt"
  "router_example/router"
)

func main() {
  r := router.SetupRouter()
  if err := r.Run(); err != nil {
      fmt.Println("err failed", err)
  }
}

当前目录结构如下

router_example
├── go.mod
├── main.go
└── router
    └── routers.go

路由拆分成多个文件

当业务规模继续膨胀,单独的一个routers文件或包已经满足不了需求,所以可以分开定义多个路由文件

package router

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

func LoadSystem(e *gin.Engine) {
  r := gin.Default()
  {
      r.GET("findSystemId", findSystemId)
        r.GET("findAll",findAll)
  }
}
package router

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

func LoadUser(e *gin.Engine) {
  r := gin.Default()
  {
      r.GET("findByUserId", findByUserId)
      r.GET("findAllUser", findAllUser)
  }
}

main.go
func main() {
  r := gin.Default()
  //加载系统路由
  router.LoadSystem(r)
  //加载用户路由
  router.LoadUser(r)
  if err := r.Run(); err != nil {
      fmt.Println(err)
  }
}

当前目录结构如下

router_example
├── go.mod
├── main.go
└── router
    └── user.go
    └── system.go

路由拆分到不同的APP

项目规模太大,那么更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP

router_example
├──app
|  ├──user
|  |  ├──handle.go
|  |  ├──router.go
|  ├──system
|  |  ├──handle.go
|  |  ├──router.go
├── go.mod
├── main.go
└── router
    └── routers.go
system
package system

import (
  "github.com/gin-gonic/gin"
  "net/http"
)

func findBySystemId(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{
      "message": "findBySystemId",
  })
}
package system

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

func Routers(e *gin.Engine) {
  e.GET("findBySystemId", findBySystemId)
}
user
package user
import (
  "github.com/gin-gonic/gin"
  "net/http"
)
func findByUserId(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{
      "message": "findByUserId",
  })
}
package user

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

func Routers(e *gin.Engine) {
  e.GET("findByUserId", findByUserId)
}

package main

import (
  "fmt"
  "router_example/router"
  "router_example/service/system"
  "router_example/service/user"
)

func main() {
  //加载多个路由
  router.Include(user.Routers, system.Routers)
  //初始化
  r := router.Init()
  if err := r.Run(); err != nil {
      fmt.Println(err)
  }
}




Gin项目目录定义
上一篇 下一篇

猜你喜欢

热点阅读