.proto
ファイルでメッセージやサービスを定義するときのコーディング規約をまとめておきます。
Google が Style Guide として指針をまとめていますが、プロジェクト内に既に .proto
ファイルがある場合は、一貫性を保つように記述するのがよいとされています。
全般
.proto
ファイル名はすべて小文字 + アンダースコア(例:lower_snake_case.proto
).proto
ファイルは、proto
という独立したディレクトリに入れて、別のソースコードとは分けて管理する(参考: File location)- 言語に依存したディレクトリ階層に配置することは推奨されていません。例えば、Java のパッケージ階層に合わせて
.proto
ファイルを配置すると、Java ではわかりやすいと感じるかもしれませんが、他の言語で使おうとしたときにその階層構造が意味を持たないことがあります。
- 言語に依存したディレクトリ階層に配置することは推奨されていません。例えば、Java のパッケージ階層に合わせて
- 1 行は 80 文字 まで
- インデントはスペース 2 文字
- 文字列リテラルは ダブルクォート で囲む(例:
"Hoge"
)
.proto の構成
.proto
ファイルの内容は次のような順番で記述します。
- ライセンス / コピーライト(必要があれば)
- 概要 / Overview
- 構文バージョン (syntax)
- 例:
syntax = "proto3";
- これを省略すると、デフォルトで
"proto2"
とみなされてしまいます。
- 例:
- パッケージ定義 (package)
- 例:
package example.echo;
package
の指定はオプションです。例えば、Ruby や C# ではデフォルトでネームスペースに反映されますが、Python では無視されます(Python はディレクトリ構造でモジュール管理するため)。
- 例:
- インポート (import)
- 例:
import "message/other.proto";
import
ディレクティブはアルファベト順にソートしておきます。
- 例:
- オプション (option)
- 例:
option go_package = "github.com/maku77/hello";
- 例:
option java_package = "com.example.hello";
- 例:
- その他(残り全部)
パッケージ
package example.echo;
- パッケージ名はすべて小文字 (
lowercase
) - できるだけ
.proto
ファイルのディレクトリ階層と対応させる(つまり、proto
ディレクトリ以下のディレクトリ名)
メッセージ
message SongServerRequest {
optional string song_name = 1;
}
- メッセージ名は
CamelCase
で、フィールド名はlower_snace_case
の形.proto
ファイル内でsong_name
というフィールド名で定義しても、Java や Kotlin のコードを生成したときは、正しくgetSongName()
のような名前になるので心配しなくて大丈夫です。
- フィールド名のサフィックスに数値を付ける場合は、アンダースコアを挟まない
string song_name1; // ✅ Good string song_name_1; // ❌ NG
repeated
修飾子のついたフィールドの名前は複数形にするrepeated string keys = 1; // ✅ Good repeated string key = 1; // ❌ NG
Enum
- Enum 名は
CamelCase
で、各値はCAPITALS_WITH_UNDERSCORES
の形にする - 各値の行末はセミコロン (
;
) で終わる - 0 の値を持つものは、
_UNSPECIFIED
サフィックスを付けるenum FooBar { FOO_BAR_UNSPECIFIED = 0; FOO_BAR_FIRST_VALUE = 1; FOO_BAR_SECOND_VALUE = 2; }
- 各値のプレフィックスとして Enum 名に対応する名前を付ける(上記の例では
FOO_BAR_
)
サービス
- サービス名は
CamelCase
で、RPC メソッド名もCamelCase
の形にするservice FooService { rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse); rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse); }
その他
required
はproto3
以降は使わないgroups
はproto3
以降は使わない