2020-03-21

protocのApexプラグインを作った

protobufの勉強がてらprotocのApexのプラグインを作ってみました

インストール方法

$ go get github.com/tzmfreedom/protoc-gen-apex

使い方

メッセージだけ作成

$ protoc -I. --apex_out=. target.proto

サービスクライアントも作成

$ protoc -I. \
    -I${GOPATH}/src \
    -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
    --apex_out=host=example.com/hoge:. hello.proto

サービスクライアントを作成するときはgrpc-gatewayを使う前提のコードになっているので こんな感じでprotoファイルを記述します

syntax = "proto3";

import "google/api/annotations.proto";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      post: "/v1/say_hello"
      body: "*"
    };
  }
}

protoファイル

syntax = "proto3";

package helloworld;

import "google/api/annotations.proto";

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      post: "/v1/say_hello"
      body: "*"
    };
  }
  rpc GetTask(HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/get_task"
    };
  }
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
  int32 a = 2;
  int64 b = 3;
  Hoge c = 4;
  repeated string d = 5;
  message Hoge {
    string name = 1;
  }
}

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

出力ファイル

// HelloRequest.cls
class HelloRequest {
    public String name { get; set; }
    public Integer a { get; set; }
    public Integer b { get; set; }
    public HelloRequest.Hoge c { get; set; }
    public List<String> d { get; set; }
    class Hoge {
        public String name { get; set; }

    }
}

// HelloReply.cls
class HelloReply {
    public String message { get; set; }
}

// GreeterService.cls
class GreeterService {
    
    public HelloReply SayHello(HelloRequest input) {
        String res = this.call('POST', '/v1/say_hello', JSON.serialize(input);
        return JSON.deserializeStrict(res.getBody(), HelloReply.class);
    }
    
    public HelloReply GetTask(HelloRequest input) {
        String res = this.call('GET', '/v1/get_task', JSON.serialize(input);
        return JSON.deserializeStrict(res.getBody(), HelloReply.class);
    }
    
    private String call(String method, String path, String requestBody) {
        HttpRequest req = new HttpRequest();
        req.setMethod(method);
        req.setTimeout(60000);
        req.setEndpoint('https://example.com' + path);
        req.setBody(requestBody);

        Http http = new Http();
        HTTPResponse res;
        String content;

        // Execute Http Callout
        res = http.send(req);

        if (res.getStatusCode() == 401) {
            // throw new Exception(res.getStatus());
        }
        return res;
    }
}

機能

所感

ノリで作ったのでサービスのコードはうまく動かないかも…w

このエントリーをはてなブックマークに追加