ASP.NET Core의 gRPC JSON 코드 변환

참고

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 10 버전을 참조하세요.

경고

이 버전의 ASP.NET Core는 더 이상 지원되지 않습니다. 자세한 내용은 .NET 및 .NET Core 지원 정책을 참조 하세요. 현재 릴리스는 이 문서의 .NET 10 버전을 참조하세요.

작성자: James Newton-King

gRPC는 고성능 RPC(원격 프로시저 호출) 프레임워크입니다. gRPC는 HTTP/2, 스트리밍, Protobuf 및 메시지 계약을 사용하여 고성능 실시간 서비스를 만듭니다.

gRPC의 한 가지 제한 사항은 모든 플랫폼에서 사용할 수 없다는 것입니다. 브라우저는 HTTP/2를 완전히 지원하지 않으므로 브라우저 앱으로 데이터를 가져오는 기본 방법으로 REST API 및 JSON을 설정합니다. gRPC가 제공하는 이점에도 불구하고 API REST 및 JSON은 최신 앱에서 중요한 위치를 차지합니다. gRPC 및 JSON Web API를 빌드하면 앱 개발에 원치 않는 오버헤드가 추가됩니다.

이 문서에서는 gRPC 서비스를 사용하여 JSON 웹 API를 만드는 방법을 설명합니다.

개요

gRPC JSON 코드 변환은 gRPC 서비스용 RESTful JSON API를 만드는 ASP.NET Core를 위한 확장입니다. 일단 구성된 후 코드 변환을 사용하면 앱에서 친숙한 HTTP 개념으로 gRPC 서비스를 호출할 수 있습니다.

  • HTTP 동사
  • URL 매개 변수 바인딩
  • JSON 요청/응답

서비스를 호출하는 데 gRPC를 계속 사용할 수 있습니다.

참고

gRPC JSON 트랜스코딩은 대체 실험적 확장인 gRPC HTTP API를 대체합니다.

사용

  1. Microsoft.AspNetCore.Grpc.JsonTranscoding에 대한 패키지 참조를 추가합니다.

  2. AddJsonTranscoding를 추가하여 서버 시작 코드에 트랜스코딩을 등록합니다: Program.cs 파일에서 builder.Services.AddGrpc();를 builder.Services.AddGrpc().AddJsonTranscoding();로 변경합니다.

  3. 프로젝트 파일(.csproj)의 속성 그룹에 <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>를 추가합니다:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <InvariantGlobalization>true</InvariantGlobalization>
        <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
      </PropertyGroup>
    
  4. .proto 파일의 gRPC 메서드에 HTTP 바인딩 및 경로를 주석으로 추가합니다.

    syntax = "proto3";
    
    option csharp_namespace = "GrpcServiceTranscoding";
    import "google/api/annotations.proto";
    
    package greet;
    
    // The greeting service definition.
    service Greeter {
      rpc SayHello (HelloRequest) returns (HelloReply) {
        option (google.api.http) = {
          get: "/v1/greeter/{name}"
        };
      }
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings.
    message HelloReply {
      string message = 1;
    }
    

SayHello RPC 메서드는 이제 gRPC 및 JSON 웹 API로 호출할 수 있습니다.

  • 요청: GET /v1/greeter/world
  • 응답: { "message": "Hello world" }

서버가 각 요청에 대한 로그를 작성하도록 구성된 경우, 서버 로그는 gRPC 서비스가 HTTP 호출을 실행함을 보여줍니다. 코드 변환은 들어오는 HTTP 요청을 gRPC 메시지에 매핑하고 응답 메시지를 JSON으로 변환합니다.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
      Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.996ms 200 application/json

gRPC 메서드 주석 달기

gRPC 메서드는 트랜스코딩을 지원하려면 먼저 HTTP 규칙으로 주석 처리되어야 합니다. HTTP 규칙에는 HTTP 메서드 및 경로와 같은 gRPC 메서드를 호출하는 방법에 대한 정보가 포함됩니다.

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

진행 예제:

  • Greeter 메서드를 사용하여 SayHello 서비스를 정의합니다. 메서드에는 google.api.http 이름을 사용하여 지정된 HTTP 규칙이 있습니다.
  • 메서드는 GET 요청 및 /v1/greeter/{name} 경로로 액세스할 수 있습니다.
  • 요청 메시지의 name 필드는 경로 매개 변수에 바인딩됩니다.

gRPC 메서드가 RESTful API에 바인딩하는 방법을 사용자 지정하는 데 많은 옵션을 사용할 수 있습니다. gRPC 메서드에 주석을 추가하고 JSON을 사용자 지정하는 방법에 대한 자세한 내용은 gRPC JSON 코드 변환에 대한 HTTP 및 JSON 구성을 참조 하세요.

스트리밍 메서드

기존의 HTTP/2를 통한 gRPC는 모든 방향에서 스트리밍을 지원합니다. 코드 변환은 서버 스트리밍으로만 제한됩니다. 클라이언트 스트리밍 및 양방향 스트리밍 메서드는 지원되지 않습니다.

서버 스트리밍 메서드는 줄로 구분된 JSON을 사용합니다. 사용하여 WriteAsync 작성된 각 메시지는 JSON으로 직렬화되고 그 다음에 새 줄이 잇습니다.

다음 서버 스트리밍 메서드는 세 개의 메시지를 씁니다.

public override async Task StreamingFromServer(ExampleRequest request,
    IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
{
    for (var i = 1; i <= 3; i++)
    {
        await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}

클라이언트는 세 개의 줄로 구분된 JSON 개체를 받습니다.

{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

JSON 설정은 WriteIndented 서버 스트리밍 메서드에 적용되지 않습니다. 예쁜 인쇄는 줄로 구분된 JSON과 함께 사용할 수 없는 JSON에 새 선과 공백을 추가합니다.

ASP.NET Core gPRC 트랜스코딩 및 스트리밍 앱 샘플을 보거나 다운로드합니다.

HTTP 프로토콜

.NET SDK에 포함된 ASP.NET Core gRPC 서비스 템플릿은 HTTP/2에 대해서만 구성된 앱을 만듭니다. HTTP/2는 앱이 기존의 HTTP/2를 통한 gRPC만 지원하는 경우에 좋은 기본값입니다. 그러나 코드 변환은 HTTP/1.1 및 HTTP/2 모두에서 작동합니다. UWP 또는 Unity와 같은 일부 플랫폼은 HTTP/2를 사용할 수 없습니다. 모든 클라이언트 앱을 지원하려면 HTTP/1.1 및 HTTP/2를 사용하도록 서버를 구성합니다.

appsettings.json에서 기본 프로토콜을 업데이트합니다.

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

또는 시작 코드에서 Kestrel 엔드포인트를 구성합니다.

동일한 포트에서 HTTP/1.1 및 HTTP/2를 사용하도록 설정하려면 프로토콜 협상을 위해 TLS가 필요합니다. gRPC 앱에서 HTTP 프로토콜을 구성하는 방법에 대한 자세한 내용은 ASP.NET Core gRPC 프로토콜 협상을 참조하세요.

gRPC JSON 코드 변환 및 gRPC-Web

코드 변환 및 gRPC-Web 둘 다 사용하여 브라우저에서 gRPC 서비스를 호출할 수 있습니다. 그러나 각각 해당 작업을 수행하는 방법은 다릅니다.

  • gRPC-Web을 사용하면 브라우저 앱은 gRPC-Web 클라이언트 및 Protobuf를 사용하여 브라우저에서 gRPC 서비스를 호출할 수 있습니다. gRPC-Web을 사용하려면 브라우저 앱이 gRPC 클라이언트를 생성해야 하며 gRPC-Web에는 작고 빠른 Protobuf 메시지를 보내는 이점이 있습니다.
  • 코드 변환을 사용하면 브라우저 앱이 JSON을 사용하여 RESTful API인 것처럼 gRPC 서비스를 호출할 수 있습니다. 브라우저 앱에서 gRPC 클라이언트를 생성하거나 gRPC에 관해 알고 있을 필요가 없습니다.

이전 Greeter 서비스는 브라우저 JavaScript API를 사용하여 호출할 수 있습니다.

var name = nameInput.value;

fetch('/v1/greeter/' + name)
  .then((response) => response.json())
  .then((result) => {
    console.log(result.message);
    // Hello world
  });

grpc-gateway

grpc-gateway는 gRPC 서비스에서 RESTful JSON API를 만들 수 있는 또 다른 기술입니다. 동일한 .proto 주석을 사용하여 HTTP 개념을 gRPC 서비스에 매핑합니다.

grpc-gateway는 역방향 프록시 서버를 만들기 위해 코드 생성을 사용합니다. 역방향 프록시는 RESTful 호출을 gRPC+Protobuf로 변환하고, 호출을 HTTP/2를 통해 gRPC 서비스로 보냅니다. 이 방법의 장점은 gRPC 서비스에서 RESTful JSON API에 대해 알지 못한다는 것입니다. 모든 gRPC 서버에서 grpc-gateway를 사용할 수 있습니다.

한편 gRPC JSON 코드 변환은 ASP.NET Core 앱 내에서 실행됩니다. JSON을 Protobuf 메시지로 역직렬화한 다음 gRPC 서비스를 직접 호출합니다. ASP.NET Core 내의 코드 변환은 .NET 앱 개발자에게 다음과 같은 이점을 제공합니다.

  • 덜 복잡합니다. gRPC 서비스와 매핑된 RESTful JSON API가 ASP.NET Core 앱 중 하나에서 실행되기 때문입니다.
  • 성능 향상: 코드 변환은 JSON을 Protobuf 메시지로 역직렬화하고 gRPC 서비스를 직접 호출합니다. 다른 서버에 새로운 gRPC 호출을 생성하는 것과 비교하면 이 In Process 수행에는 상당한 성능 이점이 있습니다.
  • 비용이 낮아집니다. 서버 수가 적을수록 월별 호스팅 요금도 줄어듭니다.

grpc-gateway 설치 및 사용에 대해서는 grpc-gateway 추가 정보를 참조하세요.

gRPC는 고성능 RPC(원격 프로시저 호출) 프레임워크입니다. gRPC는 HTTP/2, 스트리밍, Protobuf 및 메시지 계약을 사용하여 고성능 실시간 서비스를 만듭니다.

gRPC의 한 가지 제한 사항은 모든 플랫폼에서 사용할 수 없다는 것입니다. 브라우저는 HTTP/2를 완전히 지원하지 않으므로 브라우저 앱으로 데이터를 가져오는 기본 방법으로 REST API 및 JSON을 설정합니다. gRPC가 제공하는 이점에도 불구하고 API REST 및 JSON은 최신 앱에서 중요한 위치를 차지합니다. gRPC 및 JSON Web API를 빌드하면 앱 개발에 원치 않는 오버헤드가 추가됩니다.

이 문서에서는 gRPC 서비스를 사용하여 JSON 웹 API를 만드는 방법을 설명합니다.

개요

gRPC JSON 코드 변환은 gRPC 서비스용 RESTful JSON API를 만드는 ASP.NET Core를 위한 확장입니다. 일단 구성된 후 코드 변환을 사용하면 앱에서 친숙한 HTTP 개념으로 gRPC 서비스를 호출할 수 있습니다.

  • HTTP 동사
  • URL 매개 변수 바인딩
  • JSON 요청/응답

서비스를 호출하는 데 gRPC를 계속 사용할 수 있습니다.

참고

gRPC JSON 트랜스코딩은 대체 실험적 확장인 gRPC HTTP API를 대체합니다.

사용

  1. Microsoft.AspNetCore.Grpc.JsonTranscoding에 대한 패키지 참조를 추가합니다.
  2. AddJsonTranscoding를 추가하여 서버 시작 코드에 트랜스코딩을 등록합니다: Program.cs 파일에서 builder.Services.AddGrpc();를 builder.Services.AddGrpc().AddJsonTranscoding();로 변경합니다.
  3. 파일이 포함된 프로젝트 디렉터리에 디렉터리 구조를 /google/api 만듭니다 .csproj .
  4. /google/api 디렉터리에 google/api/http.proto 및 google/api/annotations.proto 파일을 추가합니다.
  5. .proto 파일의 gRPC 메서드에 HTTP 바인딩 및 경로를 주석으로 추가합니다.
syntax = "proto3";

option csharp_namespace = "GrpcServiceTranscoding";
import "google/api/annotations.proto";

package greet;

// The greeting service definition.
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

SayHello RPC 메서드는 이제 gRPC 및 JSON 웹 API로 호출할 수 있습니다.

  • 요청: GET /v1/greeter/world
  • 응답: { "message": "Hello world" }

서버가 각 요청에 대한 로그를 작성하도록 구성된 경우, 서버 로그는 gRPC 서비스가 HTTP 호출을 실행함을 보여줍니다. 코드 변환은 들어오는 HTTP 요청을 gRPC 메시지에 매핑하고 응답 메시지를 JSON으로 변환합니다.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
      Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.996ms 200 application/json

gRPC 메서드 주석 달기

gRPC 메서드는 트랜스코딩을 지원하려면 먼저 HTTP 규칙으로 주석 처리되어야 합니다. HTTP 규칙에는 HTTP 메서드 및 경로와 같은 gRPC 메서드를 호출하는 방법에 대한 정보가 포함됩니다.

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

진행 예제:

  • Greeter 메서드를 사용하여 SayHello 서비스를 정의합니다. 메서드에는 google.api.http 이름을 사용하여 지정된 HTTP 규칙이 있습니다.
  • 메서드는 GET 요청 및 /v1/greeter/{name} 경로로 액세스할 수 있습니다.
  • 요청 메시지의 name 필드는 경로 매개 변수에 바인딩됩니다.

gRPC 메서드가 RESTful API에 바인딩하는 방법을 사용자 지정하는 데 많은 옵션을 사용할 수 있습니다. gRPC 메서드에 주석을 추가하고 JSON을 사용자 지정하는 방법에 대한 자세한 내용은 gRPC JSON 코드 변환에 대한 HTTP 및 JSON 구성을 참조 하세요.

스트리밍 메서드

기존의 HTTP/2를 통한 gRPC는 모든 방향에서 스트리밍을 지원합니다. 코드 변환은 서버 스트리밍으로만 제한됩니다. 클라이언트 스트리밍 및 양방향 스트리밍 메서드는 지원되지 않습니다.

서버 스트리밍 메서드는 줄로 구분된 JSON을 사용합니다. 사용하여 WriteAsync 작성된 각 메시지는 JSON으로 직렬화되고 그 다음에 새 줄이 잇습니다.

다음 서버 스트리밍 메서드는 세 개의 메시지를 씁니다.

public override async Task StreamingFromServer(ExampleRequest request,
    IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
{
    for (var i = 1; i <= 3; i++)
    {
        await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}

클라이언트는 세 개의 줄로 구분된 JSON 개체를 받습니다.

{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

JSON 설정은 WriteIndented 서버 스트리밍 메서드에 적용되지 않습니다. 예쁜 인쇄는 줄로 구분된 JSON과 함께 사용할 수 없는 JSON에 새 선과 공백을 추가합니다.

ASP.NET Core gPRC 트랜스코딩 및 스트리밍 앱 샘플을 보거나 다운로드합니다.

HTTP 프로토콜

.NET SDK에 포함된 ASP.NET Core gRPC 서비스 템플릿은 HTTP/2에 대해서만 구성된 앱을 만듭니다. HTTP/2는 앱이 기존의 HTTP/2를 통한 gRPC만 지원하는 경우에 좋은 기본값입니다. 그러나 코드 변환은 HTTP/1.1 및 HTTP/2 모두에서 작동합니다. UWP 또는 Unity와 같은 일부 플랫폼은 HTTP/2를 사용할 수 없습니다. 모든 클라이언트 앱을 지원하려면 HTTP/1.1 및 HTTP/2를 사용하도록 서버를 구성합니다.

appsettings.json에서 기본 프로토콜을 업데이트합니다.

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

또는 시작 코드에서 Kestrel 엔드포인트를 구성합니다.

동일한 포트에서 HTTP/1.1 및 HTTP/2를 사용하도록 설정하려면 프로토콜 협상을 위해 TLS가 필요합니다. gRPC 앱에서 HTTP 프로토콜을 구성하는 방법에 대한 자세한 내용은 ASP.NET Core gRPC 프로토콜 협상을 참조하세요.

gRPC JSON 코드 변환 및 gRPC-Web

코드 변환 및 gRPC-Web 둘 다 사용하여 브라우저에서 gRPC 서비스를 호출할 수 있습니다. 그러나 각각 해당 작업을 수행하는 방법은 다릅니다.

  • gRPC-Web을 사용하면 브라우저 앱은 gRPC-Web 클라이언트 및 Protobuf를 사용하여 브라우저에서 gRPC 서비스를 호출할 수 있습니다. gRPC-Web을 사용하려면 브라우저 앱이 gRPC 클라이언트를 생성해야 하며 gRPC-Web에는 작고 빠른 Protobuf 메시지를 보내는 이점이 있습니다.
  • 코드 변환을 사용하면 브라우저 앱이 JSON을 사용하여 RESTful API인 것처럼 gRPC 서비스를 호출할 수 있습니다. 브라우저 앱에서 gRPC 클라이언트를 생성하거나 gRPC에 관해 알고 있을 필요가 없습니다.

이전 Greeter 서비스는 브라우저 JavaScript API를 사용하여 호출할 수 있습니다.

var name = nameInput.value;

fetch('/v1/greeter/' + name)
  .then((response) => response.json())
  .then((result) => {
    console.log(result.message);
    // Hello world
  });

grpc-gateway

grpc-gateway는 gRPC 서비스에서 RESTful JSON API를 만들 수 있는 또 다른 기술입니다. 동일한 .proto 주석을 사용하여 HTTP 개념을 gRPC 서비스에 매핑합니다.

grpc-gateway는 역방향 프록시 서버를 만들기 위해 코드 생성을 사용합니다. 역방향 프록시는 RESTful 호출을 gRPC+Protobuf로 변환하고, 호출을 HTTP/2를 통해 gRPC 서비스로 보냅니다. 이 방법의 장점은 gRPC 서비스에서 RESTful JSON API에 대해 알지 못한다는 것입니다. 모든 gRPC 서버에서 grpc-gateway를 사용할 수 있습니다.

한편 gRPC JSON 코드 변환은 ASP.NET Core 앱 내에서 실행됩니다. JSON을 Protobuf 메시지로 역직렬화한 다음 gRPC 서비스를 직접 호출합니다. ASP.NET Core 내의 코드 변환은 .NET 앱 개발자에게 다음과 같은 이점을 제공합니다.

  • 덜 복잡합니다. gRPC 서비스와 매핑된 RESTful JSON API가 ASP.NET Core 앱 중 하나에서 실행되기 때문입니다.
  • 성능 향상: 코드 변환은 JSON을 Protobuf 메시지로 역직렬화하고 gRPC 서비스를 직접 호출합니다. 다른 서버에 새로운 gRPC 호출을 생성하는 것과 비교하면 이 In Process 수행에는 상당한 성능 이점이 있습니다.
  • 비용이 낮아집니다. 서버 수가 적을수록 월별 호스팅 요금도 줄어듭니다.

grpc-gateway 설치 및 사용에 대해서는 grpc-gateway 추가 정보를 참조하세요.