gRPC

이 문서는 gRPC에 대한 간단한 설명과 사용 방법 및 가이드라인을 제공한다. gRPC를 사용하기 위한 protobuf에 관한 내용도 포함한다.

gRPC의 정의

gPRC Diagram

gRPC는 Google 에서 만든 RPC(Remote Procedure Call) 프로토콜이다. 네트워크 요청을 소프트웨어 내부에 있는 함수를 호출하듯이 사용하게 도와주는 프로토콜이다. gRPC 정의에 관한 자세한 내용은 What is gRPC? 문서를 참고한다.

gRPC 이점

성능

네트워크 요청으로 보내기 위해 Protobuf를 직렬화(Serialization) 및 역직렬화(Deserialization)하는 작업은 JSON 형태의 직렬화/역직렬화 보다 빠르다. 또한 gRPC의 네트워크 속도가 HTTP POST/GET 속도보다 빠르다. 특히 POST 요청 시 많은 차이를 보인다. 자세한 내용은 Mobile gRPC Benchmarks 문서를 참고한다.

API-우선 방식

Protobuf를 통해 기능을 개발하기 전에 API를 먼저 정의할 수 있다. API가 먼저 정의될 경우 개발팀이 병렬적으로 일을 진행할 수 있고, 개발 속도가 빨라지며, API를 좀 더 안정적으로 제공할 수 있다. 자세한 내용은 Understanding the API-First Approach to Building Products 문서를 참고한다.

REST API 지원

Protobuf로 정의된 API는 envoyproxygrpc-gateway 같은 gateway 를 통해 REST API로 제공 가능하다. gRPC로 정의된 API를 OpenAPI 프로토콜로 변환하여 REST API를 사용하는 클라이언트에도 API-우선 방식을 적용할 수 있다.

gRPC 사용 방법

데이터 구조 및 서비스 정의

gRPC는 데이터 구조 및 서비스를 정의하기 위해 기본적으로 protocol buffers를 사용한다. 자세한 문법 및 사용 방법은 API 정의 방법 문서를 참고한다.

gRPC 코드 생성

정의한 .proto 파일을 사용해 각 프로그래밍 언어별 코드를 생성할 수 있다. 언어별로 코드를 생성하는 방법을 제공된다. 각 언어별 코드 생성 방법은 gRPC Quick Start 문서에서 확인할 수 있다.

# Command example for generating code
protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

버즈빌에서는 buzzapis 레포지토리를 통해 API 라이브러리를 빌드한다. 자세한 방법은 API 정의 문서를 참고한다.

gRPC 구현

.proto 파일을 통해 생성된 코드를 사용해 실제 기능을 구현한다. 일반적으로 생성된 코드는 서버 인터페이스를 제공하며, 해당 인터페이스의 기능을 구현함으로써 클라이언트에게 서버의 기능을 제공할 수 있다. 각 언어별 구현 방법은 gRPC Quick Start를 참고한다.

Go 프로젝트 예시

authsvc.proto 파일을 통해 authsvc.pb.go 코드를 생성한다. server.go 에서 생성된 서비스의 인터페이스를 구현함으로써 클라이언트에게 해당 서비스를 제공할 수 있다.

// authsvc.proto
service AuthService {
    rpc GetAuth(GetAuthRequest) returns (Auth);
}
// server.go
func (s *server) GetAuth(context.Context, *pb.GetAuthRequest) (*pb.Auth, error) {
    // ...
}

Python 프로젝트 예시

weathersvc.proto 파일을 통해 weathersvc_pb2.pyweathersvc_pb2_grpc.py 코드를 생성한다. server.py 에서 생성된 서비스의 인터페이스를 구현함으로써 클라이언트에게 해당 서비스를 제공할 수 있다.

// weatersvc.proto
service WeatherService {
    rpc GetWeather (Location) returns (Weather) {}
}
# server.py
class WeatherServer(weathersvc_pb2_grpc.WeatherServiceServicer):
    def GetWeather(self, request, context):
        # ...

gRPC 서버 실행

생성된 코드를 활용해 gRPC 서버를 생성 및 실행한다. 자세한 내용은 gRPC Tutorials 문서에서 확인할 수 있다. 언어별 사용 법은 아래 문서를 확인한다.

gRPC 클라이언트 요청

TBD

OpenAPI 코드 생성

Protobuf 파일을 사용해서 OpenAPI(Swagger) 코드를 생성할 수 있다. 또한 이렇게 생성된 OpenAPI 코드를 통해 gRPC로 구현된 REST API 를 사용하는 클라이언트의 코드를 생성할 수 있다. OpenAPI 생성 방법은 grpc-gatewayUsage 7.(Optional) Generate swagger definitions 부분을 참고한다.

이때 import "google/api/annotations.proto"; 디펜던시의 경우 gRPC Transcoding 문서의 Ensure HTTP rules are deployed 부분을 참고하여 빌드할 수도 있다.

protoc -I. \
  -I./googleapis \
  --swagger_out=logtostderr=true:. \
  path/to/your_service.proto