如何使用Golang构建微服务Web接口支持REST和RPC调用

来源:APP编程网作者:马来西亚程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何使用Golang构建微服务Web接口支持REST和RPC调用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用Golang构建微服务Web接口支持REST和RPC调用》有用,将其分享出去将是对创作者最好的鼓励。

微服务架构下,服务间的通信方式多样,REST适合跨语言、轻量级的外部调用,RPC则更适合内部服务间高性能的通信。Golang生态中有成熟的库可以分别实现这两种接口,且能将它们整合到同一个微服务实例中,避免维护多个服务实例的额外成本。

如何使用Golang构建微服务Web接口支持REST和RPC调用

环境准备与依赖选择

实现REST接口可以选择gin框架,它性能优异、路由功能完善;实现RPC接口可以选择grpc,它是Google开源的高性能RPC框架,基于HTTP/2协议,支持多语言。首先初始化项目并安装依赖:

go mod init micro_service_demo
go get -u github.com/gin-gonic/gin
go get -u google.golang.org/grpc
go get -u google.golang.org/protobuf

定义RPC服务协议

使用protobuf定义RPC服务的接口和数据结构,创建user.proto文件:

syntax = "proto3";

package user;

option go_package = "./user";

// 用户服务定义
service UserService {
  // 获取用户信息RPC方法
  rpc GetUser (GetUserRequest) returns (GetUserResponse);
}

// 请求参数
message GetUserRequest {
  int64 user_id = 1;
}

// 响应参数
message GetUserResponse {
  int64 user_id = 1;
  string user_name = 2;
  int32 age = 3;
}

执行以下命令生成对应的Golang代码:

protoc --go_out=. --go-grpc_out=. user.proto

实现RPC服务端逻辑

创建rpc_server.go文件,实现protobuf定义的接口:

package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	pb "micro_service_demo/user"
)

// 用户服务结构体
type UserServiceServer struct {
	pb.UnimplementedUserServiceServer
}

// 实现GetUser方法
func (s *UserServiceServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
	// 模拟查询数据库获取用户信息
	return &pb.GetUserResponse{
		UserId:   req.UserId,
		UserName: "张三",
		Age:      25,
	}, nil
}

// 启动RPC服务
func startRPCServer() {
	listen, err := net.Listen("tcp", ":8081")
	if err != nil {
		log.Fatalf("RPC监听端口失败: %v", err)
	}
	server := grpc.NewServer()
	pb.RegisterUserServiceServer(server, &UserServiceServer{})
	log.Println("RPC服务启动,监听端口8081")
	if err := server.Serve(listen); err != nil {
		log.Fatalf("RPC服务启动失败: %v", err)
	}
}

实现REST接口逻辑

创建rest_server.go文件,使用gin框架实现REST接口:

package main

import (
	"log"
	"net/http"

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

// 用户信息结构体,用于REST接口返回
type UserInfo struct {
	UserID   int64  `json:"user_id"`
	UserName string `json:"user_name"`
	Age      int32  `json:"age"`
}

// 获取用户REST接口处理函数
func getUserHandler(c *gin.Context) {
	// 获取路径参数
	userID := c.Param("id")
	// 模拟查询逻辑,实际场景可调用RPC客户端获取数据
	c.JSON(http.StatusOK, UserInfo{
		UserID:   1001,
		UserName: "张三",
		Age:      25,
	})
}

// 启动REST服务
func startRESTServer() {
	r := gin.Default()
	// 定义REST路由
	r.GET("/api/user/:id", getUserHandler)
	log.Println("REST服务启动,监听端口8080")
	if err := r.Run(":8080"); err != nil {
		log.Fatalf("REST服务启动失败: %v", err)
	}
}

整合两个服务启动

修改main.go文件,同时启动REST和RPC服务:

package main

import (
	"log"
)

func main() {
	// 启动RPC服务,使用goroutine避免阻塞
	go startRPCServer()
	// 启动REST服务
	startRESTServer()
}

接口测试验证

测试REST接口,使用curl发送请求:

curl http://127.0.0.1:8080/api/user/1001

返回结果如下:

{"user_id":1001,"user_name":"张三","age":25}

测试RPC接口,需要编写简单的RPC客户端,创建rpc_client.go文件:

package main

import (
	"context"
	"log"
	"time"

	"google.golang.org/grpc"
	pb "micro_service_demo/user"
)

func main() {
	// 连接RPC服务
	conn, err := grpc.Dial("127.0.0.1:8081", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("连接RPC服务失败: %v", err)
	}
	defer conn.Close()
	// 创建客户端
	client := pb.NewUserServiceClient(conn)
	// 设置超时
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()
	// 调用RPC方法
	resp, err := client.GetUser(ctx, &pb.GetUserRequest{UserId: 1001})
	if err != nil {
		log.Fatalf("调用RPC方法失败: %v", err)
	}
	log.Printf("RPC调用结果: 用户ID=%d, 用户名=%s, 年龄=%d", resp.UserId, resp.UserName, resp.Age)
}

运行客户端后会输出对应的用户信息,说明两种接口都正常工作。

注意事项

  • 生产环境中RPC服务需要添加认证、限流、监控等中间件,避免服务被恶意调用
  • REST接口的参数校验、错误处理需要完善,返回统一的错误格式方便前端处理
  • 如果服务需要注册到服务发现组件,比如etcd、consul,可以在服务启动后添加对应的注册逻辑
  • 两种接口的日志需要统一收集,方便后续问题排查

Golang微服务RESTRPCWeb接口修改时间:2026-06-12 12:06:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。