go-grpc-gateway(1) proto 작성해보기

2021. 8. 2. 03:26golang/golang-webServer

go-grpc-gateway

golang을 활용해서 서버를 만들다가 go 서버간의 통신을 grpc를 사용하도록 확정했다. 하지만 몇가지 문제점이 있었다. 

 

문제점

 

1. Client 친구가 rest로 모를뿐더러 grpc를 배우기엔 부담스러워 보였다.

친구가 처음 프로젝트를 진행하다보니 모르는 부분이 많아 최대한 간단히 rest로 클라이언트와 서버는 통신하고 싶었다. 

 

2. 1번의 문제가 전혀상관 없이 현재 클라이언트와 서버는 grpc 통신을 할 수 없다. 

브라우저는 현재 서버와 grpc 통신을 할 수 없다. 

 

 

-> 이러한 문제를 해결하기 위해 클라이어트와 서버 사이에 reverse proxy 서버를 두어 proto 작성한 api에 맞게 요청을 받을 수 있었다. 

또한 클라이언트는 서버의 ip를 모르고 reverse proxy와 통신해서 보안성을 챙길 수 있었다. 

 

이 글에서는 해당 주소의 git 프로젝트를 참고해 만들겠습니다.

 

해당 git 프로젝트를 활용해서 느낄 수 있었던 좋았던 점은

 

1. swagger를 간편하게 제공하고 있습니다. 

 

2. 또한 post get 등의 어떤 메소드들도 사용할 수 있고 git ReadMe가 정말 잘 정리되어있어서 편하게 볼 수 있었습니다. 

 

 

그럼 실제로 서버를 어떻게 만들면 되는지 간단하게 작성해보겠습니다.

 

 

필요한 외부 라이브러리 설치

go install \
    github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
    github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
    google.golang.org/protobuf/cmd/protoc-gen-go \
    google.golang.org/grpc/cmd/protoc-gen-go-grpc

 

proto 작성하기

proto는 grpc 사이에 통신하기 위한 규약이라고 생각하면됩니다. grpc는 통신할 때 proto 방식으로 데이터를 직렬화하여 json 보다 훨씨 더 가볍게 전송할 수 있다.

 

파일의 확장자는 .proto입니다.

syntax = "proto3";

package daldang;

option go_package = "proto/daldang";

import "google/api/annotations.proto";

syntax - proto version3를 사용할 수 있게 해준다. proto3와 proto2의 차이점은 몇가지의 옵션과 언어 지원 차이가 있습니다. 

 

proto2의 경우에는 optional, required가 있는데 뭐 평소에 많이 쓰는 키워드니 간단히 정리하자면 

 

optional의 경우 있어도 없어도 되는 값

required의 경우에는 요청에 필수로 있어야 하는 값

 

go_package의 값을 통해 go 파일 안에서 접근할 수 있다.

 

import google/api/annotations.proto를 추가함으로써 rest요청을 받아서 처리해줄 수 있다. 

 

proto 작성

우선 앞서 전송할 때 json보다 훨씬 가볍게 직렬화 할 수 있다. 어떻게 압축하길래 가볍게 압축할 수 있을까? 

일반적으로 proto는 아래와 같은 형식으로 구성되어 있다. 

message Test1 {
  int a = 1;
  string b = 2;
}

8bit를 type과 flag tag를 사용해서 표현해서 가볍게 만들 수 있습니다. 

 

flagTag는 5bit type은 3bit로 만들어서 총 1byte로 타입과 필드를 구별 할 수 있게됩니다.

 

 

rpc 부분을 만들어 보겠습니다. 

 

우선 폴더 구조는 아래와 같이 만들어주겠습니다

annotations.proto, http.proto는 해당 주소에서 코드를 가져올 수 있습니다. 

 

이름.proto 

syntax = "proto3";

package hoony;

option go_package = "proto/hoony";

import "google/api/annotations.proto";

 

message와 service 만들어보기

 

우선 알아보기전에 작성 convention을 알아보자~~ 

 

file formatting

 

1. 길이를 80자로 제한

 

2. 2개의 들여쓰기를 사용한다.

 

3. 문자열에 따옴표 사용을 선호한다.

 

필드, 서브, 메시지

 

1. message 및 service는 카멜케이스를 사용한다. 

 

2. 필드의 이름은 스네이크 케이스를 사용한다. 

 

message의 데이터 타입

 

각 언어별로 어떤 타입에 대응하는지 확인할 수 있습니다.

 

코드 작성

syntax = "proto3";

package hoony;

option go_package = "proto/hoony";

import "google/api/annotations.proto"; 


message MessageRequest{
    string requester_id = 1;
    string content = 2;
    string receiver_id = 3;
}

message Status{
    int64 status_code = 1;
    int64 status_message = 2;
}

message MessageResponse{
    Status status = 1;
    string content = 2;
    repeated string receiver_id = 3;
}

 

message 작성된 정보를 보면 타입과 해당 타입을 구분할 수 있는 숫자 등이 있습니다. repeated는 배열인 필드를 의미합니다. 

 

Service와 rpc 만들기

코드

service ChattingServer{
    rpc SendMessage(MessageRequest) returns(MessageResponse){
        option (google.api.http) = {
            post: "/message"
        };
    }

    rpc ReceiveUsers(UserRequest) returns(UserResponse){
        option (google.api.http) = {
            get: "/user"
        };
    }
}

각 요청에 대해서 함수를 만들 수 있고 rest API를 지정해서 get, post, delete, Put 등을 설정해서 클라이언트와 통신할 수 있습니다.

 

그리고 이런 proto를 compile해서 gw를 실행시키는데 필요한 go 파일을 만들어보겠습니다.

 

protoc -I ./proto --grpc-gateway_out ./proto \    
    --grpc-gateway_opt logtostderr=true \
    --grpc-gateway_opt paths=source_relative \
    proto/hoony.proto

터미널의 위의 명령어를 작성 후 hoony.pw.gw.go라는 파일이 나오는 것을 확인할 수 있습니다.

'golang > golang-webServer' 카테고리의 다른 글

go-grpc-gateway(2) go code 작성하기  (0) 2021.08.03
golang http Server Router 설정하기  (0) 2020.04.16
golang http server 시작하기  (0) 2020.04.16