grpc之实现restful api
  Adknp2DJyaqB 2023年11月13日 19 0

grpc之实现restful api

  1. 安装插件
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
  1. 克隆 googleapis,里面有需要用到的proto文件
git clone https://github.com/googleapis/googleapis.git

这个可能会超时,多get几次

go get github.com/grpc-ecosystem/grpc-gateway/v2/runtime
  1. 还是以之前golang项目为基础,在proto文件下新建rest文件夹,添加rest.proto
syntax = "proto3";
import "google/api/annotations.proto";
package rest;
option go_package = "/";
// The greeting service definition
service Rest {
  // Sends a greeting
  rpc Hello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      post: "/hello"
      body: "*"
    };
  }
}

// The request message containing the user's name
message HelloRequest {
  string Name = 1;
}

// The response message containing the greetings
message HelloReply {
  string Message = 1;
}

比之前的rpc方法多了

option (google.api.http) = {
      post: "/hello"
      body: "*"
    };

这个就是restful请求的url。 这里就用到刚才克隆的googleapis,需要两个特殊设置。 在goland里面需要手动添加一下地址,不然就找不到文件 image 然后就是命令行生成代码

protoc --proto_path=/home/wms/project/github/googleapis --proto_path=.   --go_out=. --go-grpc_out=. --grpc-gateway_out=.  rest.proto

image 会比之前的多生成一个gw文件 4. 在server文件夹实现rpc方法

package server

import (
	"context"
	res "grpc-golang/proto/rest"
)

type Rest struct {
	res.UnimplementedRestServer
}

func (s *Rest) Hello(ctx context.Context, in *res.HelloRequest) (*res.HelloReply, error) {
	return &res.HelloReply{Message: in.Name + " world"}, nil
}

  1. 然后注册服务
import ress "grpc-golang/proto/rest"
ress.RegisterRestServer(s, &Rest{})
  1. 新建一个server_rest.go以区别之前的
package main

import (
	"context"
	"flag"
	"fmt"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	ress "grpc-golang/proto/rest"
	"grpc-golang/server"
	"log"
	"net"
	"net/http"
)

func main() {
	flag.Parse()
	lis, err := net.Listen("tcp", ":50053")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := server.Register()
	fmt.Println("*************************************************")
	fmt.Println("                  rpc")
	fmt.Println("                  服务端口", lis.Addr())
	fmt.Println("*************************************************")
	//if err := s.Serve(lis); err != nil {
	//	log.Fatalf("failed to serve: %v", err)
	//}
	go func() {
		log.Fatalln(s.Serve(lis))
	}()
	conn, err := grpc.DialContext(
		context.Background(),
		"0.0.0.0:50053",
		grpc.WithBlock(),
		grpc.WithTransportCredentials(insecure.NewCredentials()),
	)
	if err != nil {
		log.Fatalln("Failed to dial server:", err)
	}

	gwmux := runtime.NewServeMux()
	// Register Greeter
	err = ress.RegisterRestHandler(context.Background(), gwmux, conn)
	if err != nil {
		log.Fatalln("Failed to register gateway:", err)
	}

	gwServer := &http.Server{
		Addr:    ":8090",
		Handler: gwmux,
	}

	log.Println("Serving gRPC-Gateway on http://0.0.0.0:8090")
	log.Fatalln(gwServer.ListenAndServe())
}

启动服务

go run server_rest.go
  1. 用浏览器访问http://192.168.2.127:8090/hello报错,然后改用postman请求 image image 可以看到接口请求是成功的,只是需要授权才能访问。
  2. 稍微调整下server_rest.go
gwmux := runtime.NewServeMux()
改成
gwmux := runtime.NewServeMux(
		// handle incoming headers
		runtime.WithMetadata(func(ctx context.Context, request *http.Request) metadata.MD {
			header := request.Header.Get("accessToken")
			// send all the headers received from the client
			md := metadata.Pairs("accessToken", header)
			return md
		}))

image

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

Adknp2DJyaqB