Practical Guide to gRPC Development for the Huajiao Service Backend
This article presents a comprehensive overview of Huajiao's gRPC development practice, covering background decisions, gRPC features, gateway integration, Dart and Go client libraries, component architecture, protobuf conventions, code generation, SDK integration, documentation tooling, debugging strategies, and future roadmap.
gRPC is a high‑performance, open‑source RPC framework developed by Google on top of HTTP/2. The article introduces Huajiao's server‑side gRPC development practice.
Background : To increase code reuse and reduce development cost on mobile platforms, Huajiao chose Flutter for the client and gRPC for the service interface, allowing the client to focus on business logic while the server handles communication.
gRPC Features include IDL generation via ProtoBuf, HTTP/2 based multiplexing, bidirectional streaming, and strong extensibility. Limitations such as protobuf debugging difficulty and JSON incompatibility are mitigated with a gateway that exposes RESTful endpoints.
gRPC‑Web provides a JavaScript library for browsers but requires an Envoy proxy; in this project the frontend uses the gRPC‑Gateway generated REST API instead.
gRPC‑Gateway is a protoc plugin that translates gRPC services into a reverse‑proxy server, converting JSON REST requests to gRPC calls, simplifying client integration and testing.
Header Mapping from HTTP to gRPC is performed by adding X-Forwarded-For , X-Forwarded-Host , authorization , and any Grpc-Metadata- prefixed headers to the corresponding gRPC metadata.
Example HTTP request mapping to gRPC metadata:
GET /index HTTP/1.1
grpc-metadata-platform: ios
grpc-metadata-device_id: xxxxxxxx
grpc-metadata-timestamp: 1562641496
grpc-metadata-locale: en_US
grpc-metadata-version: 1.0.0
Host: gateway.hostame.comBase Libraries :
Dart : A BaseClient maintains a connection pool and provides metadata for calls.
var base = BaseClient(host: 'rpc.hostame.com', port: 443, secure: true);
final md = await base.metadata;
final stub = AuthClient(base.channel, options: CallOptions(metadata: md));Go : The server combines gRPC and gateway functionality, using interceptors for metrics, logging, authentication, and validation.
svrMux := &ServerMux{ServeMux: http.NewServeMux()}
svrMux.svr = grpc.NewServer(
grpc.UnaryInterceptor(middleware.ChainUnaryServer(
recovery.UnaryServerInterceptor(...),
prometheus.UnaryServerInterceptor,
log.UnaryServerInterceptor(...),
auth.UnaryServerInterceptor(...),
validator.UnaryServerInterceptor(),
)),
grpc.StreamInterceptor(...),
)
svrMux.mux = runtime.NewServeMux(...)
svrMux.ServeMux.Handle("/", svrMux.mux)Component Architecture : Each service component implements a Component interface with methods for naming, storage initialization, gRPC registration, gateway registration, and cron callbacks. Components are registered with base.DefaultServer.RegisterComponent(&user.Component{}) and the server is started via base.DefaultServer.Serve() .
Proto Specification : Interfaces and messages are defined in .proto files with markdown‑compatible comments, options for visibility, access levels, and HTTP bindings.
// ExampleMessage definition
message ExampleMessage { uint64 id = 1; }
service Example {
rpc test (ExampleMessage) returns (ExampleMessage) {
option (auth.access) = { level: LOW_ACCESS_LEVEL };
option (google.api.http) = { post: "/example/test" body: "*" };
}
}Code Generation uses protoc with plugins for Go, gRPC‑Gateway, validation, and authentication, as well as Dart generation for Flutter.
@protoc -Iproto \
-I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc:go/pb \
--grpc-gateway_out=logtostderr=true:go/pb \
--validate_out="lang=go:go/pb" \
--auth_out="lang=go:go/pb" \
proto/*.protoSDK Integration for Go is done via Go modules; for Dart, pubspec.yaml is updated with protobuf and grpc dependencies and the generated package is imported.
dependencies:
flutter:
sdk: flutter
protobuf: ^0.13.4
grpc: ^1.0.1
user:
git:
url: [email protected]:project/repo.git
path: dart/userKnown Issues : Dart's protobuf JSON encoding uses field numbers as keys, causing incompatibility with other languages (see issue #220).
Documentation Generation : A custom protoc-gen-markdown plugin produces markdown API docs with full navigation, based on the same .proto files.
@protoc -Iproto \
-I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--markdown_out=":doc" \
proto/*.protoDebugging : Because gRPC traffic is binary over HTTP/2, traditional packet capture is hard; Huajiao injects request logging on the server side to emulate packet capture for troubleshooting.
Future Plans include adding gRPC streaming support, full‑trace integration, and improving scaffolding to simplify component creation.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.