๊ฐ๋ ์ ๋ฆฌ: ๐ฆProtobuf ์ ๐gRPC
๐ React ํ๋ก์ ํธ์์ Protocol Buffers์ gRPC ๊ฐ๋ ์ ๋ฆฌ ๐ฆ 1. Protocol Buffers (proto)๋? Protocol Buffers (protobuf)๋ Google์์ ๊ฐ๋ฐํ ๋ฐ์ดํฐ ์ง๋ ฌํ(Serialization) ํฌ๋งท์ ๋๋ค. ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํโฆ
๐ React ํ๋ก์ ํธ์์ Protocol Buffers์ gRPC ๊ฐ๋ ์ ๋ฆฌ
๐ฆ 1. Protocol Buffers (proto)๋?
**Protocol Buffers (protobuf)**๋ Google์์ ๊ฐ๋ฐํ ๋ฐ์ดํฐ ์ง๋ ฌํ(Serialization) ํฌ๋งท์ ๋๋ค.
-
๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๊ณ , ์ด๋ฅผ ์ด์ง(Binary) ํ์์ผ๋ก ๋น ๋ฅด๊ฒ ์ง๋ ฌํ/์ญ์ง๋ ฌํํ ์ ์๊ฒ ํด์ค๋๋ค.
-
JSON, XML ๊ฐ์ ํฌ๋งท๊ณผ ๋น์ทํ ์ญํ ์ ํ์ง๋ง, ๋ ๋น ๋ฅด๊ณ , ๋ ๊ฐ๋ณ๊ณ , ๋ ํจ์จ์ ํฉ๋๋ค.
โ ์ React ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋?
1๏ธโฃ ๋ฐ์ดํฐ ์ ์ก์ ํจ์จ์ฑ
- ์ด์ง ๋ฐ์ดํฐ๋ก ์ง๋ ฌํ๋์ด ์ ์ก ์๋๊ฐ ๋น ๋ฅด๊ณ ๋คํธ์ํฌ ํธ๋ํฝ์ ์ค์ ๋๋ค.
2๏ธโฃ ๋ช ํํ ๋ฐ์ดํฐ ๊ตฌ์กฐ (Type Safety)
- ์ ์ ํ์ ์ ๋ณด์ฅํ๊ณ , ํ์ ์ค๋ฅ๋ฅผ ์ปดํ์ผ ํ์์ ๊ฒ์ถํ ์ ์์ต๋๋ค.
3๏ธโฃ gRPC ํต์ ์ง์
proto๋ gRPC์ ํต์ฌ ๊ธฐ์ ๋ก, ํจ์จ์ ์ธ API ํต์ ์ ์ํด ํ์์ ์ ๋๋ค.
๐ ์ฌ์ฉ ์์
syntax = "proto3";
message User {
string id = 1;
string name = 2;
int32 age = 3;
}
import { User } from './message_pb';
const user = new User();
user.setId('123');
user.setName('Alice');
user.setAge(30);
const binaryData = user.serializeBinary();
const receivedUser = User.deserializeBinary(binaryData);
console.log(receivedUser.getName()); // "Alice"
๐ 2. gRPC๋?
gRPC๋ Google์์ ๊ฐ๋ฐํ ๊ณ ์ฑ๋ฅ, ๋ฒ์ฉ ์๊ฒฉ ํ๋ก์์ ํธ์ถ(Remote Procedure Call, RPC) ํ๋ ์์ํฌ์ ๋๋ค.
- HTTP/2 ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ฉฐ, ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ์๋ฒ-ํด๋ผ์ด์ธํธ ํต์ ์ ์ง์ํฉ๋๋ค.
โ ์ฃผ์ ํน์ง
1๏ธโฃ HTTP/2 ๊ธฐ๋ฐ
- ๋ฉํฐํ๋ ์ฑ, ํค๋ ์์ถ ๋ฑ์ ํตํด ๋ฎ์ ์ง์ฐ ์๊ฐ๊ณผ ๋น ๋ฅธ ์ ์ก ์๋ ์ ๊ณต.
2๏ธโฃ Protocol Buffers ์ฌ์ฉ
- ์ด์ง ๋ฐ์ดํฐ ์ง๋ ฌํ๋ก ๋ฐ์ดํฐ ํฌ๊ธฐ๋ฅผ ์ต์ํํ๊ณ , ์ฒ๋ฆฌ ์๋๋ฅผ ๋์ ๋๋ค.
3๏ธโฃ ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ ์ง์
- ๋จ์ํ ์์ฒญ-์๋ต๋ฟ ์๋๋ผ ์๋ฒ ์คํธ๋ฆฌ๋ฐ, ํด๋ผ์ด์ธํธ ์คํธ๋ฆฌ๋ฐ, ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ ๊ฐ๋ฅ.
๐ REST API์ gRPC ๋น๊ต
| ํน์ง | REST API | gRPC |
| ์ ์ก ํ๋กํ ์ฝ | HTTP/1.1 | HTTP/2 |
| ๋ฐ์ดํฐ ํฌ๋งท | JSON | Protocol Buffers (์ด์ง) |
| ์คํธ๋ฆฌ๋ฐ ์ง์ | ์ ํ์ | ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ ์ง์ |
| ์ฑ๋ฅ | ์ผ๋ฐ์ | ๋ ๋น ๋ฆ |
| ํ์ ๊ฒ์ฆ | ์์ | ๊ฐ๋ ฅํ ํ์ ์์คํ |
โ๏ธ gRPC ์ฌ์ฉ ์์
๐ Proto ํ์ผ
syntax = "proto3";
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
message UserRequest {
int32 id = 1;
}
message UserResponse {
int32 id = 1;
string name = 2;
int32 age = 3;
}
๐ฅ๏ธ ์๋ฒ ๊ตฌํ (Node.js)
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync('user.proto');
const userProto = grpc.loadPackageDefinition(packageDefinition).UserService;
const server = new grpc.Server();
server.addService(userProto.service, {
GetUser: (call, callback) => {
const user = { id: call.request.id, name: 'Alice', age: 30 };
callback(null, user);
},
});
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
server.start();
});
๐ ํด๋ผ์ด์ธํธ ๊ตฌํ (React)
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync('user.proto');
const UserService = grpc.loadPackageDefinition(packageDefinition).UserService;
const client = new UserService('localhost:50051', grpc.credentials.createInsecure());
client.GetUser({ id: 1 }, (error, response) => {
if (!error) {
console.log(response); // { id: 1, name: 'Alice', age: 30 }
}
});
๐ก ์์ฝ
-
Protocol Buffers: ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ง๋ ฌํ ํฌ๋งท
-
gRPC: HTTP/2 ๊ธฐ๋ฐ์ ๊ณ ์ฑ๋ฅ ์๊ฒฉ ํ๋ก์์ ํธ์ถ ํ๋ ์์ํฌ
-
React ํ๋ก์ ํธ์์ ์ฑ๋ฅ ์ต์ ํ, ํ์ ์์ ์ฑ, ์ค์๊ฐ ํต์ ์ด ํ์ํ๋ค๋ฉด ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ๋ ์ ์์ต๋๋ค.
๐ ์ฑ๋ฅ + ํ์ฅ์ฑ + ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๊ฐ ํ์ํ ํ๋ก์ ํธ๋ผ๋ฉด gRPC์ Protocol Buffers๋ฅผ ๊ณ ๋ คํด๋ณด์ธ์!