使用Dapr 客户端 处理服务调用,需要遵循的他的模式,通常代码是这个样子的:

var client = DaprClient.CreateInvokeHttpClient(appId: "routing");

var response = await client.GetAsJsonAsync($"/accounts/{17}", cancellationToken);

var account = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken);

我更希望是这样子调用:

public interface IBank

{            [HttpGet("/accounts/{accountId}")]            Task GetUser(string accountId, CancellationToken cancellationToken = default);

           [HttpPost("/deposit")]            Task Deposit([JsonContent] Transaction transaction, CancellationToken cancellationToken = default);

           [HttpPost("/withdraw")]            [RawReturn(Enable =true, EnsureSuccessStatusCode = false)]            Task Withdraw([JsonContent] Transaction transaction, CancellationToken cancellationToken = default);

}

var account = await bankClient.GetUser("17", cancellationToken);

我们可以用 Refit,RestEase 或者是 WebApiClientCore 来达到这样的效果, 那么在Dapr 里面使用这些库如何做到呢, 在Dapr的客户端库里面有一个Handler 的官方实现:InvocationHandler。 搭配这个InvocationHandler 就可以和这几个库,在本文中,我们重点介绍Dapr Client 如何搭配 WebApiClientCore。

public interface IBank

{          [HttpGet("/accounts/{accountId}")]          Task GetUser(string accountId, CancellationToken cancellationToken = default);

          [HttpPost("/deposit")]          Task Deposit([JsonContent] Transaction transaction, CancellationToken cancellationToken = default);

          [HttpPost("/withdraw")]          [RawReturn(Enable =true, EnsureSuccessStatusCode = false)]          Task Withdraw([JsonContent] Transaction transaction, CancellationToken cancellationToken = default); }

 

  public class WebapiClientExample : Example   {       public override string DisplayName => "WebapiClient";

      private IBank bankClient;

      public WebapiClientExample(IBank bank)       {           bankClient = bank;       }

 

      public override async Task RunAsync(CancellationToken cancellationToken)       {           var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);

           // Scenario 1: Check if the account already exists.           Account? account = null;           try           {               account = await bankClient.GetUser("17", cancellationToken);           }           catch (ApiException ex)           {               // Account does not exist.           }

          Console.WriteLine($"Scenario 1: account '17' {(account is null ? "does not exist" : "already exists")}");

          // Scenario 2: Deposit some money           var transaction = new Transaction()           {               Amount = 100m,               Id = "17",           };

          // read updated balance           account = await bankClient.Deposit(transaction, cancellationToken);           Console.WriteLine($"Scenario 2: account '17' has '{account?.Balance}' money");

          // Scenario 3: Handle a validation error without exceptions           transaction = new Transaction()           {               Amount = 1_000_000m,               Id = "17",           };           HttpResponseMessage response = null;

          response = await bankClient.Withdraw(transaction, cancellationToken);           if (response.StatusCode != HttpStatusCode.BadRequest)           {               // We don't actually expect this example to succeed - we expect a 400               Console.WriteLine("Something went wrong :(");               return;           }           var problem = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken);           Console.WriteLine($"Scenario 3: got the following errors:");           foreach (var kvp in problem!.Errors)           {               Console.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value)}");           }       }   }

 

var services = new ServiceCollection();             services.AddTransient();             services.AddLogging();

            services                 .AddScoped()                 .AddHttpApi(o => o.HttpHost = new Uri("http://bank"))                 .AddHttpMessageHandler();            var serviceprovider = services.BuildServiceProvider();

代码的核心部分就在于上面红色的部分,我们把InvocationHandler 加入到AddHttpApi ,就可以和 dapr 一起玩耍了。

查看原文