쿼카러버의 기술 블로그

[gRPC] protocol buffer란? (protoc 실행 및 proto 예제) 본문

웹 개발

[gRPC] protocol buffer란? (protoc 실행 및 proto 예제)

quokkalover 2022. 2. 26. 17:47

Protocol Buffers

구글에서 개발한 직렬화 데이터 구조다. 인터페이스 정의용 언어(IDL Interface Definition Language)를 사용해 데이터를 저장하기 위해 proto라는 형태로 정의하고, protoc(proto compile)을 이용해 컴파일을 하면 언어에 맞는 코드를 생성해준다.

 

 

grpc에서는 unary, stream이라는 용어를 사용하는데, unary는 http와 유사하게 stateless한 통신방식으로 request와 response를 1회 받을 때만 TCP커넥션을 맺고 처리한다. (REST의 HTTP통신보다 훨씬 성능이 좋다)

 

stream은 이름에서 유추할 수 있지만, 지속적으로 데이터를 주고받을 수 있는 소켓 통신과 같이 사용할 수 있는 통신 방식이다.

 

 

필자가 작성한 grpc 튜토리얼 에서 사용한 코드를 가지고 자세히 살펴보자

 

참고로 본 글에서는 unary에 한해서 설명하도록 하겠다. (stream은 나중에)

syntax = "proto3";
package chat;
option go_package = "./chat";

message Message {
  string body = 1;
    repeated string items = 2;
}

service ChatService {
  rpc SayHello(Message) returns (Message) {}
}

위에서 message Message는 데이터를 주고받을 데이터 포맷이다.

repeated키워드는 모디파이어로, 기본적으로 다음의 모디파이어들이 있다.

  1. required: 반드시 제공되어야 하는 값으로 그렇지 않으면 메세지는 초기화되지 않은 것으로 간주된다.

2.optional: 옵션 필드로 이 필드가 세팅되지 않으면 기본값이 사용된다.

3.repeated: Array를 의미하고 string items를 여러개 받겠다는 의미다. (순서가 보존된다)

service부분은 웹 서비스의 api정의서라고 생각하면 된다.

rpc SayHello를 보면 Message라는 message타입을 unary로 보내겠다는 의미로, 세션을 유지하지 않는다.

이제 위 파일을 protoc로 를 통해 사용하고자 하는 언어에 맞게 stub 파일을 생성해보자.

 

protoc -I . --go_out=plugins=grpc:. protos/chat.proto
  • 이게 해보니까 chat.proto안에 option go_package 구문과 위 커맨드에서 --go_out=plugins=grpc:. 부분에서 grpc:{경로}(위 커맨드에서는 .사용) 부분이 꼬이지 않게 해주어야함.
    • go mod에서 chat.go를 인식하기 위해서는 디렉토리 설정이 잘돼야하기때문에
    • 커맨드에서 설정한 . 경로에서 option의 go_package가 설정되는 느낌임. 근데 패키지 이름은 ./만 입력하면 패키지 이름이 __처리가 되는 것 같아서 필자는 그냥 커맨드에서 경로를 현재경로인 . 로 설정하고, option go_package부분에서 “./chat”을 입력함.

 

위와 같이 컴파일을 하고나면 chat.pb.go파일이 생성된다.

 

.proto파일에서 정의한 메시지 형식과 통신 방식을 go언어로 생성해준다. 그리고 이렇게 protoc 컴파일로 생성된 파일은 수정하지 말자. getter나 setter가 필요하다면 extension기능을 통해 추가 가능하다.

 

 

참고자료:

https://velog.io/@jo_love/TIL82.-protocol-buffer

Comments