ProtoBuf
Protocol Buffer(ProtoBuf)
Google에서 구조화된 데이터를 직렬화된 바이트 스트림이다. JSON의 형식보다 가벼워 통신에 있어 속도의 이점을 지닐 수 있다. Request나 Response의 message를 정의하여 언어가 상이한 서버에서도 동일한 Message를 관리할 수 도 있다. 현재 서비스하는 프로젝트에서도 IDL로써 클라이언트, 웹 백엔드, 웹 프론트에서 각 언어에 맞게 컴파일하여 사용하고 있다.
ProtoFile
.proto
파일은 message, package, option, service 등으로 구성되어 있다.
// item.proto
syntax = "proto3";
package proto.example;
option java_package = "yearlune.lab.proto.example";
option java_outer_classname = "ItemDTO";
message ItemRequest {
repeated Item items = 1;
}
message Item {
message Manufacturer {
string id = 1;
string name = 2;
}
string id = 1;
string name = 2;
int64 price = 5;
Manufacturer manufacturer = 10;
}
Message
메시지는 필드 이름, 필드 타입, 필드 넘버로 구성되어 있다. message 이름은 camel case를 권장하며, Field 이름은 snake case를 권장한다.
repeated
를 통해서 List를 표현할 수 있다.
message ItemRequest {
repeated Item items = 1;
}
message Item {
message Manufacturer {
string id = 1;
string name = 2;
}
string id = 1;
string name = 2;
int64 price = 5;
Manufacturer manufacturer = 10;
}
Field Type
스칼라타입, Message, Enum 등을 필드 타입으로 설정할 수 있다.
Scalar Value Type
우리에게 익숙한 double, float, int32, int64, uint32, uint64, bool, string, bytes
등이 있다.
https://developers.google.com/protocol-buffers/docs/proto3#scalar
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
Message Type
파일 내 message의 참조, nested message의 참조가 가능하며, 다른 .proto
의 message 참조가 가능하다.
// item.proto
syntax = "proto3";
package proto.example;
option java_package = "yearlune.lab.proto.example";
option java_outer_classname = "ItemDTO";
// message 참조
message ItemRequest {
repeated Item items = 1;
}
// nested message 참조
message Item {
message Manufacturer {
string id = 1;
string name = 2;
}
string id = 1;
string name = 2;
int64 price = 5;
Manufacturer manufacturer = 10;
}
--------
// order.proto
syntax = "proto3";
import "item.proto";
package proto.example;
option java_package = "yearlune.lab.proto.example";
option java_outer_classname = "OrderDTO";
// other proto message 참조
message OrderRequest {
string id = 1;
repeated Item items = 10;
}
Default value
- string: empty string
- bytes: empty bytes
- bool: false
- numeric type(int): 0
- enum type: enum value 0
Enum
allow_alias
로 동일한 enum value를 두어 별칭처럼 둘 수 있다.
enum OrderStatusType {
UNKNOWN = 0;
WAIT = 1;
PROCEEDING = 2;
DONE = 3;
FAILED = 4;
TIMEOUT= 5;
}
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;
}
Field Number
필드의 고유 넘버를 부여하여 식별하는 데 사용된다. 필드 넘버는 최소 1부터 536,870,911까지 지정 가능하다. 19000 ~ 19999까지는 프로토콜 버퍼 구현에 이미 사용되고 있다.
Package
proto message 이름끼리 구분하여 충돌하지 않기 위해 사용된다. C++의 네임스페이스와 같은 역할을 담당한다.
Option
java_package
- 기본적으로 package에 따라 자바 클래스가 생성되지만, 잘못 생성될 가능성이 존재하여, 자바로 활용하기 위해서는 이를 필히 작성하여 명시하는 것이 좋다.
java_outer_classname
- 기본적으로 .proto 파일의 이름을 camel case로 자바 클래스가 생성된다. 이는 원하는 자바 클래스 이름을 사용할때 사용된다.
java_multiple_files
- 기본 값은
false
이며, 이 경우 .proto파일을 하나의 class로 생성한다. 파일 내 message나 enum 등은 해당 class의 내부 클래스로 선언된다.true
인 경우 .proto 파일 내에 존재한 message, enum 등 마다 class로 생성된다.
option java_package = "yearlune.lab.proto.example";
option java_outer_classname = "ItemDTO";
Service
RPC서비스의 인터페이스를 정의할 수 있다. 기본은 unary rpc를 지원하며,
stream
을 통해서 stream rpc를 지원한다.
service SearchService {
// Unary RPC
rpc SearchItemsByName(ItemSearchRequest) returns (ItemSearchResponse);
// Stream RPC
rpc Subscribe(ItemSubscribeRequest) returns (stream ItemSubscribeResponse);
}
참고문헌
nbp-기술-경험-시대의-흐름-grpc-깊게-파고들기-1
Leave a comment