입력 (.proto 스키마)

출력 (Go)

이 도구의 역할

Go는 protobuf의 네이티브 언어입니다 — 프로덕션의 gRPC 서비스 대부분이 Go로 작성되어 있죠. 보통은 protoc-gen-gobuf.proto에서 Go를 생성하는데, 그러려면 툴체인을 설치하고, 제너레이터를 설정하고, 빌드 단계를 돌려야 합니다. 이 변환기는 같은 일을 브라우저에서 처리합니다 — 붙여넣고, 복사해서, 레포에 떨어뜨리세요.

타입 매핑은 protoc-gen-go가 내보내는 결과를 따릅니다: stringstring, boolbool, bytes[]byte, 정수 타입들은 각각 int32/int64/uint32/uint64로 매핑되고(JavaScript처럼 정밀도 손실은 없습니다), doublefloat64, floatfloat32입니다. 단수 메시지 필드는 포인터이며(공식 Go protobuf 바인딩 관례에 맞춰서), repeated T[]T, map<K, V>map[K]V가 됩니다.

필드명은 Go의 정석인 PascalCase 처리를 받고, 자주 쓰는 약어는 Go 코드 리뷰 스타일에 따라 대문자로 바뀝니다(order_idOrderID, api_urlAPIURL). 각 필드에는 바로 붙여 쓸 수 있는 struct 태그가 달립니다: 와이어 포맷용 protobuf:"varint,3,opt,name=status,proto3"와 JSON 마샬링용 json:"status,omitempty". 변환은 로컬에서 일어납니다 — 당신의 .proto는 브라우저를 떠나지 않습니다. 프로덕션 코드라면 메서드, 디스크립터, 리플렉션 배관을 얻기 위해 결국 진짜 코드젠을 돌려야 하지만, 스케치・리뷰・일회성 스크립트라면 이쪽이 빠릅니다.

사용 방법

세 단계입니다. 출력은 표준 라이브러리만으로도 그대로 컴파일되는, 붙여넣기 즉시 사용 가능한 Go 코드입니다.

1

.proto 스키마 붙여넣기

왼쪽 에디터에 스키마를 떨어뜨리세요. 상단의 syntax = "proto3";은 있어도 없어도 됩니다. 파서는 중첩된 message 블록, enum 선언, oneof, map<K, V>, 필드 옵션을 처리합니다. import는 인식되지만 건너뜁니다.

필드명은 snake_case에서 PascalCase로 자동 변환됩니다. 변환기는 자주 쓰는 약어 접미사(IdID, UrlURL)를 대문자로 바꿔주므로 출력은 revive / golint에서 군말 없이 통과됩니다.

2

출력 읽기

오른쪽: 메시지마다 type X struct 하나, enum마다 type X int32const 블록이 있는 Go 코드입니다. 상단의 package proto는 자리표시자이니 실제 패키지명으로 바꾸세요.

3

프로젝트에 연결

파일을 프로젝트에 떨어뜨리고, package 선언을 고치고, import 하세요. 진짜 gRPC 코드라면 marshal/unmarshal 메서드를 얻기 위해 결국 protoc-gen-go를 돌리고 싶을 겁니다. 이 출력은 타입 있는 JSON 처리, struct 스케치, 리뷰용입니다 — protobuf 와이어 포맷 메서드는 여기서 생성되지 않습니다.

실제로 시간이 절약되는 순간

기존 .proto에서 Go 서비스 스케치하기

다른 팀의 Protobuf 메시지를 소비하는 Go 서비스를 짜는 중. 핸들러 시그니처와 JSON 응답을 위해 struct 모양이 필요한데 풀 코드젠 파이프라인을 세팅할 정도는 아닙니다. 붙여넣고 types.go에 떨어뜨리면 타입이 잡힙니다.

Go 소비자용 Protobuf API 변경 리뷰

백엔드 동료가 메시지에 필드를 추가했습니다. 새 .proto를 붙여넣고, Go 출력을 현재 types.go와 diff 떠서 핵심만 짚는 리뷰를 남기세요. 변경 사항을 보려고 툴체인을 띄우는 것보다 빠릅니다.

언어 간 점검

Go와 TypeScript 클라이언트 양쪽이 소비하는 .proto가 있습니다. Protobuf에서 TypeScript 변환기와 나란히 띄워놓고, JSON 인코딩 후 두 언어가 호환되는 필드명과 타입을 보게 될지 확인하세요.

일회성 통합 스크립트

gRPC-gateway 엔드포인트를 두드리는 50줄짜리 Go 스크립트를 쓰는 중. 스크립트 하나 때문에 protoc, buf, 제너레이터 설정을 세팅하는 건 과합니다. 여기서 struct를 생성해 떨어뜨리고 스크립트를 배포하세요.

자주 묻는 질문

protoc-gen-go를 대체할 수 있나요?

아닙니다. protoc-gen-go는 바이너리 marshal/unmarshal 메서드, 파일 디스크립터, 진짜 gRPC에 필요한 리플렉션 배관을 내보냅니다. 이 변환기는 struct 모양과 태그만 내보냅니다. 진짜 gRPC 서비스를 작성한다면 공식 코드젠을 돌리세요. JSON 응답, 손수 짠 스크립트, 스케치를 위한 타입만 필요하다면 — 이쪽이 빠릅니다.

메시지 타입 필드는 왜 포인터인가요?

protoc-gen-go가 proto3 메시지 필드에서 하는 방식 그대로입니다 — 포인터로 두면 zero value가 nil이 되어 비어있지만 존재하는 메시지와 구분할 수 있습니다. 스칼라 필드는 zero value(빈 문자열, 0, false) 자체가 유효하므로 값 타입으로 둡니다. 어떤 이유로든 비포인터를 선호한다면 출력에서 별표(asterisk)를 find-replace 하세요.

enum은 어떻게 출력되나요?

protoc-gen-go 관례에 맞춰 Go int32 typedef과 const 블록으로 나옵니다. 각 enum 값은 그 타입의 PascalCase Go 상수가 됩니다. 숫자 할당은 .proto에서 그대로 가져옵니다.

protobuf struct 태그는요?

각 필드에는 와이어 타입(varint, fixed32, fixed64, bytes), 필드 번호, 레이블(opt/rep), 이름, proto3 표시가 들어간 protobuf:"..." 태그가 붙습니다. 그리고 원래 snake_case 이름을 쓰는 json:"name,omitempty" 태그도요. map<K, V> 태그는 단순화되어 있으니 와이어 포맷 호환성을 엄밀히 맞추려면 진짜 코드젠을 돌리세요.

필드명은 어떻게 변환되나요?

snake_casePascalCase이며, 자주 쓰는 약어 접미사는 대문자로 바뀝니다: order_idOrderID, api_urlAPIURL, data_jsonDataJSON. Go 코드 리뷰 스타일 관례와 일치하므로 출력은 수동 정리 없이 lint를 통과합니다.

스키마가 다른 .proto를 import 한다면?

import 문은 인식되지만 건너뜁니다 — 파일 간 메시지 타입은 잎 이름(foo.BarBar)으로 렌더링되며, 같은 패키지 안에 그 타입이 존재하지 않으면 Go가 해석하지 못합니다. import된 메시지를 인라인으로 같이 붙여넣거나, 출력에서 참조를 손봐야 합니다.

관련 도구

Protobuf, JSON, Go를 다룬다면 이 도구들과 잘 어울립니다: