Blazor WebAssembly에서 REST 서비스를 gRPC 웹으로 교체하는 10단계

현대 웹 응용 프로그램에서 클라이언트와 서버 간에 데이터를 교환하는 흔한 방식은 REST (representational state transfer) services을 통해 이루어진다.JSON은 이런 양방향 통신의 표준 파일 형식이다.
REST에서 클라이언트가 특정 노드에 요청을 보내면 서버가 응답합니다.
이런 건축 풍격은 매우 좋아서 여러 해 동안 줄곧 표준이었다.SPA (한 페이지 응용 프로그램) 를 만드는 데 사용되는 모든 웹 프레임워크는 그것을 기반으로 합니다.언뜻 보기에는 Blazor Web Assembly마저도 다른 프레임워크처럼 REST를 사용하는 것 같다.
이 표준은 광범위하게 사용되고 있지만 여전히 고려해야 할 중요한 문제가 있습니다.
  • JSON이 XML만큼 상세하지 않다면 대역폭에 대한 최적화도 없다.때때로 JSON 구조가 너무 복잡해진다.
  • REST API는 무상태입니다.이것은 약간의 부정적인 결과를 초래할 수 있다.예를 들어 모든 요청은 필요한 작업을 수행하는 데 필요한 모든 정보를 포함해야 한다.
  • REST는 프로토콜이 아니라 구조 스타일입니다.이것은 개발자를 늘리는 책임과 관련된다.REST의 대다수 구현은 그 원리의 하위 집합만 사용하지만, 많든 적든 가능하다.REST 서비스와 RESTful 서비스(REST 서비스를 실현하는 서비스) 사이에는 일반적으로 혼동이 존재한다.
  • 명확한 것은 REST 체계 구조는 여전히 클라이언트와 서버 간에 데이터를 교환하는 좋은 방식이지만, 아마도 오늘날 우리는 그것을 뛰어넘어 대체 해결 방안을 찾을 수 있을 것이다.

    gRPC 및 gRPC 네트워크란 무엇입니까?


    gRPC은 구글이 2015년에 만든 원격 프로세스 호출 시스템이다.그것은 개원된 것으로 Windows Communication Foundation (WCF)의 대체품으로 정의할 수 있다.그러나 최신 업데이트로 인해 RESTAPI를 대체할 수도 있습니다.
    gRPC는 Protobuf(프로토콜 버퍼)을 유효 부하 형식으로 사용하고 다양한 스트리밍을 지원합니다.
  • 서버 스트리밍
  • 클라이언트 스트리밍
  • 양방향 흐르는 미디어
  • 성능 측면에서 볼 때 Protobuf는 효율적인 이진 메시지 형식입니다.Protobuf 서열화는 비교적 작은 메시지 유효 부하를 발생시킬 수 있는데 이것은 이동과 웹 응용 등 유한 대역폭 장면에서 매우 중요하다.
    gRPC는 서버와 클라이언트 간에 공유된 .proto file을 통해 서비스와 메시지를 정의하는 계약입니다.클라이언트 라이브러리를 자동으로 생성할 수 있습니다.gRPC는 서로 다른 플랫폼과 구현에서 일치합니다.
    The following 표는 JSON 형식의 gRPC와 RESTAPI 간의 특성 비교를 보여 줍니다.

    이 모든 것이 듣기에 매우 좋지 않습니까?불행히도 나쁜 소식이 있다!
    gRPC는 웹 브라우저에서 사용할 수 없습니다. HTTP/2 바이너리 프로토콜이 필요하기 때문입니다.걱정하지 마세요. 이 문제의 해결 방안은 gRPC-Web이라고 하는데 이것은 gRPC를 브라우저에서 사용할 수 있게 합니다.또 하나의 gRPC-Web for .NET의 실현이 이미 정식으로 발표되었다.
    공평하게 말하자면, gRPC-Web은 유한한 gRPC 지원을 제공한다.예를 들어 클라이언트와 양방향 미디어를 지원하지 않고 서버 미디어에 대한 지원도 제한되어 있다.
    이 서문 이후, 이론에서 실천으로 나아갈 때가 되었다!
    본고에서 저는 Blazor WebAssembly 응용 프로그램에서 gRPC 웹 서비스를 사용하여 일기예보 응용 프로그램을 구축하는 방법을 보여 드리겠습니다.본문을 작성할 때 이 프로젝트에 사용할 템플릿이 없기 때문에 Blazor WebAssembly 응용 프로그램에 gRPC 지원을 추가하는 것은 상당히 중요한 작업입니다.하지만 걱정하지 마세요.이 점은 결코 복잡하지 않다.10걸음밖에 안 돼!
    1단계
    Blazor WebAssembly ASP를 생성합니다.NET 코어 관리형 솔루션이며 BlazorGrpc로 명명됩니다.다음 화면 캡처를 참조하십시오.
    단계2
    의존 항목을 추가하기 위해 프로젝트 파일을 변경해야 합니다.
    BlazorGrpc.공유프로젝트 파일
    <ItemGroup>
      <None Remove="weatherforecast.proto" />
    </ItemGroup>
    
    <ItemGroup>
      <PackageReference Include="Google.Protobuf" Version="3.13.0" />
      <PackageReference Include="Grpc.Net.Client" Version="2.31.0" />
      <PackageReference Include="Grpc.Tools" Version="2.31.0">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      </PackageReference>
    </ItemGroup>
    
    <ItemGroup>
      <Protobuf Include="weatherforecast.proto" />
    </ItemGroup>
    
    BlazorGrpc.서버프로젝트 파일
    <PackageReference Include=”Grpc.AspNetCore” Version=”2.31.0” />
    <PackageReference Include=”Grpc.AspNetCore.Web” Version=”2.31.0” />
    
    BlazorGrpc.고객프로젝트 파일
    <PackageReference Include="Grpc.Net.Client.Web" Version="2.31.0" />
    
    단계 3
    공유 프로젝트에서 일기예보를 만듭니다.아래의 코드 예시와 같은 프로토 파일입니다.
    syntax = "proto3";
    
    import "google/protobuf/empty.proto";
    import "google/protobuf/timestamp.proto";
    
    option csharp_namespace = "BlazorGrpc.Shared";
    
    package WeatherForecast;
    
    service WeatherForecastService {
      rpc GetWeatherForecast (google.protobuf.Empty) returns (WeatherForecastResponse);
    }
    
    message WeatherForecastResponse {
      repeated WeatherForecast forecasts = 1;
    }
    
    message WeatherForecast {
      google.protobuf.Timestamp dateTimeStamp = 1;
      int32 temperatureC = 2;
      string summary = 3;
    }
    
    이것proto 파일은 서비스와 올바른 실행에 필요한 모든 것을 정의합니다.
    이 파일 구문에 대한 자세한 내용은 다음 문서를 참조하십시오.
    https://developers.google.com/protocol-buffers/docs/proto3
    4단계
    파일 속성으로 이동하여 Protobuf 컴파일러를 빌드 작업으로 선택합니다.NuGet 패키지 Grpc로 인해 새 창이 나타납니다.도구그리고 클라이언트와 서버 옵션을 gRPC 메모리 클래스로 선택하십시오.다음 화면 캡처를 참조하십시오.
    단계 5
    다음 코드 세그먼트를 사용하여 WeatherForecast 클래스를 수정합니다.이러한 주요 속성은 생성된 것임을 기억하십시오.원형 파일;단, 이 분류에 추가 유용한 속성을 추가할 수도 있습니다.
    using System;
    using Google.Protobuf.WellKnownTypes;
    namespace Blazorgrpc.Shared
    {
        public partial class WeatherForecast
        {
            public DateTime Date
            {
                get => DateTimeStamp.ToDateTime();
                set { DateTimeStamp = Timestamp.FromDateTime(value.ToUniversalTime()); }
            }
    
            public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
        }
    }
    
    단계 6
    서버 항목에서 용기에 gRPC 서비스를 추가합니다.시작 중입니다.다음 코드를 추가하여 Configure Services 방법을 수정하는 cs 파일:
    services.AddGrpc();
    
    성능 최적화를 위해 다음 코드를 추가하여 응답 압축을 활용하는 것이 좋습니다.
    services.AddResponseCompression(opts =>
                {
                    opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                        new[] { "application/octet-stream" });
                });
    
    7단계
    이제 서비스 클래스에서 응용 프로그램의 논리를 실현하고 용기에 추가하며 템플릿으로 생성된 컨트롤러를 수정할 때가 되었다.서비스 클래스는 아래의 코드와 유사하다.
    public class WeatherForecastService : 
     BlazorGrpc.Shared.WeatherForecastService.WeatherForecastServiceBase  
    
    {
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
    
            public override Task<WeatherForecastResponse> GetWeatherForecast(Empty request, ServerCallContext context)
            {
                var response = new WeatherForecastResponse();
    
                response.Forecasts.AddRange(GetWeatherForecast());
    
                return Task.FromResult<WeatherForecastResponse>(response);
            }
    
            public IEnumerable<WeatherForecast> GetWeatherForecast()
            {
                var rng = new Random();
                return Enumerable.Range(1, 365).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                });
            }
    }
    
    참고: Weather Forecast Service 클래스는 BlazorGrpc에서 상속됩니다.공유일기예보 서비스.Weather Forecast ServiceBase는 자동으로 생성됩니다.원형 파일.
    단계 8
    부팅으로 돌아갑니다.cs 파일은 모든 서비스가 기본적으로 gRPC 웹을 지원할 수 있도록 다음 코드와 같은 설정 방법에 gRPC 웹 중간부품을 설정합니다.
    app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
    
    그런 다음 다음 다음 코드가 있는 라우트를 추가합니다.
    app.UseEndpoints(endpoints =>
          {
           endpoints.MapGrpcService<WeatherForecastService>();
          }
    
    단계 9
    고객 프로젝트로 넘어가겠습니다.먼저 컨테이너에 Weather Forecast Service를 추가한 다음 백엔드 서버를 가리키는 gRPC 웹 채널을 만들고 이 채널의 gRPC 클라이언트를 실례화합니다.
    프로그램을 수정하려면 아래 코드를 참조하십시오.cs 파일, 필요한 이름 공간을 추가해야 합니다.
    builder.Services. AddSingleton(services =>
                {
                    var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
                    var backendUrl = services.GetRequiredService<NavigationManager>().BaseUri;
                    var channel = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpClient = httpClient });
    
                    return new WeatherForecastService.WeatherForecastServiceClient(channel);
    });
    
    주: 일기예보 서비스.Weather Forecast Service Client 클래스도 자동으로 생성됩니다.원형 파일.
    10단계
    마지막으로 FetchDataGrpc를 추가합니다.razor 파일, 그리고 가져온 데이터에 대해 약간의 변경을 합니다.면도기와 내비게이션 메뉴.razor 파일._ 가져오기를 변경하는 것을 잊지 마십시오.면도기 줄.
    다음 코드를 참조하십시오.
    @page "/fetchdatagrpc"
    @inject WeatherForecastService.WeatherForecastServiceClient WeatherForecastServiceClient
    @using Blazorgrpc.Shared
    @using Google.Protobuf.WellKnownTypes
    <h1>Weather forecast</h1>
    
    <p>This component demonstrates fetching data from the gRPC service.</p>
    
    @if (forecasts == null)
    {
        <p><em>Loading...</em></p>
    }
    else
    {
        <table class="table">
            <thead>
                <tr>
                    <th>Date</th>
                    <th>Temp. (C)</th>
                    <th>Temp. (F)</th>
                    <th>Summary</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var forecast in forecasts)
                {
                    <tr>
                        <td>@forecast.Date.ToShortDateString()</td>
                        <td>@forecast.TemperatureC</td>
                        <td>@forecast.TemperatureF</td>
                        <td>@forecast.Summary</td>
                    </tr>
                }
            </tbody>
        </table>
    }
    
    @code {
    
        private IList<WeatherForecast> forecasts;
    
        protected override async Task OnInitializedAsync()
        {
            forecasts = (await WeatherForecastServiceClient.GetWeatherForecastAsync(new Empty())).Forecasts;
        }
    }
    
    이게 다야!이제 우리는 우리의 일을 테스트하는 데 즐거움을 얻을 수 있다.상기 코드 예시를 실현하면 다음과 같은 화면 캡처를 얻을 수 있습니다.
    우리는 두 페이지가 같은 데이터를 되돌려주지만 하나는 REST 서비스를 사용하고 다른 하나는 gRPC 서비스를 사용하는 것을 볼 수 있다.
    그것들을 테스트하고 네트워크 데이터의 진정한 장점을 확인하기 위해 검사한다.
    네트워크 데이터 비교
    위의 화면 캡처에서 REST 서비스가 55.6KB를 보냈지만 gRPC 서비스는 10.1KB만 보냈습니다!

    리소스


    변환된 항목은 이 GitHub repository에서 얻을 수 있습니다.

    결론


    본고에서 우리는 Blazor WebAssembly가 위탁 관리하는 응용 프로그램에서 gRPC 서비스를 만드는 방법과 이 해결 방안이 어떻게 현저한 성능 우위를 가져오는지 이해했다.이것은 제한된 대역폭 상황에서 데이터 전송 작업을 가속화하는 데 도움이 될 것이다.
    네가 직접 해 봐라, 아래의 평론 부분에 너의 피드백을 남겨라!
    Syncfusion Essential Studio for Blazor은 소프트웨어 패키지에서 웹에 65개 이상의 고성능, 경량급, 응답성 UI 구성 요소를 제공합니다. 파일 형식 라이브러리를 포함합니다.실제 체험을 위해 sample browser의 현장 프레젠테이션을 보십시오.
    기존 고객의 경우 License and Downloads 페이지에서 최신 버전을 다운로드할 수 있습니다.Syncfusion 고객이 아니라면 30일 동안 사용할 수 있는 free trial을 사용해 보십시오.그 밖에 당신은 이 GitHub위치에서 우리의 견본을 시험적으로 사용할 수 있습니다.
    당신도 우리의 support forums, Direct-Trac 또는 feedback portal을 통해 우리와 연락할 수 있습니다.우리는 항상 기꺼이 너를 돕는다!
    만약 당신이 이 게시물을 좋아한다면, 우리는 당신도 다음과 같은 내용을 좋아할 것이라고 생각합니다.

  • [블로그]

  • [블로그]

  • [Webinar Show Notes]

  • Blazor Succintly [전자책]
  • 좋은 웹페이지 즐겨찾기