生涯未熟

生涯未熟

プログラミングをちょこちょこと。

MD650LにKarabinerでアンダースコアを割り当てる

地味に困ったのでメモ代わりに書いておく。

MD650Lを日本語配列で使っているとアンダースコアが打てなくて困ることがありました。
Karabinerで上手いことキー割り当てたらええかーと思ったのですが、どのキーを割り当てたらいいのか分からず・・・

f:id:syossan:20190728000017p:plain
どれやねん

で、アレコレ試行錯誤した結果この「international1」ってのがアンダースコアに該当するキーのようで、右のAltに割り当てることで事なきを得ました。
いやー、これは分からん😇

f:id:syossan:20190728000241p:plain
わからん

Protocol Buffersにclang-formatをかけるとインデント崩れを起こすパターンがある

Protocol Buffersをシコシコ使ってるんですが、clang-formatをかけると具合の悪くなるパターンを発見したのでメモ。

ちなみに一応書いときますがclang-formatはProtocol Buffersをサポートしてます。

github.com

どういうパターン?

例えばこういうパターンです。

これに対してclang-formatをかけると・・・

🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔

なんでこうなるの?

調べたけどソースコード読むのダルくてわからん。
ただLLVMのbug reportはされているみたいなので、バグという認識をしている人はちゃんといるっぽい。

bugs.llvm.org

応急措置

このままじゃ困るので一旦の応急措置。

はい。微妙な違いなのですがoption内でセミコロンを使わないってことをしています。
こうするとclang-formatをかけても・・・

schema のところがちょっと変わっちゃいましたが、まぁ概ね問題無しですね。

まとめ

というわけで、clang-formatでインデント崩れ起こしちゃうパターンがあるよという話でした。
まぁバグっぽい挙動なので直るのを粛々と待つしかないですね・・・

gRPC GatewayとServerで異なるレスポンスで返す方法

前置き

gRPCにはgrpc-gatewayという、gRPC ServerのレスポンスをRestful APIの形にして返すプラグインがあります。
Protocol Buffersに少し記述を足すだけで、簡単にRestful APIの対応が出来るのでとても重宝しているのですが、一つ困ったことが起きました。それが掲題の件です。

ページネーションに対応したレスポンスを返すエンドポイントを作成する際に、以下のような形で返したかったというのが理由になります。

Serverレスポンス

Gatewayレスポンス

Server側ではページ移動する際に必要なリクエストの内容を返却し、Gateway側では直接URLを返却するという感じになります。
で、ここで問題になるのがServerのレスポンス形式とGatewayのレスポンス形式は同じにしか出来ないというところです。

例えば、このようなprotocを記述すると思うのですが、

こうした場合、Server・Gatewayのどちらもレスポンスが ExampleResponse の形式に依存することになります。 google.api.httpGatewayのレスポンスを設定が出来たらいいんですが、そういったものも見つかりませんでした。

対処法

対処の流れ説明すると

  • ResponseにAny型を使用する
  • Serverから返す場合にはServer用のレスポンス形式で返すようにする
  • Gatewayから返す場合にはGateway用のレスポンス形式で返すようにする

ってな感じです。(言語はGoを想定しているのであしからず)

ResponseにAny型を使用する

protocol buffersは google/protobuf/any.proto をインポートすることでAny型というものが使えます。Anyの名前が指し示す通りどんなメッセージ型でも受け入れることが出来ます。まずは、これをResponseに入れ込みましょう。

これで Responsepagination を通して、Server側のレスポンスとしては ServerPaginationMessage を、Gateway側のレスポンスとしては GatewayPaginationMessage を返す土壌は出来ました。

Serverから返す場合にはServer用のレスポンス形式で返すようにする

Any型のpagination fieldにServer側レスポンスを当て込むように実装していきます。
コードとしては以下のようなイメージです。

これでAny型にServer側レスポンスを上手く流せ込めました。

Gatewayから返す場合にはGateway用のレスポンス形式で返すようにする

さて、ここからが本番なのですがGateway側の場合、少し複雑なプロセスが必要になります。
https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/cmd/example-gateway-server/main.go#L21-L37 を参考に説明していきます。

grpc-gatewayにはruntimeパッケージが用意されており、まずはその中の runtime.WithForwardResponseOption を使って「レスポンスを返す前の処理」を実装していきます。

実に面倒なのが分かりますね。こんな風に Server側レスポンスを受け取る→Gateway側レスポンスを構築する→Any型に埋め込んで返す といった一連の流れになります。この辺のAny型の扱い、なかなか記事としても無いので難しいですね・・・

まとめ

という感じでこの問題は解決できましたが、Google API Design Guideを読むとどうやらGoogle様的には「ページネーションはTokenでやり取りせえよ!」というスタンスみたいなので、(Common Design Patterns  |  Cloud APIs  |  Google Cloud)もしかしたらこのやり方は邪道なのかもしれません。
しかし、昔ながらのページネーションを踏襲しつつやるにはこういった方法も必要になる場面が多いんじゃないかな?と一応書き残しておきます。

Protocol Buffersが出力するSwaggerのParameter descriptionを記述する方法

Protocol BuffersでSwaggerを吐くことが出来ますが、その際にParametersの個々のfieldにdescriptionをどうやったら付けれるのかよく分からなかったのでメモ。

どういうこと?

f:id:syossan:20190311192111p:plain

これを追加したかった。

やり方

至極簡単で、OpenAPIのfieldを使ってゴニョゴニョすればいい。

例えば以下のような感じで、protocファイルに記述する。

message HogeRequest {
  uint64 id = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {description: "Test hoge"}];
}

簡単なことだけど、これに気付くまでにめちゃくちゃかかった・・・

基礎からわかるElm 読書感想文

基礎からわかるElm読み終わったので読書感想文です。

基礎からわかる Elm
基礎からわかる Elm
posted with amazlet at 19.03.09
シーアンドアール研究所 (2019-02-27)
売り上げランキング: 3,474