본문 바로가기
Backend2026년 4월 23일9분 읽기

tonic·gRPC vs Connect-Web — 2026 RPC 표준 선택

YS
김영삼
조회 1
tonic·gRPC vs Connect-Web — 2026 RPC 표준 선택

핵심 요약

마이크로서비스 RPC의 사실상 표준은 gRPC. 그러나 브라우저에서 직접 호출하려면 envoy proxy 같은 추가 레이어 필요. Connect는 이 한계를 해결한 신규 프로토콜 — gRPC 호환 + 브라우저 직접 호출.

  • gRPC: HTTP/2 + Protocol Buffers, 가장 많은 언어 지원
  • Connect: gRPC + REST + 브라우저 호환을 한 프로토콜로
  • 둘 다 .proto 파일이 single source of truth

1. .proto 파일 — 공통 기반

// user.proto
syntax = "proto3";

package user.v1;

service UserService {
  rpc GetUser(GetUserRequest) returns (User);
  rpc CreateUser(CreateUserRequest) returns (User);
  rpc StreamEvents(StreamEventsRequest) returns (stream Event);
}

message User {
  string id = 1;
  string name = 2;
  string email = 3;
}

message GetUserRequest {
  string id = 1;
}

2. gRPC 서버 — Rust tonic

use tonic::{transport::Server, Request, Response, Status};
use user::user_service_server::{UserService, UserServiceServer};
use user::{GetUserRequest, User};

pub mod user { tonic::include_proto!("user.v1"); }

pub struct UserSvc;

#[tonic::async_trait]
impl UserService for UserSvc {
    async fn get_user(&self, req: Request<GetUserRequest>) -> Result<Response<User>, Status> {
        let id = req.into_inner().id;
        Ok(Response::new(User {
            id,
            name: "Alice".into(),
            email: "alice@example.com".into(),
        }))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    Server::builder()
        .add_service(UserServiceServer::new(UserSvc))
        .serve("[::1]:50051".parse()?)
        .await?;
    Ok(())
}

3. gRPC 클라이언트 — Go

conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
client := userpb.NewUserServiceClient(conn)

user, err := client.GetUser(ctx, &userpb.GetUserRequest{Id: "abc"})

4. Connect-Web — 브라우저 직접 호출

Connect는 .proto는 동일, 그러나 HTTP/1.1 또는 HTTP/2로 작동. 브라우저에서 fetch로 직접 호출.

// generated client
import { createPromiseClient } from "@connectrpc/connect"
import { createConnectTransport } from "@connectrpc/connect-web"
import { UserService } from "./gen/user_connect"

const transport = createConnectTransport({
  baseUrl: "https://api.example.com",
})
const client = createPromiseClient(UserService, transport)

const user = await client.getUser({ id: "abc" })
// 타입 자동, 응답 도 자동

envoy proxy 없이 브라우저 직접 호출. JSON 또는 protobuf 둘 다 가능.

5. Connect 서버 — Go

import (
  "connectrpc.com/connect"
  "net/http"
)

func (s *UserSvc) GetUser(ctx context.Context, req *connect.Request[userpb.GetUserRequest]) (*connect.Response[userpb.User], error) {
  return connect.NewResponse(&userpb.User{
    Id: req.Msg.Id,
    Name: "Alice",
  }), nil
}

mux := http.NewServeMux()
mux.Handle(userv1connect.NewUserServiceHandler(&UserSvc{}))
http.ListenAndServe(":8080", h2c.NewHandler(mux, &http2.Server{}))

6. 비교

항목gRPCConnect
전송HTTP/2 onlyHTTP/1.1·HTTP/2 둘 다
브라우저 호환gRPC-Web 필요 + envoy proxy네이티브
encodingprotobuf 기본protobuf·JSON 둘 다
스트리밍풀 (양방향)서버 → 클라이언트 (단방향)
언어 지원13+5 (Go·TS·Swift·Kotlin·Python)
성능최고약간 낮음 (HTTP/1.1 시)

7. 의사결정

gRPC 권장

  • 마이크로서비스 간 통신 (서버 ↔ 서버)
  • 대량 스트리밍 필요
  • 최고 성능
  • 다양한 언어 지원 필요

Connect 권장

  • 브라우저 ↔ 서버 직접
  • JSON·protobuf 둘 다 필요 (디버깅 용이)
  • envoy 같은 proxy 없이 단순 배포
  • 주로 Go·TypeScript 환경

8. 하이브리드 — 가장 흔한 패턴

// 단일 .proto에서:
// - 마이크로서비스 간: gRPC (tonic·grpc-go)
// - 브라우저: Connect (connect-web)
// - REST 호환 클라이언트: Connect의 JSON 모드

// 같은 서버가 Connect로 마운트되어 모두 처리

9. 인증·관측성

gRPC 인터셉터

fn auth_interceptor(mut req: Request<()>) -> Result<Request<()>, Status> {
    let token = req.metadata().get("authorization")
        .ok_or(Status::unauthenticated("no token"))?;
    // verify
    Ok(req)
}

Connect 미들웨어

const authInterceptor: Interceptor = (next) => async (req) => {
  req.header.set("authorization", `Bearer ${token}`)
  return next(req)
}

10. OpenAPI vs gRPC vs Connect

표준강점약점
REST + OpenAPI가장 광범위 호환스키마 검증 약함
GraphQLover-fetching 방지복잡함
gRPC성능·스트리밍브라우저 직접 호출 어려움
ConnectgRPC + 브라우저지원 언어 적음

자주 묻는 질문

gRPC-Web으로 충분?가능. 단 envoy proxy 필요. Connect는 그것 없이 동작.

tRPC와 차이?tRPC는 TypeScript only. Connect는 다언어. 단일 팀+TS면 tRPC, 다언어면 Connect.

스트리밍 양방향 필요하면?gRPC만 가능. Connect는 server-streaming만 (브라우저 제약).

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록