개발을 하던 와중에 grpc를 통해서 클라이언트에서 이미지를 업로드하면 HTTP API를 요청을 처리하는 서버에서 이미지 파일을 받고 또 다시 이미지 파일을 다른 service에 보내야 하는 경우가 생겼다.
사실 프론트에서 바로 해당 서비스로 바로 업로드를 하거나 최종에는 스토리지에 저장을 하는 것이므로 바로 스토리지에 올려도 되지만 실시간으로 작성하는 게시판의 기능을 위한 서비스고 다른 아키텍처와의 트레이드 오프가 체감이 안되서 그냥 경험삼아 위의 루트로 업로드하는 방식을 택했다.
그럼 본론으로
syntax = "proto3";
package pb;
import "article.proto";
service image_task {
rpc UploadImage (ImageUploadRequest) returns (ImageUploadResponse){}
}
message ImageUploadRequest {
bytes image = 1; // byte data
}
message ImageUploadResponse {
ReplyType reply = 1;
string url = 2;
}
위와 같이 protobuf를 설정한다. image 데이터를 byte로 변환해서 보낸다.
func (h *Handler) UploadImage(c echo.Context) error {
file, err := c.FormFile("file") // file : "file" parsing
if err != nil {
return err
}
src, err := file.Open() // file api open
if err != nil {
return err
}
defer src.Close()
buffer := make([]byte, file.Size) // file size buf define
src.Read(buffer) // file read
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := h.imageConn.UploadImage(ctx, &pb.ImageUploadRequest{Image:buffer})
if err != nil {
return c.JSON(http.StatusInternalServerError, nil)
}
return c.JSON(http.StatusCreated, r.Url)
}
Echo 프레임워크를 이용하여 HTTP API 요청을 처리하였다. 이미지를 byte로 읽은 다음에 grpc를 통해서 upload를 담당하는 service로 보내고 그 서비스는 스토리지에 업로드하고 url을 돌려준다.
grpc를 통한 file transfer에 관한 예제와 실험이 있는 글
https://ops.tips/blog/sending-files-via-grpc/
'개발일지 > go' 카테고리의 다른 글
GORM (2) - CRUD (0) | 2020.04.24 |
---|---|
GORM (1) - Getting Started (0) | 2020.04.23 |
gRPC - Multiplexing, Metadata, Load Balancing and Compression (0) | 2020.04.13 |
gRPC - Context and Error Handling (0) | 2020.04.11 |
gRPC - Interceptor (0) | 2020.03.31 |