PHP Academy · 강의

서비스 통신: REST와 gRPC

서비스를 동기식으로 효율적으로 연결합니다.

레슨 2/413개 단계

서비스 통신: REST와 gRPC은(는) CoddyKit의 무료 PHP Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 PHP Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. PHP Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

REST 및 gRPC

서비스는 동기적으로 통신해야 합니다. 요청을 보내면 응답이 돌아옵니다. 대표적인 두 가지 선택지는 HTTP/JSON 기반 REST와 HTTP/2 + Protobuf 기반 gRPC입니다. 두 방식은 서로 다른 것을 최적화합니다. REST는 도달 범위와 사람이 다루기 쉬운 특성을, gRPC는 속도와 엄격한 계약을 중시합니다.

이 강의에서는 PHP 관점에서 두 방식을 살펴보고 각각 언제 선택해야 하는지 알아봅니다.

REST: 공용어

REST는 URL을 통해 리소스를 모델링하고 HTTP 동사와 상태 코드로 의미를 표현합니다. 장점은 보편적인 도구, 캐시 가능성, curl을 이용한 디버깅, 별도 클라이언트가 필요 없다는 점입니다. 단점은 장황한 JSON, 강제되는 스키마의 부재, 요청과 응답만 지원한다는 점입니다.

공개 API와 브라우저를 대상으로 하는 엔드포인트에는 REST가 거의 항상 적합합니다.

REST 서비스 호출

PSR-18 HTTP 클라이언트(여기서는 Guzzle)를 사용하십시오. 항상 연결 시간 제한과 요청 시간 제한을 설정해야 합니다. 느린 상대 서비스에 제한 없이 호출하면 PHP-FPM 작업자가 모두 소진되고 장애가 연쇄적으로 확산될 수 있습니다.

<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;

$http = new Client([
    'base_uri'        => 'http://customers-svc/',
    'connect_timeout' => 1.0,  // never block forever on connect
    'timeout'         => 3.0,  // total request budget
    'http_errors'     => false,
]);

$res = $http->get('customers/42', ['headers' => ['Accept' => 'application/json']]);
if ($res->getStatusCode() === 200) {
    $customer = json_decode((string) $res->getBody(), true);
    echo $customer['email'] . "\n";
}

상태 코드는 계약입니다

서비스 간 REST에서 HTTP 상태 코드가 곧 오류 프로토콜입니다. 다음과 같이 신중하게 처리하십시오:

  • 2xx는 성공, 4xx는 호출자의 잘못이므로 무작정 재시도하지 말고, 5xx/시간 제한 초과는 재시도할 수 있습니다.
  • 충돌에는 409, 검증 오류에는 422, 속도 제한에는 429를 사용하고 Retry-After를 준수하십시오.

400을 재시도하면 호출만 낭비하지만, 503을 지수 백오프로 재시도하는 것은 올바릅니다.

<?php
function isRetryable(int $status): bool {
    return $status === 0          // timeout/connection error
        || $status === 429
        || ($status >= 500 && $status !== 501);
}
var_dump(isRetryable(503)); // true
var_dump(isRetryable(400)); // false

gRPC: 계약 우선 및 고속

gRPC는 Protocol Buffers를 사용합니다. .proto 파일에 서비스와 메시지를 정의한 다음 강한 형식의 클라이언트/서버 스텁을 생성합니다. HTTP/2에서 바이너리 Protobuf를 사용하므로 JSON보다 훨씬 작고 지연 시간이 짧으며, 스트리밍도 지원합니다.

syntax = "proto3";
package customers;

service Customers {
  rpc GetCustomer (GetCustomerRequest) returns (Customer);
}

message GetCustomerRequest { string id = 1; }
message Customer {
  string id = 1;
  string email = 2;
  int32  loyalty_points = 3;
}

PHP 스텁 생성

gRPC PHP 확장과 protoc 플러그인을 설치한 다음 .proto에서 클라이언트 클래스를 생성하십시오. PHP는 ext-grpc를 통해 완전한 기능을 갖춘 gRPC 클라이언트로 동작할 수 있지만, 네이티브 PHP gRPC 서버를 실행하려면 일반적으로 Roadrunner 또는 Swoole이 필요합니다.

pecl install grpc
composer require grpc/grpc google/protobuf

protoc --proto_path=. \
  --php_out=./generated \
  --grpc_out=./generated \
  --plugin=protoc-gen-grpc=$(which grpc_php_plugin) \
  customers.proto

gRPC 클라이언트 호출

생성된 스텁은 형식이 지정된 요청과 응답을 제공합니다. gRPC 호출은 메시지와 status 객체를 반환하므로, 응답을 신뢰하기 전에 항상 상태 코드를 확인해야 합니다.

<?php
require 'vendor/autoload.php';
use Customers\CustomersClient;
use Customers\GetCustomerRequest;
use Grpc\ChannelCredentials;

$client = new CustomersClient('customers-svc:50051', [
    'credentials' => ChannelCredentials::createInsecure(),
]);

$req = (new GetCustomerRequest())->setId('42');
[$reply, $status] = $client->GetCustomer($req)->wait();

if ($status->code === \Grpc\STATUS_OK) {
    echo $reply->getEmail(), "\n";
} else {
    fwrite(STDERR, "gRPC error: {$status->details}\n");
}

스키마 진화

다음 규칙을 지키면 Protobuf는 순방향/역방향 호환성을 지원하도록 설계되어 있습니다:

  • 필드 번호를 절대 재사용하거나 변경하지 마십시오. 새 필드는 새 번호로 추가합니다.
  • 삭제한 필드는 reserved로 표시하여 해당 번호를 재사용할 수 없게 합니다.
  • 이전 클라이언트는 알 수 없는 필드를 무시하고, 누락된 필드에는 타입의 기본값이 적용됩니다.

JSON/REST는 이런 기능을 자동으로 제공하지 않습니다. 관례로 호환성을 관리하고, 이상적으로는 계약 테스트와 함께 공유 OpenAPI 스키마를 사용해야 합니다.

message Customer {
  string id = 1;
  string email = 2;
  reserved 3;            // old 'loyalty_points', never reuse 3
  reserved "loyalty_points";
  string display_name = 4; // new field, safe additive change
}

스트리밍

gRPC는 네 가지 호출 유형을 지원하며, REST가 기본적으로 지원하는 것은 첫 번째 유형뿐입니다:

  • 단항 — 요청 하나와 응답 하나.
  • 서버 스트리밍 — 요청 하나와 응답 스트림 하나(예: 실시간 업데이트).
  • 클라이언트 스트리밍 — 요청 스트림 하나와 응답 하나(예: 대량 업로드).
  • 양방향 — 양쪽이 동시에 스트리밍.

사용 사례가 푸시 또는 장기 데이터 흐름이라면 gRPC 스트리밍이 REST 엔드포인트를 폴링하는 것보다 뛰어납니다.

컨텍스트 및 기한 전파

동기 호출은 사슬을 형성하므로 모든 요청에 두 가지가 함께 전달되어야 합니다. 하나는 종단 간 추적을 위한 상관관계/추적 식별자이고, 다른 하나는 느린 말단 서비스 때문에 전체 사슬이 멈추지 않게 하는 기한입니다. gRPC는 기한을 기본적으로 지원하며, REST에서는 하위 서비스로 전달할 때 계속 줄어드는 시간 제한 예산을 사용해 이를 흉내 냅니다.

<?php
// REST: shrink the remaining budget as the call chain deepens
function forwardHeaders(array $incoming, float $remainingMs): array {
    return [
        'X-Correlation-Id' => $incoming['X-Correlation-Id'] ?? bin2hex(random_bytes(8)),
        // downstream must finish within what's left of our budget
        'X-Timeout-Ms'     => (string) max(0, (int) $remainingMs),
    ];
}
print_r(forwardHeaders(['X-Correlation-Id' => 'trace-9'], 1500));

둘 중 선택하기

실용적인 선택 기준은 다음과 같습니다:

  • REST는 공개/파트너 API, 브라우저 클라이언트, 단순한 CRUD, 손쉬운 디버깅, 폭넓은 캐시 지원에 적합합니다.
  • gRPC는 내부 서비스 간의 대규모·저지연 호출, 엄격한 타입 계약, 스트리밍에 적합합니다.

많은 시스템이 두 방식을 함께 사용합니다. 서비스 간 게이트웨이 뒤에서는 gRPC를 사용하고, 외부 세계를 향한 경계에서는 REST를 사용합니다. 한 도구에 다른 도구의 역할까지 억지로 맡기지 마십시오.

빠른 확인

사용 사례에 맞는 프로토콜을 선택하는 방법입니다.

복습

동기식 서비스 통신:

  • REST/JSON — 보편적이고 디버깅하기 쉬우며 캐시할 수 있습니다. 상태 코드가 계약이므로 항상 시간 제한을 설정해야 합니다.
  • gRPC/Protobuf — 계약 우선 방식이며 작고 빠르고 스트리밍을 지원합니다. 타입이 지정된 PHP 스텁을 생성합니다.
  • 상태 코드/gRPC 코드로 재시도 가능 여부를 결정하고, 클라이언트 오류는 절대 재시도하지 마십시오.
  • 스키마는 추가 방식으로 발전시키고 Protobuf 필드 번호를 절대 재사용하지 마십시오.
  • 외부 경계에서는 REST를, 내부 서비스 간에는 gRPC를 사용하는 구성이 흔하고 타당합니다.

다음: 게이트웨이와 서비스 검색을 사용해 이 모든 서비스를 라우팅하고 찾는 방법.

무료로 시작

AI 튜터와 함께 PHP을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
49
레슨
195

자주 묻는 질문

“서비스 통신: REST와 gRPC” 강의는 무료인가요?

네 — “서비스 통신: REST와 gRPC” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 PHP Academy 강의 전체를 잠금 해제할 수 있습니다. PHP Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“서비스 통신: REST와 gRPC”에서 뭘 배우나요?

서비스를 동기식으로 효율적으로 연결합니다. 브라우저에서 직접 실행하는 실습 코드로 PHP Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

PHP Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 PHP Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“서비스 통신: REST와 gRPC” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 PHP Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 PHP Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 모놀리스에서 마이크로서비스로
  2. 서비스 통신: REST와 gRPC
  3. API 게이트웨이와 서비스 검색
  4. 복원력: 회로 차단기와 재시도
← PHP Academy(으)로 돌아가기