TIL82. protocol buffer

jo_love·2021년 6월 10일
0
post-thumbnail

IDL을 비교하고, 그 중 'protocol buffer'에 대해 자세히 알아보고 사용해보자.

IDL(Interfaece Definition Language)

프로토콜 버퍼를 알려면 먼저 IDL에 대한 개념을 알아야 한다. 이미 알고있는 개념인 프로토콜은 서버와 클라이언트 간의 정보를 주고 받는 규칙이라면, IDL은 정보를 저정하는 규칙이라고 할 수 있다.
대표적인 IDL로 XML, JSON, protocol buffer가 있다.
protocol buffer는 gRPC의 IDL로 사용된다.

*gRPC란?

RPC(Remote Communication Mechanism)는 한 프로그램이 네트워크의 세부 정보를 이해하지 않고도 네트워크 안의 다른 컴퓨터에 있는 프로그램에서 서비스를 요청하는 프로토콜로, client-server 모델을 사용한다. gRPC는 구글에서 만든 RPCf를 말한다. TCP/IP 프로토콜, HTTP 2.0 프로토콜을 사용하고 IDL로 protocol buffer를 사용한다.

1. XML

특정한 데이터를 설명하기 위해 임의의 태그로 감싸며, 태그로 사용자가 직접 데이터 구조를 정의할 수 있다.
HTTP + XML 조합으로 많이 사용되며, 데이터를 저장하고 전달하는 것이 목적이다.

2. JSON

javascript에서 많이 사용되고 있는 데이터 구조로, XML에 비해서 속도가 빠르며 데이터 구조가 직관적이다.(key-value구조)
http + RESTful API + JSON 조합으로 많이 사용된다.

⭐️3.protocol buff

구글에서 만든 오프소스로 XML문제점을 개선하기 위해 만들어진 IDL이며, 직렬화된 데이터 구조를 사용한다.

  • 파일의 크기가 작다.
  • 다양한 언어를 지원한다.(C++, c#, Go, Java, Javascript, RUby, Python...)
  • 이미 배포한 서비스를 중단할 필요 없이 데이터 구조를 바꿀 수도 있다.
  • JSON 파일을 프로토콜 버퍼 파일 포맷으로 전환 가능하고, 반대의 경우도 가능하다.

*직렬화(Serialization)란?
하나의 어플리케이션을 만들 때, 프론트엔드를 자바스크립트, 백엔드를 자바로 구현한다고 가정하자. 데이터를 전송할 경우, 언어가 다르기 때문에 둘은 서로의 언어를 이해하지 못할 것이다. 따라서 서로 다른 언어로 데이터를 주고받으려고 할 때는 원시타입의 데이터를 주고받는 것이 기본이다.
직렬화란 객체의 내용을 바이트 단위로 변환하여 파일 또는 네트워크를 통해서 스트림(송수신)이 가능하도록 하는 것을 말한다.

(사실 서로 같은 언어로 프론트와 백엔드를 구현해도, 직렬화가 필요하다.)

vs xml

1.이름과 이메일을 포함하는 사람에 대한 모델을 만드는 XML의 경우

<person>
	<name>John</name>
	<email>john@example.com</email>
</person>

2.이름과 이메일을 포함하는 사람에 대한 모델을 만드는 protocol buffer의 경우

person {
	name: "John"
	email: "john@example.com"
}

-> xml과 비교해서 동일한 메세지를 인코딩하는데 시간이 단축되고, 코드가 직관적이다.

vs json

JSON은 텍스트 기반이라서, 파싱하는데 비용이 상당히 많이 들고 데이터의 크기가 커진다는 단점이 있다. 이에 비해 protocol buffer는 사람 눈으로 확인할 수 없는 이진 데이터를 사용하기 때문에 데이터 비용을 줄이고 속도도 빠르다.

구조 및 작동


프로토콜 버퍼는 하나의 프로그래밍 언어가 아닌 여러 프로그래밍 언어를 지원하는 , proto file 형태로 정의한다. .proto파일에 정의된 데이터 타입을 프로토콜 버퍼 컴파일러로 컴파일링해주면, 효율적인 바이너리(2진법)포맷의 프로토콜 버퍼 데이터를 자동으로 인코딩하고 파싱하여 각 언어에 맞는 형태의 클래스 파일을 생성해준다.

//Person메세지는 PhoneNumber메세지를 포함하고 있다.
message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}
// AddressBook메세지는 Person메세지를 포함하고 있다.
message AddressBook {
  repeated Person person = 1;
}

직렬화하려는 각각의 데이터 구조들에 대한 메세지를 추가하고, 메세지에서 각각의 필드들에 대한 이름과 타입을 .proto파일에 지정한다.

  • 다른 메세지 안에서 메세지 타입을 지정할 수 있다.
  • 각각의 요소들이 가지고 있는 "=1", "=2"마커들은 필드가 바이너리 인코딩에서 사용하는 유니크한 태그를 식별해준다.
  • 각각의 필드는 다음의 모디파이어 중 하나를 가진다.
    1.required: 반드시 제공되어야 하는 값으로 그렇지 않으면 메세지는 초기화되지 않은 것으로 간주된다.
    2.optional: 옵션 필드로 이 필드가 세팅되지 않으면 기본값이 사용된다.
    3.repeated: 이 필드는 여러번 반복되는 것으로 반복되는 값들의 순서는 프로토콜 버퍼에 보존된다.
// c++
Person person;
person.set_name("John");
person.set_id(1234);
person.set_email("john@example.com");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);

위와 같은 형태로 데이터를 사용할 수 있게된다.

protocol buffer in javascript

protocol.js설치

npm install protobufjs or yarn add protobufjs
노드js에서 사용하기 위해서 protobufjs라이브러리를 설치해야한다.

import protobuf from 'protobufjs';
  • 백엔드쪽 protocolbuf 모듈 가져오기
  • package.json scripts부분에 proto.js, proto.json.js, proto.ts 순서로 추가하기.(프로토콜 버퍼를 js에서 사용할 수 있도록 변환, 일종의 변역기 역할)
    json.js에서 protocolbuffer문법 제이슨으로 바꿔줌.필요한 것들 꺼내쓰면 된다.
profile
Lv.1🌷

0개의 댓글