13.在gin中調用節課構建的rpc服務(獲取商品列表)並封裝代碼


封裝gin的router

package Weblib

import (
    "github.com/gin-gonic/gin"
    "go-micro/Services"
)

func NewGinRouter(prodService Services.ProdService) *gin.Engine {
    ginRouter := gin.Default()
    ginRouter.Use(InitMiddleware(prodService)) //使用中間件去封裝prodService到ctx中
    v1Group := ginRouter.Group("/v1")
    {
        v1Group.Handle("POST", "/prods", GetProdsList) //綁定業務處理方法到路由上
    }
    return ginRouter
}

中間件代碼

package Weblib

import (
    "github.com/gin-gonic/gin"
    "go-micro/Services"
)

func InitMiddleware(prodService Services.ProdService) gin.HandlerFunc { //返回一個中間件
    return func(context *gin.Context) { //使用中間件封裝prodService到context中
        context.Keys = make(map[string]interface{})
        context.Keys["prodservice"] = prodService
        context.Next() //Next的方法內部會調用該路由前的其他其他中間件去執行,比如有多個中間件,執行完這個會進行下一個中間件的執行
    }
}

業務處理代碼

package Weblib

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

func GetProdsList(ctx *gin.Context) {
    var prodReq Services.ProdsRequest
    prodservice := ctx.Keys["prodservice"].(Services.ProdService) //類型斷言之前通過中間件封裝到ctx中的prodService
    err := ctx.Bind(&prodReq)
    if err != nil {
        ctx.JSON(500, gin.H{"status": err.Error()})
    } else {
        prodRes, err := prodservice.GetProdsList(ctx, &prodReq)
        if err != nil {
            fmt.Println(err)
        }
        ctx.JSON(200, gin.H{"data": prodRes.Data})
    }
}

main方法

package main

import (
    "github.com/micro/go-micro"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/web"
    "github.com/micro/go-plugins/registry/consul"
    "go-micro/Services"
    "go-micro/Weblib"
)

func main() {
    //下面兩局代碼是注冊rpcserver
    myService := micro.NewService(micro.Name("prodservice.client"))
    prodService := Services.NewProdService("prodservice", myService.Client())


    consulReg := consul.NewRegistry( //新建一個consul注冊的地址,也就是我們consul服務啟動的機器ip+端口
        registry.Addrs("localhost:8500"),
    )

    //其實下面這段代碼的意義就是啟動的時候把服務注冊進去,並且啟動webservier
    httpserver := web.NewService( //go-micro很靈性的實現了注冊和反注冊,我們啟動后直接ctrl+c退出這個server,它會自動幫我們實現反注冊
        web.Name("httpprodservice"), //注冊進consul服務中的service名字
        web.Address(":8001"),        //注冊進consul服務中的端口,也是這里我們gin的server地址
        web.Handler(Weblib.NewGinRouter(prodService)),      //web.Handler()返回一個Option,我們直接把ginRouter穿進去,就可以和gin完美的結合
        web.Registry(consulReg),     //注冊到哪個服務器上的consul中
    )
    httpserver.Init() //加了這句就可以使用命令行的形式去設置我們一些啟動的配置
    httpserver.Run()
}

使用第三方工具自定義生成pb的tag

syntax = "proto3";
package Services;
import "Models.proto";
message ProdsRequest {
    //因為我們是用http請求去調用rpc請求的,httpserver解析客戶端post請求這里加上form,然后使用這個結構體傳入ctx.Bind()解析后作為request傳入rpc的方法去調用,所以要保證post的返回值的key要和我們這個form解析出來的key一樣,加入下面的注釋,使用inject_tag工具生成即可命令為protoc-go-inject-tag -input=../ProdService.pb.go(需先生成pb文件,再使用此命令修改文件的tag)

    // @inject_tag: json:"size" form:"size"
    int32 size = 1;
}

message ProdListResponse {
    repeated ProdModel data = 1;
}

service ProdService{
    rpc GetProdsList (ProdsRequest) returns (ProdListResponse);
}





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM