Building Grpc Web Services with ASP.NET Core

Author

Reads 1.2K

Computer server in data center room
Credit: pexels.com, Computer server in data center room

Building Grpc Web Services with ASP.NET Core is a great choice for creating high-performance APIs.

You can use the Grpc.AspNetCore package to add gRPC support to your ASP.NET Core project.

The first step is to create a gRPC service by inheriting from the Grpc.AspNetCore.Server.ServerBase class.

This will provide a foundation for building your gRPC web services.

In the example, a Greeter service is created by inheriting from the ServerBase class and implementing the Greeter interface.

The Greeter interface defines the methods that will be exposed by the gRPC service.

The Greeter service is then registered with the DI container using the AddGrpc method.

This sets up the gRPC service to be used in the application.

With the gRPC service set up, you can start building your web services.

You might like: Grpc .net

Installation

To install gRPC-Web, start by downloading the protoc-gen-grpc-web protoc plugin from the release page. Make sure all executables are discoverable from your PATH.

On macOS, you can do this by running a command in your terminal. If you're using our Docker setup, the prereqs image already includes both protoc and the protoc-gen-grpc-web plugin on the PATH.

Typically, you will run a command to generate the proto messages and the service client stub from your .proto definitions. This will create two new files in the current directory: helloworld_pb.js and helloworld_grpc_web_pb.js.

If this caught your attention, see: Nextjs Pwa

Install Code Generator

Computer server in data center room
Credit: pexels.com, Computer server in data center room

To install the code generator, you can download the protoc-gen-grpc-web protoc plugin from the release page. Make sure all executables are discoverable from your PATH.

For example, on macOS, you can do this by ensuring the plugin is installed and accessible. Note that if you're using a Docker setup, the prereqs image already includes both protoc and the protoc-gen-grpc-web plugin on the PATH.

Typically, you'll run a command to generate proto messages and the service client stub from your .proto definitions.

Verify Installations

You can verify that the plugins are working by following the Hello World example. This will help you ensure that everything is installed correctly.

After running the command, you should see two new files generated in the current directory. These files are helloworld_pb.js and helloworld_grpc_web_pb.js.

You can check if the installation is successful by looking for these two files. If you see them, it's a good sign that everything is working as expected.

Here's what you should see if the installation is successful:

  • helloworld_pb.js — Generated by protoc-gen-js plugin
  • helloworld_grpc_web_pb.js - Generated by gRPC-Web plugin

Runtime and Library

Credit: youtube.com, Hands on Building Web API, gRPC Web, and Blazor WASM | Viswanatha Swamy | XMonkeys360

The gRPC-web runtime library is available on npm, making it easy to get started with your project. You can install it with a simple npm command.

To use the gRPC-web runtime library, you'll need to install it first, and then you can start building your gRPC-web application.

Runtime Library

The gRPC-web runtime library is available on npm. This is a crucial piece of information for developers who want to get started with gRPC-web.

You can easily install the gRPC-web runtime library using npm by running the command npm install grpc-web in your terminal.

Unary

Unary is a type of gRPC call.

It's a simple request-response model, where the client sends a single message to the server and receives a single response in return. This is in contrast to other types of gRPC calls, like server streaming, which involve multiple messages being sent back and forth.

gRPC Web Unary is used in certain scenarios, such as when a client needs to make a single request to a backend server, like clicking on a button to find something.

In the context of gRPC Web Unary, a unary call is made when the client clicks on a button, like the 'Find' button for the Square Input.

Streaming Support

Credit: youtube.com, grpc web demo

Streaming Support is a crucial aspect of gRPC-Web, and it's essential to understand its limitations. gRPC-web currently supports 2 RPC modes: Unary RPCs and Server-side Streaming RPCs.

Client-side streaming is not currently supported, and it's unlikely to change until the new whatwg fetch/streams API lands in browsers. This means you're limited to unary RPCs and server-side streaming RPCs.

Here are the supported streaming modes in gRPC-web:

  • Unary RPCs
  • Server-side Streaming RPCs (only when grpcwebtext mode is used)

If you're looking for client-side or bi-directional streaming support, you might want to consider using a built-in websocket transport, like the one provided by @improbable-eng/grpc-web. This can support client-side/bi-directional streaming RPCs.

Check this out: Grpc New Client

Web and HTTP

gRPC Web uses a special proxy to connect to gRPC services, with Envoy being the default choice.

gRPC Web has a roadmap that includes support for language-specific web frameworks like Python, Java, and Node, but that's still in the future.

The ASP.NET Core gRPC service template only configures the app for HTTP/2 by default, which is a good default for traditional gRPC over HTTP/2, but gRPC-Web works with both HTTP/1.1 and HTTP/2.

Credit: youtube.com, gRPC vs REST - KEY differences and performance TEST

To support all client apps, including those that can't use HTTP/2, you should configure the server to enable both HTTP/1.1 and HTTP/2.

You can update the default protocol in appsettings.json or configure Kestrel endpoints in startup code.

gRPC uses HTTP2 as its network protocol and protocol-buffers to define the API and data models for application interaction.

gRPC Web allows browsers to use the same proto file to interact with a backend gRPC server, making it possible to develop a full-stack gRPC application.

Most modern browsers support the Fetch API, which allows for efficient reading of partial, binary responses, and gRPC-Web automatically falls back to XMLHttpRequest for older browsers.

Here are the browsers that support gRPC-Web:

  • Chrome >= 41
  • Firefox >= 38
  • Edge >= 13
  • IE >= 11
  • Safari >= 8

To call gRPC-Web from the browser, the server must contain configuration to support gRPC-Web, and server streaming is supported, but client streaming and bidirectional streaming calls aren't.

Browsers do support HTTP2 for static files, but for XMLHttpRequest/Ajax calls, they still use HTTP/1.1, which is a limitation of browsers as of now.

A fresh viewpoint: Personal Web Server

Service and Server

Credit: youtube.com, Daniel Alm - Supercharging your Web APIs with gRPC

To create a gRPC service, you start by defining it, which involves using protocol buffers to define the RPC service methods and their message request and response types.

The first step is to define your service, and this is done using protocol buffers. This is a crucial step in setting up your gRPC service.

To implement the service interface, you need to run a gRPC server. This server is responsible for handling the incoming requests and sending responses back to the client.

A gateway proxy is also required to allow the client to connect to the server. This proxy is typically implemented using a tool like Envoy.

The Echo service provides a simple example of how to implement a gRPC server and a gateway proxy.

Here are the steps to run the server and proxy:

  • Run the gRPC server that implements the service interface.
  • Run the Envoy proxy to allow the client to connect to the server.

By following these steps, you can set up a basic gRPC service with a server and proxy.

Configure in ASP.NET Core

Credit: youtube.com, Background Services in ASP.NET Core and .NET - Steve Gordon - NDC London 2024

To configure gRPC-Web in ASP.NET Core, you need to add a reference to the Grpc.AspNetCore.Web package. This package allows you to configure the app to use gRPC-Web alongside HTTP/2 gRPC services.

The gRPC-Web middleware, UseGrpcWeb, should be added after routing and before endpoints in Program.cs. This will enable gRPC-Web for the services.

Alternatively, you can configure the gRPC-Web middleware to enable all services to support gRPC-Web by default. To do this, specify new GrpcWebOptions { DefaultEnabled = true } when adding the middleware.

Here's a step-by-step guide to configuring gRPC-Web:

1. Add a reference to the Grpc.AspNetCore.Web package.

2. Add the UseGrpcWeb middleware in Program.cs.

3. Specify new GrpcWebOptions { DefaultEnabled = true } to enable all services to support gRPC-Web by default.

Note that there is a known issue that causes gRPC-Web to fail when hosted by HTTP.sys in .NET Core 3.x. A workaround is available in Grpc-web experimental and UseHttpSys().

On a similar theme: When to Use Grpc

Define Your Service

Defining your service is the first step in creating a gRPC service. It involves using protocol buffers to define RPC service methods and their message request and response types.

Credit: youtube.com, Servers: What are they? Client - Server Relationship explained | Blonde Dictionary

You can start by defining the methods your service will provide. gRPC-web, like all gRPC services, uses protocol buffers for this purpose.

The methods you define will determine how your service interacts with clients. This includes the data that is sent and received in each interaction.

To define your service, you'll need to create a .proto file. This file contains the protocol buffer definitions for your service.

The .proto file will specify the message request and response types for each method. This is where you'll define the structure of the data that is sent and received.

A different take: Index Html File

Run Server and Proxy

To run a gRPC server, you need to implement the service interface, just like in our Echo service example. This involves creating a server that can handle requests and send responses back to the client.

A gateway proxy is also necessary to allow the client to connect to the server. Our example uses the Envoy proxy to achieve this.

Credit: youtube.com, Proxy vs Reverse Proxy vs Load Balancer | Simply Explained

To get started, you'll need to build a simple Node gRPC backend server, similar to the one we've implemented for the Echo service. This will provide the foundation for your server to handle requests.

The Envoy proxy will then act as a gateway, allowing the client to connect to the server. This setup enables communication between the client and server.

Example Envoy Configuration

An Envoy proxy is a type of gateway proxy that allows clients to connect to a gRPC server.

For an Envoy proxy, you'll need to configure it to listen for HTTP client connections on a specific port. In the example, the port is 8080.

The Envoy configuration for this is a standard HTTP configuration, but with a few small differences.

Here are the key differences:

  • A handful of atypical headers — x-grpc-web, grpc-status, and grpc-message — are required for handling gRPC-Web client requests.
  • The built-in envoy.grpc_web HTTP filter performs the “heavy lifting” for gRPC-Web proxying.
  • The http2_protocol_options: {} specifies that the auth_service takes HTTP/2 (in this case gRPC) connections.

Interoperability and Support

Multiple proxies support the gRPC-web protocol, making it a flexible choice for developers. The current default proxy is Envoy, which supports gRPC-web out of the box. You can try using the gRPC-web Go Proxy or Apache APISIX, which also have gRPC-web support.

Credit: youtube.com, Service Interoperability With gRPC - Varun Gupta & Tuhin Kanti Sharma, Salesforce

Most modern browsers support the Fetch API, allowing for efficient reading of partial, binary responses. This includes Chrome >= 41, Firefox >= 38, Edge >= 13, IE >= 11, and Safari >= 8. For older browsers, gRPC-Web falls back to XMLHttpRequest or HTTP/1.1 chunk responses.

You can also use the @improbable-eng/grpc-web client in a Node.js environment, which uses the http and https packages. However, if you're using Typescript, you'll need to include "dom" in your tsconfig.json file to avoid compilation issues.

Proxy Interoperability

Proxy interoperability is key to ensuring seamless communication between different systems. Multiple proxies support the gRPC-web protocol, including Envoy, which supports gRPC-web out of the box.

You can try using the gRPC-web Go Proxy, which is another option for proxying gRPC-web requests. This option can be used by running `docker-compose up -d node-server grpcwebproxy binary-client`.

Apache APISIX has also added gRPC-web support, and more details can be found on their website. Nginx has a gRPC-web module that seems to work with simple configs, according to user feedback.

Here are some popular proxies that support gRPC-web:

Custom Interceptors

Credit: youtube.com, Process Sentry - The interoperability software

Custom Interceptors are a powerful feature of the @improbable-eng/grpc-web client. They allow you to implement custom logic for features like authentication and retries.

You can implement and chain multiple interceptors, making it easy to add new functionality to your gRPC client. There are two types of interceptors: UnaryInterceptor and StreamInterceptor.

UnaryInterceptor is specifically designed for Unary RPCs and can only be used with Promise clients. On the other hand, StreamInterceptor is more versatile and can be used with regular clients.

Here are the two types of interceptors in a handy list:

  • UnaryInterceptor: for Unary RPCs, only works with Promise clients.
  • StreamInterceptor: more versatile, works with regular clients.

Custom interceptors are a great way to extend the functionality of the @improbable-eng/grpc-web client and make it more suitable for your specific use case.

Frontend Development

gRPC-Web is a cutting-edge spec that enables invoking gRPC services from modern browsers.

Components of the stack are based on Golang and TypeScript, including grpcweb, grpcwebproxy, ts-protoc-gen, and @improbable-eng/grpc-web.

The @improbable-eng/grpc-web client library for browsers (and Node.js) uses multiple techniques to efficiently invoke gRPC services.

Credit: youtube.com, What Is GRPC Web? - Next LVL Programming

Most modern browsers support the Fetch API, which allows for efficient reading of partial, binary responses. For older browsers, it automatically falls back to XMLHttpRequest.

Browser support includes Chrome >= 41, Firefox >= 38, Edge >= 13, IE >= 11, and Safari >= 8.

The @improbable-eng/grpc-web client also supports Node.js through a transport that uses the http and https packages.

To use the @improbable-eng/grpc-web client in a Node.js environment with TypeScript, you must include 'dom' in the "lib" array in your tsconfig.json.

Here are the supported browsers for gRPC-Web:

Configuration and Settings

To configure gRPC-Web, you need to add a reference to the Grpc.AspNetCore.Web package and configure the app to use gRPC-Web by adding UseGrpcWeb and EnableGrpcWeb to Program.cs.

In ASP.NET Core, you can enable gRPC-Web by adding the gRPC-Web middleware, UseGrpcWeb, after routing and before endpoints. This middleware is necessary to support gRPC-Web alongside HTTP/2 gRPC.

Specify new GrpcWebOptions { DefaultEnabled = true } when the middleware is added to configure all services to support gRPC-Web by default.

For more insights, see: Can I Use Webp

Credit: youtube.com, Resolving Protocol Error When Connecting Envoy to gRPC Service with gRPC Web

A known issue causes gRPC-Web to fail when hosted by HTTP.sys in .NET Core 3.x. However, a workaround is available in Grpc-web experimental.

To use gRPC-Web with the .NET gRPC client, you need to add a reference to the Grpc.Net.Client.Web package and ensure the reference to Grpc.Net.Client package is version 2.29.0 or later.

The GrpcWebHandler has two configuration options: InnerHandler and GrpcWebMode. InnerHandler is the underlying HttpMessageHandler that makes the gRPC HTTP request, and GrpcWebMode specifies whether the gRPC HTTP request Content-Type is application/grpc-web or application/grpc-web-text.

Here are the configuration options for GrpcChannelOptions.HttpVersion and GrpcChannelOptions.HttpVersionPolicy:

Generated gRPC clients have both synchronous and asynchronous methods for calling unary methods. However, asynchronous methods are always required in Blazor WebAssembly, as calling a synchronous method can cause the app to become unresponsive.

Known Limitations

As you explore the world of grpc web, it's essential to be aware of its limitations.

There are certain caveats to using grpc web in web browsers.

You can find a comprehensive list of these caveats in the @improbable-eng/grpc-web client Transport Documentation.

Frequently Asked Questions

Is gRPC-web faster than REST?

gRPC-web is generally faster than REST due to its use of the HTTP/2 protocol and Protocol Buffers. However, the choice between gRPC-web and REST ultimately depends on your specific use case and priorities.

Is gRPC just HTTP?

No, gRPC is not just HTTP, as it's designed to work with the more efficient HTTP/2 protocol, offering significant performance benefits. gRPC builds upon HTTP/2's binary framing and compression features to provide a faster and more compact communication framework.

Patricia Dach

Junior Copy Editor

Patricia Dach is a meticulous and detail-oriented Copy Editor with a passion for refining written content. With a keen eye for grammar and syntax, she ensures that articles are polished and error-free. Her expertise spans a range of topics, from technology to lifestyle, and she is well-versed in various style guides.

Love What You Read? Stay Updated!

Join our community for insights, tips, and more.