ASP.NET Core의 gRPC JSON 코드 변환

작성자: James Newton-King

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

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

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

개요

gRPC RESTON 코드 변환은 gRPC 서비스용 JSful 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. HTTP 바인딩 및 경로를 사용하여 파일에 gRPC 메서드 .proto 에 주석을 추가합니다.

    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}"
    };
  }
}

진행 예제:

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

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

스트리밍 메서드

기존의 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"}

WriteIndentedJSON 설정은 서버 스트리밍 메서드에 적용되지 않습니다. 자동 서식 지정은 줄로 구분된 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가 제공하는 혜택이 있지만, REST API 및 JSON은 최신 앱에서 중요합니다. gRPC JSON 웹 API를 빌드하면 앱 개발에 원치 않는 오버헤드가 추가됩니다.

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

개요

gRPC RESTON 코드 변환은 gRPC 서비스용 JSful 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. HTTP 바인딩 및 경로를 사용하여 파일에 gRPC 메서드 .proto 에 주석을 추가합니다.
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}"
    };
  }
}

진행 예제:

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

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

스트리밍 메서드

기존의 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"}

WriteIndentedJSON 설정은 서버 스트리밍 메서드에 적용되지 않습니다. 자동 서식 지정은 줄로 구분된 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 추가 정보를 참조하세요.

추가 리소스