zoukankan      html  css  js  c++  java
  • 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);
    }




  • 相关阅读:
    MySQL概述
    Seleniumselenium基础入门
    MySQL数据库的安装与使用
    元素定位_id
    Selenium浏览器的前进、后退、刷新
    元素定位_tag_name
    Selenium浏览器操作_窗口大小设置
    元素定位_name
    搭建maven服务器(repository)
    使用dos命令生成目录树
  • 原文地址:https://www.cnblogs.com/hualou/p/12130355.html
Copyright © 2011-2022 走看看