FE ๊ด€์ ์—์„œ grpc ์ฐ๋จนํ•˜๊ธฐ (feat. REST api ์™€์˜ ๋น„๊ต)

 

๐Ÿ’ก gRPC์™€ Rest api์˜ ์ฐจ์ด์ ์„ ์ •๋ฆฌํ•˜๊ณ  ์žฅ๋‹จ์ ์„ ํŒŒ์•…ํ•˜์—ฌ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ŠคํŠธ๋ ˆ์Šค ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์กฐ์‚ฌํ•˜๋‹ค๊ฐ€ ํŠน์ • ํˆด๋“ค๋งŒ gRPC๋ฅผ ์ง€์›ํ•˜๊ณ , gRPC๋ฅผ ์‚ฌ์šฉ ์ค‘์ธ ์ฝ”๋“œ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ ๊ฑฐ์˜ Go, Kotiin ๊ธฐ๋ฐ˜ ์ฝ”๋“œ๋“ค ๋ฐ–์— ์—†๊ธธ๋ž˜ gRPC์™€ Rest api์˜ ์ฐจ์ด์ ์ด ๋ฌด์—‡์ด๊ณ  ์–ธ์ œ ๋ฌด์–ผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ / JS๋ฅผ ํ†ตํ•ด ์ž์ฃผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๊ฐ€ ์žˆ์„ ์ง€ ๊ถ๊ธˆํ•ด์„œ ์กฐ์‚ฌํ•ด ๋ด…๋‹ˆ๋‹ค.

Rest api๋Š” ๊ธฐ์กด์— ๋งŽ์ด ์‚ฌ์šฉํ•ด๋ณด์…จ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„ ์„ค๋ช… ์—†์ด ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

 

gRPC๋ž€?

grpc๋ž€ ๊ตฌ๊ธ€์—์„œ ๊ฐœ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค ์›๊ฒฉ ํ”„๋กœ์‹œ์ € ํ˜ธ์ถœ(RPC) ์‹œ์Šคํ…œ์ด๋ฉฐ, ์ „์†ก์„ ์œ„ํ•ด HTTP/2 ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ ์–ธ์–ด๋กœ ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

client - server side๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, server side์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ์„œ๋ฒ„๋ฅผ ๊ตฌ๋™ํ•˜์—ฌ client์˜ ์š”์ฒญ์„ ๋ฐ›๊ณ  client side์—์„œ๋Š” stub๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : https://grpc.io/docs/what-is-grpc/introduction/

 

gRPC ์‚ฌ์šฉ

gRPC๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด JS ๊ธฐ๋ฐ˜ ์›น ํด๋ผ์ด์–ธํŠธ์—์„œ ์–ด๋–ค ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

1. gRPC ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

  • protobuf: binary serialization format
  • grpc : gRPC communication
  • grpc-tools : .proto ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ client, server stub๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์„œ๋ธŒ ํˆด
โ“ stub๋ž€ protobuf๋กœ ์ •์˜๋œ ์š”์ฒญ / ์‘๋‹ต ๋ฉ”์‹œ์ง€๋“ค๋กœ๋ถ€ํ„ฐ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” client ์ธก ์ธ์Šคํ„ด์Šค ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ์šฐ๋ฆฌ๋Š” low-level์˜ ์›๋ฆฌ๋ฅผ ์•Œ ํ•„์š” ์—†์ด ๋ณด๋‹ค ๋†’์€ ๋ ˆ๋ฒจ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•ด ํ†ต์‹ ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

2. proto ํŒŒ์ผ ์ž‘์„ฑ

.proto ํŒŒ์ผ์— IDL(Interface Definition Language)๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•ด ์ค๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด ํ•ด๋‹น ํŒŒ์ผ์ด api ์ •์˜์„œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.  

syntax = "proto3";

service MyService {
  rpc MyMethod(MyRequest) returns (MyResponse) {}
}

message MyRequest {
  string message = 1;
}

message MyResponse {
  string message = 1;
}

 

 

3. (์„ ํƒ) gRPC Client ์ฝ”๋“œ ์ƒ์„ฑ

protoc cli ๋ฅผ ์ด์šฉํ•˜์—ฌ js๋กœ ๋œ gRPC ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ ์šฐ๋ฆฌ๊ฐ€ JS ์ฝ”๋“œ ์ƒ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” stub๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

4. JS ํ†ต์‹  ์ฝ”๋“œ ์ž‘์„ฑ

const grpc = require('grpc');
const myService = require('./my_service_pb'); // 3๋ฒˆ์—์„œ ๋งŒ๋“  ํŒŒ์ผ

/* ์ด๋ ‡๊ฒŒ ์ง์ ‘ ์ฝ”๋“œ ์ƒ์—์„œ stub๋ฅผ ์ƒ์„ฑํ•ด๋„ ๋จ
const packageDefinition = protoLoader.loadSync('path/to/your.proto');
const myService = grpc.loadPackageDefinition(packageDefinition).myService;
*/

// Create a client stub
const myServiceClient = new myService.MyServiceClient('localhost:50051', grpc.credentials.createInsecure());

// Invoke a remote method on the server
const request = new myService.MyRequest();
request.setMessage('Hello from gRPC client!');

myServiceClient.myMethod(request, (error, response) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Response:', response.getMessage());
  }
});

 

gRPC vs REST API

  gRPC REST API
performance binary serialization์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ž‘์€ payload๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋น ๋ฅธ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.  
+) HTTP/2๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์ข‹์€ ์„ฑ๋Šฅ์„ ๋‚ธ๋‹ค. text serialization (e.g. JSON) ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋น„๊ต์  ๋Š๋ฆฌ๋‹ค.  
interface stub๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๊ฒŒ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. fetch, axios ์™€ ๊ฐ™์€ web api๋กœ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
simplicity HTTP/2 ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  protobuf ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋Ÿฌ๋‹ ์ปค๋ธŒ๊ฐ€ ์ข€ ์žˆ๋‹ค. HTTP์˜ ํ‘œ์ค€ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์‰ฝ๋‹ค.
debugging grpc-web-devtools ๊ฐ™์€ ์ต์Šคํ…์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ๋„คํŠธ์›Œํฌ ์ƒ์˜ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋กœ ๋ณ„๋„ ์ฒ˜๋ฆฌ ์—†์ด ์š”์ฒญ, ์‘๋‹ต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
interoperability ํŠน์ • ์–ธ์–ด๋“ค์„ ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์„ค์ •์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ์ง€์›ํ•œ๋‹ค. ํ”Œ๋žซํผ์ด๋‚˜ ์–ธ์–ด์— ๊ธฐ๋ฐ˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.
streaming ์–‘๋ฐฉํ–ฅ streaming์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜์ง€๋งŒ gRPC-web์—์„œ๋Š” ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ์ง€์›ํ•˜์ง€ ์•Š๊ณ  ๋ณ„๋„์˜ ํˆด์„ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค.
generate code o with tools

gRPC๋Š” ๋†’์€ ํผํฌ๋จผ์Šค๋ฅผ ๋‚ด๋ฉฐ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค๋Š” ์ ์—์„œ ์˜๋ฏธ๊ฐ€ ์žˆ์ง€๋งŒ, ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šฐ๋ฉฐ ๊ธฐ์กด ์‹œ์Šคํ…œ๊ณผ ์ƒํ˜ธ์šด์šฉ์ ์ด๊ณ  ์ด๋ฏธ REST API์— ์ต์ˆ™ํ•œ ํŒ€์ด๋ผ๋ฉด REST API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ gRPC๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋””๋ฒ„๊น… ๋ฐ ๊ฐœ๋ฐœ ์‹œ ๋„ˆ๋ฌด ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ + ํˆด์— ์˜์กดํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๋„ ๋‹จ์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

Appendix

https://grpc.io/docs/what-is-grpc/introduction/

https://bourbonkk.tistory.com/109

https://chacha95.github.io/2020-06-16-gRPC2/

https://learn.microsoft.com/ko-kr/aspnet/core/grpc/comparison?view=aspnetcore-7.0

Chatgpt

 

 

 

 ๋ถ€์ •ํ™•ํ•œ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! 

 ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š” :) 

๋ฐ˜์‘ํ˜•