Welcome back to the Tech Radar bulletin. In modern Microservices architecture, maintaining a system capable of communicating flexibly both externally (HTTP) and internally (gRPC) is an essential requirement. Simultaneously, State Management in distributed environments demands rigorous solutions to prevent data collisions.
Today, we will dissect how to combine Go’s highly acclaimed Kratos framework with Dapr v1.15 to comprehensively solve this problem.
1. Kratos Dual-Protocol: HTTP & gRPC Running in Parallel
Answer-first: The Kratos framework integrates with Dapr v1.15 State Management via the sidecar pattern, allowing HTTP and gRPC servers to run concurrently. To avoid state collisions when running dual-protocol, the system uses Dapr ETags via SaveStateWithETag for Optimistic Concurrency Control, and uses Middleware for Metadata synchronization.
Protocol-First Design with Protobuf
Kratos utilizes Protobuf as the single source of truth. From a single .proto file, Kratos auto-generates code for both gRPC and HTTP RESTful APIs. This frees developers from writing manual routing logic for each protocol type.
Unified Transport Layer (Solving DRY for Middleware)
The architectural brilliance of Kratos lies in its abstracted Transport layer. Instead of configuring Middleware (such as Logging, Authentication, Tracing) separately for HTTP and gRPC, you only need to write it once. The Unified Transport layer applies these Middlewares uniformly across both servers, completely eliminating code duplication (DRY).
2. Dapr v1.15 State Management: Pluggable Architecture & ETags
Answer-first: Dapr v1.15 manages state through a pluggable architecture, abstracting the underlying database (Redis, PostgreSQL). Specifically, Dapr provides an Optimistic Concurrency Control (OCC) mechanism utilizing ETags to entirely prevent lost updates in distributed environments.
The Power of the Dapr Sidecar
Dapr runs as a sidecar completely isolated from the application logic. When Kratos needs to store state, it does not care whether the underlying database is MongoDB or Redis. Kratos simply calls the Dapr API over HTTP or gRPC on localhost.
Optimistic Concurrency Control (OCC) with ETags
In Kratos’s Dual-Protocol model, an HTTP request and a gRPC request might attempt to modify a record simultaneously. To resolve this, Dapr attaches an ETag to every state record. When Kratos updates data, it must send the current ETag along with the request. Dapr will reject the transaction if the ETag does not match (meaning the data has already been modified by another process).
3. Integrating Kratos and Dapr: Solving State Collisions & Metadata
Answer-first: For flawless integration, developers use the Dapr Go SDK to call the SaveStateWithETag function, combined with Kratos Middleware to propagate context.Context seamlessly. This ensures all tracking IDs and ETags are preserved when moving between the HTTP/gRPC layers and the Dapr Sidecar.
Code snippet: SaveStateWithETag using Dapr Go SDK
When saving data, it is mandatory to fetch the ETag first, process the logic, and save it back alongside that specific ETag.
item, err := client.GetState(ctx, storeName, key, nil)
// ... logic to increment counter ...
err = client.SaveStateWithETag(ctx, storeName, key, data, item.Etag, nil)
Critical Note on Metadata Propagation
Kratos translates information from HTTP headers and gRPC metadata into context.Context. For the Dapr Sidecar to recognize these tracing or auth tokens, you must pass this ctx into every Dapr SDK function call. Neglecting the context will fracture the Distributed Tracing flow.
4. Q&A: Practical Bottlenecks (FAQ)
Answer-first: Integrating Kratos and Dapr brings flexibility but requires optimizing local network configurations, managing application lifecycles (graceful shutdown), and building sensible retry strategies to minimize latency overhead.
Does the Dapr Sidecar increase Kratos gRPC latency?
app-channel) and enable the keep-alive feature to reuse connections.How do I test Kratos and Dapr locally using Docker Compose?
network_mode: "service:kratos-app" declaration. This accurately simulates the network model of a Pod on Kubernetes.How do you configure Graceful Shutdown for Kratos and Dapr?
terminationGracePeriodSeconds parameter on Kubernetes is greater than Dapr’s dapr.io/graceful-shutdown-seconds annotation value to prevent the sidecar from being killed before Kratos finishes processing the final request.Does Dapr State Management support Data Querying/Filtering?
/query API (currently in alpha). It supports EQ, IN, AND, OR operators on JSON data. However, this feature is primarily compatible with databases that support complex JSON querying, like MongoDB or PostgreSQL.How do I auto-retry when a State update encounters a 409 Conflict error?
resiliency.yaml file, and Dapr will automatically handle it when an ETag encounters a 409 Conflict error.Read our upcoming articles on the Kratos Framework, Microservices with Dapr, and the System Design Series on the blog to continue following practical microservices patterns.