프로토콜 버퍼(Protocol Buffer)는 gRPC에서 데이터의 스키마를 정의하고 직렬화할때 사용하는 메커니즘입니다. google에서 개발했으며, *.proto형식의 메시지 뿐만 아니라, JSON등의 데이터를 직렬화할때도 사용되는 방식이고, gRPC에서 직렬화 방식으로 사용되고 있습니다.
프로토콜 버퍼가 gRPC에서 어떻게 동작하는지는 링크:이전 글을 참조해주세요
이 글에서는 Protocol Buffer3(Proto3)에서 스키마를 정의하는 방법들 중, 기본적인 내용에 대해 다룹니다.
syntax= "proto3";
message SearchRequest{
string query=1;
int32 page_number=2;
int32 result_per_page=3;
}
/*
C/C++ Style Comment
*/
//C/C++ Style Comment
위의 프로토콜 버퍼는 아래와 같은 특징을 가지고 있습니다.
메시지의 필드는 아래 4개중 하나의 타입에 해당합니다.
Proto3에서는 field presence라는 개념이 존재합니다. 자세한 내용은 링크(https://protobuf.dev/programming-guides/field_presence/)를 참고하시면 되고, 필드 규칙을 이해하기 위해서는 [ explicit, no ] present의 개념에 대해서만 이해하면 됩니다.
explicit present: 명시적으로 값이 존재하는지를 저장하는 값 체계
no present: 값이 존재하는지 아닌지를 노출하지 않고, 기본값을 통해 대치하는 방식
https://protobuf.dev/programming-guides/field_presence/
메시지 파싱 시, 특정 필드가 지정되어있지 않으면 필드는 기본값으로 설정됩니다! 그러므로, 메시지 필드가 직렬화 이후 파싱되었을 때, 필드의 값이 기본값인지 지정되지 않았던것인지 판단할 수 없습니다. 주의해야합니다.
각 타입별 기본값입니다.
하나의 파일에서 여러개의 메시지를 정의할 수 있으며, 정의한 메시지를 다른 메시지에서 타입으로 사용할 수 있습니다.
message SearchResponse {
repeated Result results = 1;
}
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}
메시지를 원하는만큼 중첩해 정의할 수 있으며, 메시지 내부에 정의된 메시지는 부모 메시지로부터 참조해야합니다
message SearchResponse {
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}
repeated Result results = 1;
}
message SomeOtherMessage {
SearchResponse.Result result = 1;
}
Map을 통해 키와 값을 매핑시킬 수 있으며, 기본 형식은 아래와 같습니다.
map<key_type, value_type> map_field = N;
OneOf타입은 상수형 값을 매핑시키는 enum과 다릅니다! 실제 자료형을 통해 선언된 여러 필드들 중, 하나의 값을 가질 수 있습니다. (map과 repeated는 사용할 수 없습니다)
message SampleMessage{
oneof test_oneof{
string name=4;
SubMessage sub_message=9;
}
}
메모리를 공유하기때문에 OneOf필드를 세팅하면 기존에 가지고있던 값이 사라집니다.
SampleMessage message;
message.set_name("name");
CHECK_EQ(message.name(), "name");
// sub_messgae필드를 없애고, name값을 할당합니다.
// sub_message to a new instance of SubMessage with none of its fields set.
message.mutable_sub_message();
CHECK(message.name().empty());
언어별로 WhichOf, Case 등, 내부에 있는 값을 확인하는 로직을 통해 사용합니다.
https://protobuf.dev/programming-guides/proto3/#simple
https://protobuf.dev/reference/protobuf/proto3-spec/
https://medium.com/naver-cloud-platform/nbp-기술-경험-시대의-흐름-grpc-깊게-파고들기-1-39e97cb3460