프로토콜 버퍼(Protocol Buffer)은 구글에서 만든 데이터 직렬화 규격을 말한다. JSON, XML 등과 같이 텍스트 기반이 아니라, 바이너리 기반 규격이기에 용량이 작고 더 빠르게 데이터를 처리할 수 있다.
프로토콜 버퍼는 바이너리 형태로 데이터를 가공하므로 사람이 읽을 수 없다. 그리고 메세지를 받는 소프트웨어 역시 메세지를 보낸 곳과 같은 메세지 규격을 사용해야만 복원하고 읽을 수 있다. 하지만 이는 암호화하여 저장한다는 의미가 아니기 때문에 보안에 안전한 것은 아니다.
프로토콜 버퍼로 가공된 데이터는 프로토콜 버퍼에서 제공하는 인터페이스 코드를 통해서만 볼 수 있어 디버깅 하기 어렵다. 그래도 바이너리 기반 규격을 사용하는 이유는 메세지 크기를 크게 줄일 수 있고 처리 성능이 좋기 때문이다.
JSON, XML과 같은 텍스트 기반 메세지 규격은 규격만 일치하는 파일을 만들어도 사용할 수 있지만, 프로토콜 버퍼의 경우 다른 형태로 규격을 관리하므로 몇 가지 준비가 필요하다.
message SimpleMessage {
string name = 1;
int64 num64 = 2;
double float64 = 3;
bytes uuid = 4;
-
}
컴파일러
컴파일러(protoc)는 스키마 파일에 필요한 언어를 인터페이스 코드로 만들어주는 프로그램이다.
인터페이스 코드
인터페이스 코드는 컴파일러가 스키마를 읽어 만들어낸 결과물로, 모든 프로그램은 이 코드를 통해서만 데이터를 직렬화/역직렬화할 수 있다.
// 프로토콜 버퍼 문법 정의
syntax = "proto3";
// 여기서부터 메세지 정의
// message 키워드는 메세지 시작
message AnotherMessage {
string name = 1;
int64 num = 2;
}
message SimpleMessage {
string name = 1;
int64 num = 2;
double float = 3;
bytes uuid = 4;
enum Type {
Ping = 0;
Urgent = 1;
}
Type type = 5;
}
repeated string name_list = 6;
repeated int64 num_list = 7;
map<string, string> map_field = 8;
<타입> <필드 이름> = <필드 번호>
필드 번호는 메세지 안에 정의된 필드를 직렬화할 때 사용하는 고유 식별자이다. 같은 메세지 내에서는 중복될 수 없지만, 다른 메세지면 중복될 수 있다.
이넘 필드
이넘 타입을 정의할 때 첫번째 이넘 필드 번호는 반드시 0이어야 한다. 이넘 타입은 중괄호로 감싸져 메세지와 독립적인 형태로 취급하기 때문에 같은 메세지 내에서도 필드 번호가 중복될 수 있다.
리스트와 맵 필드
타입 앞에 repeated 키워드가 붙은 필드는 리스트를 의미하고, map 키워드가 붙은 필드는 맵 필드를 의미한다.