gRPC Between Web and Server: A Simple gRPC Communication

GRPC-Web is a JavaScript client library that allows web applications to talk to gRPC services. Since browsers don’t support HTTP/2 or the binary protocol used by standard gRpc, gR PC-Web provides a way to bridge the gap. The client sends requests to the server using gR PCs using HTTP/1.1 or http/2.


This content originally appeared on HackerNoon and was authored by Jay Ehsaniara

This is a simple gRPC communication between a web client and server with an Envoy proxy.

\ I’m using the gRPC-Web library for this. gRPC-Web is a JavaScript client library that allows web applications to talk to gRPC services. Since browsers don’t support HTTP/2 or the binary protocol used by standard gRPC, gRPC-Web provides a way to bridge the gap by using HTTP/1.1 or HTTP/2 and encoding gRPC messages in a way that browsers can handle. Here’s how gRPC-Web works:

\n 1- The client sends requests to the server using gRPC-Web, which typically uses HTTP/1.1 or HTTP/2. Metadata (like headers) can be attached to the request, such as for authentication (e.g., JWT tokens).

\

The request is encoded in gRPC-Web format, typically using base64 encoding for the binary gRPC payload. The client sends this request over HTTP/1.1 or HTTP/2.

\n 2- Envoy (or another reverse proxy like Nginx) sits between the gRPC-Web client and the gRPC server. Envoy receives the gRPC-Web request, decodes the gRPC-Web payload, and forwards it as a standard gRPC request to the gRPC server using HTTP/2.

\

The gRPC server processes the request as if it were a native gRPC request, using HTTP/2.

\n 3- The gRPC server processes the incoming gRPC request, does the business logic, and generates a response (in this case, the Go written application). The response is encoded in the standard gRPC format and sent back to Envoy.

\n 4- Envoy receives the gRPC response, encodes it in gRPC-Web format (typically base64), and sends it back to the gRPC-Web client over HTTP/1.1 or HTTP/2. Any metadata in the gRPC response, such as status codes, is translated.

\n 5- The gRPC-Web client decodes the response and uses the web application.

\n NOTE: Client-side and Bi-directional streaming is not currently supported (see streaming roadmap)

\n

Architecture overview

Advantages of gRPC-Web

  • Browser Compatibility: Allows modern web applications to interact with gRPC services without needing native support for HTTP/2 and binary protocols.

\

  • Efficiency: Leverages the performance and efficiency of gRPC while adapting it for the web.

Here Is a Working Demo

https://github.com/ehsaniara/gRPC-web-example

Demo Quick Start

docker compose up -d

\n Then, open the browser onhttp://localhost:8081 (note: this demo uses 8081 and 8080 ports)

\ Browser on http://localhost:8081

Project Structure

  • client/: Contains the gRPC-Web client code
  • server/: Contains the gRPC server code written in Go
  • envoy/: envoy configuration file

Prerequisites

\

Proto File

syntax = "proto3";

package helloworld;

option go_package = "./proto"; // Add this line

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Server

Server’s main file (server/main.go):

package main

import (
   "context"
   "google.golang.org/grpc/reflection"
   "log"
   "net"

   pb "github.com/ehsaniara/gRPC-web-example/proto"
   "google.golang.org/grpc"
)

type server struct {
 pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
 return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
 lis, err := net.Listen("tcp", ":50051")
 if err != nil {
  log.Fatalf("failed to listen: %v", err)
 }
 s := grpc.NewServer()
 pb.RegisterGreeterServer(s, &server{})

 // Register reflection service on gRPC server.
 reflection.Register(s)
 if err := s.Serve(lis); err != nil {
  log.Fatalf("failed to serve: %v", err)
 }

 log.Println("Server is running on port 50051")
 if err := s.Serve(lis); err != nil {
  log.Fatalf("failed to serve: %v", err)
 }
}

Envoy Config

...
http_filters:
  - name: envoy.filters.http.grpc_web
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
  - name: envoy.filters.http.cors
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
  - name: envoy.filters.http.router
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
...

Web Client

Client file (client/src/index.js )

// Import the generated gRPC-Web client stubs and message classes
import {GreeterClient} from './generated/helloworld_grpc_web_pb';
import {HelloRequest} from './generated/helloworld_pb';

// Create an instance of the Greeter client
const client = new GreeterClient('http://localhost:8080');

// Function to send a greeting request
function sayHello(name) {
    // Create a new request
    const request = new HelloRequest();
    request.setName(name);

    // Call the sayHello method on the Greeter client
    client.sayHello(request, {}, (err, response) => {
        if (err) {
            console.error('Error:', err.message);
            document.getElementById('output').textContent = 'Error: ' + err.message;
        } else {
            console.log('Greeting:', response.getMessage());
            document.getElementById('output').textContent = 'Greeting: ' + response.getMessage();
        }
    });
}

// Example usage: sending a request when the page loads
document.addEventListener('DOMContentLoaded', () => {
    const name = 'World';
    sayHello(name);
});

\ Run generate.sh to generate *_pb.js files, for which you need to have grpc-web and protoc-gen-js already installed in your machine.

$ npm i grpc-web
$ npm install -g protoc-gen-js

This will generate helloworld_grpc_web_pb.js and helloworld_pb.js files, which already exist in this demo.

\ Here’s a related GitHub project:

https://github.com/ehsaniara/gRPC-web-example?embedable=true

\ \ \


This content originally appeared on HackerNoon and was authored by Jay Ehsaniara


Print Share Comment Cite Upload Translate Updates
APA

Jay Ehsaniara | Sciencx (2024-09-08T19:00:24+00:00) gRPC Between Web and Server: A Simple gRPC Communication. Retrieved from https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/

MLA
" » gRPC Between Web and Server: A Simple gRPC Communication." Jay Ehsaniara | Sciencx - Sunday September 8, 2024, https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/
HARVARD
Jay Ehsaniara | Sciencx Sunday September 8, 2024 » gRPC Between Web and Server: A Simple gRPC Communication., viewed ,<https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/>
VANCOUVER
Jay Ehsaniara | Sciencx - » gRPC Between Web and Server: A Simple gRPC Communication. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/
CHICAGO
" » gRPC Between Web and Server: A Simple gRPC Communication." Jay Ehsaniara | Sciencx - Accessed . https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/
IEEE
" » gRPC Between Web and Server: A Simple gRPC Communication." Jay Ehsaniara | Sciencx [Online]. Available: https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/. [Accessed: ]
rf:citation
» gRPC Between Web and Server: A Simple gRPC Communication | Jay Ehsaniara | Sciencx | https://www.scien.cx/2024/09/08/grpc-between-web-and-server-a-simple-grpc-communication/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.