gRPC API Development for Web Application

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Developing gRPC API for Web Application

gRPC is an RPC framework from Google based on Protocol Buffers and HTTP/2. Provides strict typing via .proto files, bidirectional streaming, and significantly lower overhead compared to JSON. Most appropriate for inter-service communication (microservices) and mobile clients with limited bandwidth.

Protocol Buffers

Service contract is defined in .proto files:

syntax = "proto3";
package articles.v1;

import "google/protobuf/timestamp.proto";

message Article {
  string id = 1;
  string title = 2;
  string body = 3;
  string author_id = 4;
  repeated string tag_ids = 5;
  google.protobuf.Timestamp created_at = 6;
}

message GetArticleRequest { string id = 1; }
message ListArticlesRequest {
  int32 page = 1;
  int32 limit = 2;
  string status = 3;
}
message ListArticlesResponse {
  repeated Article articles = 1;
  int32 total = 2;
}

service ArticleService {
  rpc GetArticle(GetArticleRequest) returns (Article);
  rpc ListArticles(ListArticlesRequest) returns (ListArticlesResponse);
  rpc CreateArticle(CreateArticleRequest) returns (Article);
  rpc WatchArticle(GetArticleRequest) returns (stream Article); // server streaming
}

Code is generated for any language from .proto: protoc --go_out=. --go-grpc_out=..

Server Implementation (Go)

type ArticleServer struct {
    pb.UnimplementedArticleServiceServer
    db *sql.DB
}

func (s *ArticleServer) GetArticle(ctx context.Context, req *pb.GetArticleRequest) (*pb.Article, error) {
    row := s.db.QueryRowContext(ctx, "SELECT id, title, body FROM articles WHERE id = $1", req.Id)
    var a pb.Article
    if err := row.Scan(&a.Id, &a.Title, &a.Body); err != nil {
        if errors.Is(err, sql.ErrNoRows) {
            return nil, status.Error(codes.NotFound, "article not found")
        }
        return nil, status.Error(codes.Internal, err.Error())
    }
    return &a, nil
}

// Server startup
lis, _ := net.Listen("tcp", ":50051")
grpcServer := grpc.NewServer(grpc.UnaryInterceptor(authInterceptor))
pb.RegisterArticleServiceServer(grpcServer, &ArticleServer{db: db})
grpcServer.Serve(lis)

Streaming

gRPC supports 4 interaction types:

// Unary (standard request/response)
rpc GetArticle(Request) returns (Response);

// Server streaming (one request → stream of responses)
rpc WatchUpdates(Request) returns (stream Event);

// Client streaming (stream of requests → one response)
rpc UploadChunks(stream Chunk) returns (UploadResult);

// Bidirectional streaming
rpc Chat(stream Message) returns (stream Message);

Server streaming is useful for: real-time notifications, exporting large data volumes, live results.

Interceptors

func authInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    md, ok := metadata.FromIncomingContext(ctx)
    if !ok {
        return nil, status.Error(codes.Unauthenticated, "missing metadata")
    }
    token := md.Get("authorization")
    if !validateToken(token[0]) {
        return nil, status.Error(codes.Unauthenticated, "invalid token")
    }
    return handler(ctx, req)
}

Interceptors are middleware analogs: logging, auth, tracing (OpenTelemetry), rate limiting.

gRPC in Browser

gRPC doesn't work directly in browsers (HTTP/2 binary framing unavailable). Solutions:

  • gRPC-Web—special protocol with Envoy proxy on server side
  • Connect (Buf)—modern alternative, works with HTTP/1.1 and HTTP/2, compatible with gRPC
# Buf CLI for code generation
buf generate --template buf.gen.yaml

Documentation and Testing

  • gRPCurl—curl for gRPC: grpcurl -plaintext localhost:50051 articles.v1.ArticleService/GetArticle
  • Postman—supports gRPC from version 9.7
  • Buf Schema Registry—centralized storage of .proto files

When to Choose gRPC

gRPC is justified for:

  • Inter-service communication within infrastructure
  • Strict contract between teams
  • Need for efficient binary protocol (IoT, mobile)
  • Bidirectional streaming

REST/GraphQL is better for: public APIs, browser clients without grpc-web, quick prototypes.

Timelines

gRPC service (5–10 methods, auth interceptor, proto contract): 1–2 weeks. With bidirectional streaming, service mesh (Istio/Linkerd), gRPC-Web for browser: 2–4 weeks.