網頁

2021/8/5

Golang Gin Router HandlerFunc 拆分練習

Go Gin 把Router處理請求的HandlerFunc拆分為另外的檔案。


本篇是做Gin Router與處理請求的HandlerFunc的拆分練習,簡單說就是類似做MVC架構那樣。

範例

範例環境:

  • Go 1.16
  • Gin 1.7.2

目錄結構:

/
├─ main.go
├─ handler/
│  └─ employeehandler.go
├─ model/
│  └─ employee.go
├─ route/
│  └─ demoroute.go
│
├─ go.mod
└─ go.sum

Employee為一個簡單的struct型別,類似Java Spring Boot的model/dto/vo。

model/employee.go

package model

type Employee struct {
    Id int
    Name string
    Age int
}

main()為主程式進入點。初始化gin Engine,設定Router群組路徑/demo並啟動engine。

main.go

package main

import (
    "abc.com/demo/route"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    group := router.Group("/demo")
    route.NewDemoRoute(group).Route()
    router.Run(":8080")
}

DemoRoute角色類似Java Spring Boot的Controller的mapping,用來設定API路徑/employee/:id及負責處理請求的HandlerFunc函式。

route/demoroute.go

package route

import (
    "abc.com/demo/handler"
    "github.com/gin-gonic/gin"
)

type DemoRoute struct {
    *gin.RouterGroup
    employeeHandler *handler.EmployeeHandler
}

func NewDemoRoute(group *gin.RouterGroup) *DemoRoute {
    return &DemoRoute{
        group,
        handler.NewEmployeeHandler(),
    }
}

func (route *DemoRoute) Route() {
    route.GET("/employee/:id", route.employeeHandler.GetEmployeeById())
}

EmployeeHandler角色類似Java Spring Boot的Controller,將接收的請求參數轉交給業務層,GetEmployeeById()即為Router的函式型別HandlerFunc的實作,用來處理/empployee/:id送來的請求,函式會帶入Context參數。裡面設定一個假的裝有Employeemap,會依請求的路徑參數(path parameters)id取得對應的Employee.Name

handler/employeehandler.go

package handler

import (
    "log"
    "strconv"

    "abc.com/demo/model"
    "github.com/gin-gonic/gin"
)

type EmployeeHandler struct {
}

func NewEmployeeHandler() *EmployeeHandler {
    return &EmployeeHandler{}
}

func (h *EmployeeHandler) GetEmployeeById() gin.HandlerFunc {
    m := map[int]model.Employee{
        1: {Id: 1, Name: "John", Age: 33},
        2: {Id: 2, Name: "Mary", Age: 28},
    }

    return func(c *gin.Context) {
        id, _ := strconv.Atoi(c.Param("id"))
        log.Printf("id=%d\n", id)

        name := m[id].Name
        c.JSON(200, gin.H{
            "name": name,
        })
    }
}

參考github


測試

啟動專案以cURL測試如下。

$ curl "http://localhost:8080/demo/employee/1"
{"name":"John"}

$ curl "http://localhost:8080/demo/employee/2"
{"name":"Mary"}


沒有留言:

張貼留言