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;
}
}
機能
- messageを別々のApexクラスファイルに変換
- extends_message, extends_serviceのパラメータでデフォルトで継承するクラスをカスタマイズ可能
- サービスのコードはgrpc-gatewayのフォーマットで送信するクラスを作成
- Apexから直grpcはできないので…
- endpointのパラメータでAPIのエンドポイントを指定する
所感
ノリで作ったのでサービスのコードはうまく動かないかも…w