Gin框架下Golang图书/评分/评论微服务互联调用方法
Gin 微服务本地连通方案(无Docker/K8s依赖)
微服务本质是独立的HTTP服务,本地部署时不需要容器或编排工具,直接通过HTTP请求做服务间调用即可,以下是可直接落地的实现步骤。
原有服务核心逻辑参考
现有三个服务的单数据查询逻辑不需要做核心改动:
Books API 原有查询逻辑
var book models.Books_model // fmt.Println("book is:- ", book.Book_id) if err := h.DB.Where("Book_id= ?", ctx.Param("id")).First(&book).Error; err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"}) return } ctx.JSON(http.StatusOK, gin.H{"data": book})
Ratings API 原有查询逻辑
var rat models.Rating_model if err := h.DB.Where("Books_rating_id= ?", ctx.Param("id")).First(&rat).Error; err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"}) return } fmt.Println("book is:- ", rat.Rating) ctx.JSON(http.StatusOK, gin.H{"data": rat})
Reviews API 原有查询逻辑
var rev models.Reviews_model if err := h.DB.Where("books_model_id= ?", ctx.Param("id")).First(&rev).Error; err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"}) return } ctx.JSON(http.StatusOK, gin.H{"data": rev})
前置配置
- 给三个服务分配互不冲突的本地监听端口,避免端口占用导致启动失败,参考配置:
- Books API:
127.0.0.1:8080 - Ratings API:
127.0.0.1:8081 - Reviews API:
127.0.0.1:8082
启动服务时直接在r.Run()里指定端口即可,例如Ratings API启动代码写r.Run(":8081")。
- Books API:
- 先单独调试每个服务,确保直接访问对应接口(比如访问
http://127.0.0.1:8081/ratings/1)能正常返回数据,再做服务间联调。
服务间调用实现
在Books API查询到本地书籍数据后,直接通过Go标准库net/http向另外两个服务发HTTP请求,拿到结果后拼接返回即可,不需要引入额外重型依赖。
修改后的Books API查询逻辑如下,完全保留原有代码的变量、模型命名:
import ( "net/http" "encoding/json" "fmt" "time" "github.com/gin-gonic/gin" // 原有引入的其他包,比如gorm、模型包之类的保持不变 ) // ... handler逻辑 var book models.Books_model bookId := ctx.Param("id") if err := h.DB.Where("Book_id= ?", bookId).First(&book).Error; err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"}) return } // 调用Ratings API获取评分数据 var rating models.Rating_model ratingClient := http.Client{Timeout: 3 * time.Second} // 设3秒超时,避免下级服务故障拖垮当前接口 ratingResp, err := ratingClient.Get(fmt.Sprintf("http://127.0.0.1:8081/ratings/%s", bookId)) if err == nil { defer ratingResp.Body.Close() var ratingResult struct { Data models.Rating_model `json:"data"` } if json.NewDecoder(ratingResp.Body).Decode(&ratingResult) == nil { rating = ratingResult.Data } } // 调用Reviews API获取评论数据,逻辑和上面完全一致 var review models.Reviews_model reviewClient := http.Client{Timeout: 3 * time.Second} reviewResp, err := reviewClient.Get(fmt.Sprintf("http://127.0.0.1:8082/reviews/%s", bookId)) if err == nil { defer reviewResp.Body.Close() var reviewResult struct { Data models.Reviews_model `json:"data"` } if json.NewDecoder(reviewResp.Body).Decode(&reviewResult) == nil { review = reviewResult.Data } } // 聚合三个服务的结果返回 ctx.JSON(http.StatusOK, gin.H{ "data": gin.H{ "book_info": book, "rating": rating, "review": review, }, })
优化提示
- 如果不想在Books API里重复定义Rating、Review的结构体,可以把三个服务共用的模型抽到公共
pkg/models目录下,三个服务都引用公共模型包即可,避免结构字段不一致导致的JSON解析失败。 - 本地启动三个服务嫌麻烦可以写个简单的shell脚本,一次性拉起三个服务进程,不用开三个终端手动执行启动命令。
- 如果前端直接调用这三个接口碰到浏览器跨域拦截,给每个Gin服务加上CORS中间件即可。
运行效果参考




内容的提问来源于stack exchange,提问作者Adnan Parvez
相关产品推荐
相关产品推荐

