Розробка gRPC API для мікросервісів та веб-застосунків
Уявіть: мікросервісна архітектура з десятків сервісів, кожен спілкується по REST, але зі зростанням навантаження починаються проблеми — затримки зростають, а помилки типізації час від часу прориваються в продакшен. Інтеграція вимагає постійного узгодження контрактів, а для real-time функціональності доводиться винаходити велосипеди з WebSocket. Ми пройшли цей шлях не раз, і gRPC став для нас стандартним інструментом для внутрішніх API.
gRPC — RPC-фреймворк від Google на основі Protocol Buffers та HTTP/2. Він забезпечує строгу типізацію через .proto-файли, двонаправлений стрімінг та значно менший overhead порівняно з JSON. Найбільш доречний для міжсервісної взаємодії та мобільних клієнтів з обмеженим каналом.
Чому gRPC швидший за REST?
Продуктивність gRPC у 5–10 разів вища на великих повідомленнях завдяки бінарній упаковці та HTTP/2 мультиплексуванню. У наших навантаженнях перехід з REST на gRPC скоротив час відповіді з 45 мс до 8 мс, а трафік зменшився на 60% через компактні протобуфери. Це особливо критично для сервісів з високою частотою запитів — наприклад, агрегаторів даних або платіжних систем.
Що таке Protocol Buffers?
Контракт сервісу визначається у .proto файлах:
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); } З .proto генерується код для будь-якої мови: protoc --go_out=. --go-grpc_out=.. Генерація клієнтів на TypeScript або Python — пара команд.
Розробка сервера на 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 } // Запуск сервера lis, _ := net.Listen("tcp", ":50051") grpcServer := grpc.NewServer(grpc.UnaryInterceptor(authInterceptor)) pb.RegisterArticleServiceServer(grpcServer, &ArticleServer{db: db}) grpcServer.Serve(lis) Перехоплювачі — аналог middleware: автентифікація, логування, трасування (OpenTelemetry), rate limiting. Приклад перехоплювача:
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) } Ми налаштовуємо ланцюжок перехоплювачів, щоб ізолювати наскрізну функціональність від бізнес-логіки.
Як gRPC підтримує стрімінг?
gRPC пропонує чотири типи взаємодії:
// Unary (звичайний запит/відповідь) rpc GetArticle(Request) returns (Response); // Server streaming (один запит → потік відповідей) rpc WatchUpdates(Request) returns (stream Event); // Client streaming (потік запитів → одна відповідь) rpc UploadChunks(stream Chunk) returns (UploadResult); // Bidirectional streaming rpc Chat(stream Message) returns (stream Message); Серверний стрімінг зручний для real-time сповіщень, експорту великих обсягів даних і live-результатів пошуку. В одному з проєктів для IoT-платформи ми використовували bidirectional streaming для передачі телеметрії від сотень пристроїв — затримка склала менше 20 мс.
gRPC у браузері та сучасні альтернативи
Напряму gRPC не працює в браузері через обмеження HTTP/2 binary framing. Рішення:
- gRPC-Web — спеціальний протокол з Envoy proxy на стороні сервера.
- Connect (Buf) — сучасна альтернатива, яка працює з HTTP/1.1 і HTTP/2, сумісна з gRPC.
buf generate --template buf.gen.yaml Buf також надає Schema Registry для централізованого зберігання .proto-файлів і версіонування контрактів.
Що входить у розробку gRPC API?
| Deliverable | Опис |
|---|---|
| Контракти .proto | Проектування та версіонування контрактів |
| Кодогенерація | Автоматична генерація клієнтів для Go, TypeScript, Python |
| Серверна частина | Реалізація бізнес-логіки, перехоплювачі, стрімінг |
| gRPC-Web інтеграція | Налаштування Envoy або Connect для браузерних клієнтів |
| Документація | Автоматична документація з .proto (Buf Schema Registry) |
| Тестування | Модульне, інтеграційне, навантажувальне тестування |
| Моніторинг | Метрики через OpenTelemetry, логування |
Як розробити gRPC API: покрокова інструкція
- Визначте контракти у
.protoфайлах, продумайте всі типи повідомлень і RPC-методи. - Згенеруйте код сервера та клієнта за допомогою
protocабоbuf generate. - Реалізуйте бізнес-логіку сервера, впровадьте перехоплювачі для автентифікації та логування.
- Налаштуйте стрімінг, якщо потрібна real-time передача даних.
- Інтегруйте з gRPC-Web або Connect, якщо клієнти працюють з браузера.
- Протестуйте API за допомогою gRPCurl або Postman, перевірте типобезпеку.
- Задеплойте сервіси в Kubernetes, підключіть моніторинг через OpenTelemetry.
Приклад використання gRPCurl
grpcurl -plaintext localhost:50051 articles.v1.ArticleService/GetArticle Порівняння gRPC та REST
| Параметр | gRPC | REST |
|---|---|---|
| Формат даних | Protocol Buffers (бінарний) | JSON/XML (текстовий) |
| Протокол | HTTP/2 | HTTP/1.1 / HTTP/2 |
| Стрімінг | Підтримується (всі 4 типи) | Ні (потрібен WebSocket) |
| Контракт | Строгий (.proto) | Вільний (OpenAPI) |
| Продуктивність | Висока (низький overhead) | Середня |
| Підтримка браузера | Через gRPC-Web/Connect | Нативна |
Джерело: офіційна документація gRPC
Коли обрати gRPC?
gRPC виправданий при міжсервісній взаємодії всередині інфраструктури, коли потрібен строгий контракт між командами, для ефективного бінарного протоколу в IoT і мобільних застосунках, а також якщо потрібен двонаправлений стрімінг. Для публічних API та браузерних клієнтів без gRPC-Web частіше підходять REST або GraphQL. Замовте консультацію — допоможемо визначитися з вибором.
Наш досвід
Понад 10 років ми розробляємо високонавантажені API для fintech, e-commerce та IoT. У портфоліо — 50+ успішних проєктів на Go та TypeScript. Ми гарантуємо надійність та продуктивність вашого gRPC-рішення. Зв'яжіться з нами для оцінки вашого проєкту.







