dotnet-sdk/samples/AspNetCore/GrpcServiceSample
Ryan Nowak 9748ca0a82
Simplify service invocation APIs (#555)
Fixes: #549

This change mixes up the service invocation APIs to reflect some changes
that are coming down the pipe in dapr/dapr#2683.

We're now using HTTP's semantics and JSON for the main functionality in
`InvokeMethodAsync`. This means that the error handling is simplified
and base on HTTP's status codes rather than trying to abstract over HTTP
and gRPC's different error models. This also means that we're free to
expose HttpRequestMessage and related types in the API because it's no
longer an abstraction.

You can still use `InvokeMethodAsync` to invoke gRPC services, but you
will get a status code in the response, and it will expect JSON, etc,
similar to how gRPC gateway works.

In addition to that we're added `InvokeMethodGrpcAsync` for cases where
you really want *gRPC's* semantics. These methods do Protobuf
serialization, as is a natural choice for gRPC. I do not recommend using
this approach to invoke HTTP services.

---

I also mad updates and improvments to various infrastructure where
necessary (like InvocationException). Also, the gRPC sample in the repo
now uses the new `InvokeMethodGrpcAsync` APIs.
2021-01-22 16:28:20 -08:00
..
Models Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00
Properties Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00
Protos Simplify service invocation APIs (#555) 2021-01-22 16:28:20 -08:00
Services Simplify service invocation APIs (#555) 2021-01-22 16:28:20 -08:00
GrpcServiceSample.csproj Simplify service invocation APIs (#555) 2021-01-22 16:28:20 -08:00
Program.cs Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00
Readme.md Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00
Startup.cs Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00
appsettings.Development.json Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00
appsettings.json Includes a gRPC sample (#382) 2020-12-02 17:52:43 -08:00

Readme.md

ASP.NET Core Grpc Service Sample

This sample shows using Dapr with ASP.NET Core Grpc Service. This application is a simple and not-so-secure banking application. The application uses the Dapr state-store for its data storage.

It exposes the following endpoints over GRPC:

  • /getaccount: Get the account information for the account specified by id
  • /deposit: Accepts a Protobuf payload to deposit money to an account
  • /withdraw: Accepts a Protobuf payload to withdraw money from an account

The application also registers for pub/sub with the deposit and withdraw topics.

Running the Sample

To run the sample locally run this command in this project root directory:

dapr run --app-id grpcsample --app-port 5050 --app-protocol grpc -- dotnet run

The application will listen on port 5050 for GRPC.

NOTE: Because of this bug, only can use port 5050 without TLS.

Client Examples

See InvokeGrpcBalanceServiceOperationAsync, InvokeGrpcDepositServiceOperationAsync and InvokeGrpcWithdrawServiceOperationAsync on DaprClient project.

Code Samples

All of the interesting code in this sample is in Startup.cs and Services/BankingService.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();

    services.AddDaprClient();
}

AddDaprClient() registers the Dapr integration with grpc service. This also registers the DaprClient service with the dependency injection container. This service can be used to interact with the Dapr state-store.


app.UseEndpoints(endpoints =>
{
    endpoints.MapGrpcService<BankingService>();

    ...
});

MapGrpcService() exposes BankingService grpc service into ASP.NET Core route endpoints.


public class BankingService : AppCallback.AppCallbackBase
{
    ...
}

You need to inherit AppCallback.AppCallbackBase that will be called by the Dapr runtime to invoke method, register for pub/sub topics and register bindings.


public override async Task<InvokeResponse> OnInvoke(InvokeRequest request, ServerCallContext context)
{
    ...
}

You need to implement this overridable method to support Dapr's service invocation.


public override Task<ListTopicSubscriptionsResponse> ListTopicSubscriptions(Empty request, ServerCallContext context)
{
    ...
}

You need to implement this overridable method to support Dapr's pub/sub topic register.


public override async Task<TopicEventResponse> OnTopicEvent(TopicEventRequest request, ServerCallContext context)
{
    ...
}

You need to implement this overridable method to support Dapr's pub/sub topic handle.