protobuf
- 구글에서 개발한 오픈소스 직렬화 라이브러리
- 메시지 직렬화, 역직렬화를 통해 네트워크 통신, 데이터 저장에 사용
- 데이터 구조와 서비스를 proto 스키마 파일에 저장하고 원하는 언어로 컴파일하면 자동으로 코드 생성
- java, Erlang, javascript, Lua, Perl, PHP, R, Scala, Swift, python, c++, go, ruby, c# 등 다양한 언어 지원
- json 을 사용하는 것보다 데이터 크기를 줄이고 전반적인 성능 향상을 기대할 수 있음
- 전력, 네트워크 컴퓨팅 파워가 부족한 임베디드 기기의 경우 도움이 됨
json vs protobuf
구분 | 특징 |
---|---|
json |
|
protobuf |
|
설치
Language Guide (proto3)
https://developers.google.com/protocol-buffers/docs/proto3
- 메시지 타입 정의 : .proto 파일 생성
- protobuf 의 패키지가 아닌 다른 패키지명 지정 가능, 언어별로 다르게 지정 가능 (지정하지 않으면 protobuf 패키지를 따름)
- 클래스명도 원하는 이름으로 변경 가능 (지정하지 않으면 .proto 파일명을 따름)
syntax = "proto3" ; option java_package= "com.test.common.protobuf" ; option java_outer_classname = "Message" ; import "Command.proto" ; message MessageBase { string data = 1 ; } |
Style Guide
- Message 및 Field name
- Message name :CamelCase (with an initial capital)
- Field name : underscore_separated_names
.proto 정의
message SongServerRequest {
required string song_name =
1
;
}
컴파일 결과
C++:
const
string& song_name() { ... }
void
set_song_name(
const
string& x) { ... }
Java:
public
String getSongName() { ... }
public
Builder setSongName(String v) { ... }
- Enums
- Enum 타입명 :CamelCase (with an initial capital)
- Enum 타입값 : CAPITALS_WITH_UNDERSCORES
- 각 Enum 값은 세미콜론(;) 으로 구분
- Service
- RPC Service 를 정의할 경우, 서비스명과 RPC 메소드명 모두 CamelCase (with an initial capital)
service FooService {
rpc GetSomething(FooRequest) returns (FooResponse);
}
Scalar Value Types
.proto 파일에 .proto Type 을 정의하면 자동 생성된 클래스에 각 언어별로 지정된 타입이 정의됨
.proto Type | Notes | C++ Type | Java Type | Python Type[2] | Go Type | Ruby Type | C# Type | PHP Type |
---|---|---|---|---|---|---|---|---|
double | double | double | float | float64 | Float | double | float | |
float | float | float | float | float32 | Float | float | float | |
int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer |
int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] |
uint32 | Uses variable-length encoding. | uint32 | int[1] | int/long[3] | uint32 | Fixnum or Bignum (as required) | uint | integer |
uint64 | Uses variable-length encoding. | uint64 | long[1] | int/long[3] | uint64 | Bignum | ulong | integer/string[5] |
sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer |
sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] |
fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 228. | uint32 | int[1] | int/long[3] | uint32 | Fixnum or Bignum (as required) | uint | integer |
fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 256. | uint64 | long[1] | int/long[3] | uint64 | Bignum | ulong | integer/string[5] |
sfixed32 | Always four bytes. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer |
sfixed64 | Always eight bytes. | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] |
bool | bool | boolean | bool | bool | TrueClass/FalseClass | bool | boolean | |
string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode[4] | string | String (UTF-8) | string | string |
bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | String (ASCII-8BIT) | ByteString | string |
You can find out more about how these types are encoded when you serialize your message in Protocol Buffer Encoding.
[1] In Java, unsigned 32-bit and 64-bit integers are represented using their signed counterparts, with the top bit simply being stored in the sign bit.
[2] In all cases, setting values to a field will perform type checking to make sure it is valid.
[3] 64-bit or unsigned 32-bit integers are always represented as long when decoded, but can be an int if an int is given when setting the field. In all cases, the value must fit in the type represented when set. See [2].
[4] Python strings are represented as unicode on decode but can be str if an ASCII string is given (this is subject to change).
[5] Integer is used on 64-bit machines and string is used on 32-bit machines.
Default Values
Type | 기본값 | 비고 |
---|---|---|
string | empty string | |
byte | empty bytes | |
bool | false | |
numeric type | zero | |
enum | first defined enum value | 0 |
message field | not set | language-dependent |
.proto 자바 컴파일
protoc 다운로드 : https://github.com/google/protobuf/releases (하단, 2018.06.18 현재 최신 protoc-3.5.1-win32.zip)
protoc --proto_path=src --java_out=build/gen src/foo.proto |
- 자바 컴파일을 위해 --java_out 지정
- .proto 파일 당 하나의 .java 파일 생성
- 경로에 포함된 / 는 패키지 구조 . 으로 변경됨
자바 코드에서 사용
public MessageBase.Builder createData(String data){ MessageBase.Builder msg = MessageBase.newBuilder(); msg.setData(data); return msg; } |
'소질없는 개발' 카테고리의 다른 글
[H2] Database C:\\user... not found, either pre-create it or allow remote database creation 오류 (0) | 2020.12.07 |
---|---|
IntelliJ code style 적용하기 (STS 사용자) (0) | 2019.02.07 |
IntelliJ 에서 Mongo 사용하기 (0) | 2019.02.07 |
IntelliJ 에서 project explorer 가 사라짐 (0) | 2019.02.07 |
Windows PowerShell (0) | 2018.02.12 |