Files
2025-11-17 23:25:36 +09:00
..
2025-11-17 23:25:36 +09:00
2025-11-17 23:25:36 +09:00
2025-11-17 23:25:36 +09:00

인터페이스 정의 언어(IDL) 파일 정의하기

인터페이스 정의 언어(IDL) 파일을 정의하는 방법을 배워보겠습니다.

우리가 개발할 gRPC 서비스는 다음 기능을 지원할 것입니다:

  • 서버는 클라이언트에게 현재 날짜와 시간을 반환해야 합니다.
  • 서버는 클라이언트에게 주어진 길이의 무작위로 생성된 비밀번호를 반환해야 합니다.
  • 서버는 클라이언트에게 무작위 정수를 반환해야 합니다.

gRPC 클라이언트와 서버 개발을 시작하기 전에, IDL 파일을 먼저 정의해야 합니다. IDL 파일과 관련된 파일들을 관리하기 위해 별도의 GitHub 저장소가 필요하며, 여기서는 https://github.com/Educative-Content/protoapi 를 사용합니다.

IDL 파일의 구조

다음은 protoapi.proto라는 IDL 파일의 내용입니다:

syntax = "proto3";

이 파일은 프로토콜 버퍼 언어의 proto3 버전을 사용합니다. 이전 버전인 proto2도 있으며, 약간의 문법적 차이가 있습니다. proto3를 명시하지 않으면, 프로토콜 버퍼 컴파일러는 proto2를 사용하는 것으로 간주합니다. 버전 정의는 .proto 파일의 첫 번째 비어있지 않은, 주석이 아닌 라인에 위치해야 합니다.

syntax = "proto3";

option go_package = "./;protoapi";

gRPC 도구들은 이 .proto 파일로부터 Go 코드를 생성할 것입니다. 위 라인은 생성될 Go 패키지의 이름이 protoapi임을 명시합니다. ./를 사용했기 때문에 출력 파일은 protoapi.proto와 동일한 현재 디렉토리에 생성됩니다.

service Random {
    rpc GetDate (RequestDateTime) returns (DateTime);
    rpc GetRandom (RandomParams) returns (RandomInt);
    rpc GetRandomPass (RequestPass) returns (RandomPass);
}

이 블록은 gRPC 서비스의 이름(Random)과 지원하는 메서드들을 명시합니다. 또한, 각 상호작용에 필요한 메시지들을 지정합니다. 예를 들어, GetDate의 경우 클라이언트는 RequestDateTime 메시지를 보내고 DateTime 메시지를 받기를 기대합니다.

이 메시지들은 동일한 .proto 파일에 정의되어 있습니다.

// For random number

모든 .proto 파일은 C와 C++ 스타일의 주석을 지원합니다. 즉, // text/* text */ 형식의 주석을 사용할 수 있습니다.

message RandomParams {
    int64 Seed = 1;
    int64 Place = 2;
}

난수 생성기는 시드(seed) 값으로 시작하며, 이 값은 클라이언트가 지정하여 RandomParams 메시지를 통해 서버로 전송됩니다. Place 필드는 무작위로 생성된 정수 시퀀스에서 반환될 난수의 위치를 지정합니다.

message RandomInt {
    int64 Value = 1;
}

앞선 두 메시지는 GetRandom 메서드와 관련이 있습니다. RandomParams는 요청의 매개변수를 설정하는 데 사용되고, RandomInt는 서버가 생성한 난수를 저장하는 데 사용됩니다. 모든 메시지 필드는 int64 데이터 타입을 가집니다.

message DateTime {
    string Value = 1;
}

message RequestDateTime {
    string Value = 2;
}

위 두 메시지는 GetDate 메서드의 동작을 지원하기 위한 것입니다. RequestDateTime 메시지는 실질적인 데이터를 담고 있지 않은 더미 메시지입니다. 단지 클라이언트가 서버로 보내는 메시지가 필요할 뿐이며, Value 필드에는 어떤 종류의 정보든 저장할 수 있습니다. 서버가 반환하는 정보는 DateTime 메시지에 string 값으로 저장됩니다.

// For random password
message RequestPass {
    int64 Seed = 1;
    int64 Length = 8;
}

message RandomPass {
    string Password = 1;
}

마지막으로, 위 두 메시지는 GetRandomPass의 동작을 위한 것입니다.

요약하자면, IDL 파일은 다음을 수행합니다:

  • proto3를 사용함을 명시합니다.
  • 서비스의 이름이 Random임을 정의합니다.
  • 생성될 Go 패키지의 이름이 protoapi임을 명시합니다.
  • gRPC 서비스가 GetDate, GetRandom, GetRandomPass 세 가지 메서드를 지원함을 정의하고, 이 메서드 호출에서 교환될 메시지들의 이름을 정의합니다.
  • 데이터 교환에 사용될 여섯 가지 메시지의 형식을 정의합니다.

Go에서 IDL 파일 사용하기

다음 중요한 단계는 이 파일을 Go에서 사용할 수 있는 형식으로 변환하는 것입니다. protoapi.proto나 다른 .proto 파일을 처리하여 관련된 Go .pb.go 파일을 생성하기 위해 몇 가지 추가 도구를 다운로드해야 합니다. 프로토콜 버퍼 컴파일러 바이너리의 이름은 protoc입니다. macOS에서는 brew install protobuf 명령을 사용하여 protoc를 설치해야 합니다. 마찬가지로, Homebrew를 사용하여 protoc-gen-go-grpcprotoc-gen-go 패키지도 설치해야 합니다. 이 두 패키지는 Go와 관련이 있습니다.

Linux에서는 선호하는 패키지 관리자를 사용하여 protobuf를 설치하고, go install github.com/golang/protobuf/protoc-gen-go@latest 명령을 사용하여 protoc-gen-go를 설치해야 합니다. 마찬가지로, go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest를 실행하여 protoc-gen-go-grpc 실행 파일을 설치해야 합니다.

참고: Go 1.16부터는 모듈 모드에서 패키지를 빌드하고 설치하는 데 go install을 사용하는 것이 권장됩니다. go get의 사용은 더 이상 사용되지 않습니다. go install을 사용할 때는 최신 버전을 설치하기 위해 패키지 이름 뒤에 @latest를 추가하는 것을 잊지 마세요.

  • protoc
  • protoc-gen-go
  • protoc-gen-go-grpc

변환 과정은 다음 단계를 필요로 합니다:

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. \
--go-grpc_opt=paths=source_relative protoapi.proto

이 명령을 실행하면, GitHub 저장소의 루트 디렉토리에 protoapi_grpc.pb.goprotoapi.pb.go라는 두 개의 파일이 생성됩니다. protoapi.pb.go 소스 코드 파일에는 메시지가 포함되어 있고, protoapi_grpc.pb.go에는 서비스가 포함되어 있습니다.

protoapi_grpc.pb.go의 첫 열 줄은 다음과 같습니다:

// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package protoapi

앞서 논의했듯이, 패키지 이름은 protoapi입니다.

import (
	context "context"
	grpc "google.golang.org/grpc"

codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

이것은 import 블록입니다. context "context"가 있는 이유는 context가 예전에는 표준 Go 라이브러리의 일부가 아닌 외부 Go 패키지였기 때문입니다.

protoapi.pb.go의 첫 줄은 다음과 같습니다:

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.27.1
// 	protoc        v3.17.3
// source: protoapi.proto

package protoapi

protoapi_grpc.pb.goprotoapi.pb.go는 모두 protoapi Go 패키지의 일부이므로, 코드에서 한 번만 포함하면 됩니다.