Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ A Kubernetes-native Go microservice framework for building production-grade gRPC
| **gRPC Reflection** | Server reflection enabled by default — works with [grpcurl], [grpcui], and Postman |
| **HTTP Compression** | Automatic gzip and [zstd] compression for all HTTP gateway responses (content-negotiated via `Accept-Encoding`) |
| **Container-aware Runtime** | Auto-tunes GOMAXPROCS to match container CPU limits via [automaxprocs] |
| **Request Validation** | [Protovalidate] annotations enforced automatically — define validation rules in your proto, get `InvalidArgument` errors for free |
| **CI/CD Pipelines** | Ready-to-use [GitHub Actions] and [GitLab CI] workflows for build, test, lint, coverage, and benchmarks |

## Quick Start
Expand Down Expand Up @@ -100,9 +101,10 @@ Run `buf generate` — it creates typed Go interfaces from your proto definition
│ │ Gateway │──► │ │ │
│ │ (grpc- │ │ ► Response Time │ │
gRPC Request ──► │ │ gateway)│ │ ► Trace ID │ │
│ └─────────┘ │ ► OpenTelemetry │ │
│ │ │ ► Prometheus │ │
│ ▼ │ ► Error Notify │ │
│ └─────────┘ │ ► Proto Validate │ │
│ │ │ ► OpenTelemetry │ │
│ ▼ │ ► Prometheus │ │

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interceptor-chain diagram lists “OpenTelemetry” as part of the chain, but elsewhere in the docs (e.g., architecture.md) OpenTelemetry span creation is described as coming from the otelgrpc stats handler, not an interceptor. This diagram should be updated to avoid implying OpenTelemetry is an interceptor (e.g., label it as stats handler/outside the chain).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — removed from Index.md diagram.

│ │ ► Error Notify │ │
│ ┌─────────┐ │ ► Panic Recovery │ │
Comment thread
coderabbitai[bot] marked this conversation as resolved.
│ │ gRPC │──► │ │ │──► Your Handler
│ │ Server │ │ │ │
Expand Down Expand Up @@ -188,3 +190,4 @@ ColdBrew composes proven Go libraries — not replacements:
[GitLab CI]: https://docs.gitlab.com/ci/
[slog]: https://pkg.go.dev/log/slog
[zstd]: https://datatracker.ietf.org/doc/html/rfc8878
[Protovalidate]: https://github.com/bufbuild/protovalidate
9 changes: 5 additions & 4 deletions architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,11 @@ Interceptors are gRPC middleware that run on every request. ColdBrew chains them
|-------|------------|---------|--------------|
| 1 | Response Time Logging | `interceptors` | Logs method name, duration, and status code |
| 2 | Trace ID | `interceptors` | Generates a trace ID (or reads it from the `x-trace-id` HTTP header or a `trace_id` proto field) and propagates it to structured logs, Sentry/Rollbar error reports, and OpenTelemetry spans (as the `coldbrew.trace_id` attribute) |
| 3 | Prometheus | `interceptors` | Records request count, latency histogram, and status codes |
| 4 | Error Notification | `interceptors` | Sends errors to Sentry/Rollbar/Airbrake asynchronously |
| 5 | New Relic | `interceptors` | Creates a New Relic transaction for APM |
| 6 | Panic Recovery | `interceptors` | Catches panics and converts them to gRPC errors |
| 3 | Proto Validate | `interceptors` | Validates incoming messages using [protovalidate](https://github.com/bufbuild/protovalidate) annotations. Returns `InvalidArgument` on failure. Disable with `DISABLE_PROTO_VALIDATE` |
Comment thread
ankurs marked this conversation as resolved.
| 4 | Prometheus | `interceptors` | Records request count, latency histogram, and status codes |
| 5 | Error Notification | `interceptors` | Sends errors to Sentry/Rollbar/Airbrake asynchronously |
| 6 | New Relic | `interceptors` | Creates a New Relic transaction for APM |
| 7 | Panic Recovery | `interceptors` | Catches panics and converts them to gRPC errors |
Comment thread
coderabbitai[bot] marked this conversation as resolved.

{: .note }
OpenTelemetry tracing spans are created by the `otelgrpc` stats handler configured at the gRPC server/client level, not as an interceptor in the chain.
Expand Down
1 change: 1 addition & 0 deletions config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ cfg := config.GetColdBrewConfig()
| `GRPC_MAX_SEND_MSG_SIZE` | int | `2147483647` | Maximum send message size in bytes (default: ~2GB, unlimited) |
| `GRPC_MAX_RECV_MSG_SIZE` | int | `4194304` | Maximum receive message size in bytes (default: 4MB) |
| `DISABLE_VT_PROTOBUF` | bool | `false` | Disable [vtprotobuf](https://github.com/planetscale/vtprotobuf) marshaller for gRPC. See [vtprotobuf guide](/howto/vtproto) |
| `DISABLE_PROTO_VALIDATE` | bool | `false` | Disable [protovalidate](https://github.com/bufbuild/protovalidate) interceptor. When disabled, proto validation annotations are ignored |

## gRPC TLS

Expand Down
36 changes: 36 additions & 0 deletions howto/interceptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,42 @@ func main() {
}
```

## Proto Validation

ColdBrew includes a [protovalidate](https://github.com/bufbuild/protovalidate) interceptor in the default chain. It validates incoming messages using annotations defined in your `.proto` files and returns `InvalidArgument` on failure.

### Adding validation rules

Add `buf/validate/validate.proto` import and annotations to your proto:

```protobuf
Comment thread
ankurs marked this conversation as resolved.
import "buf/validate/validate.proto";

message CreateUserRequest {
string email = 1 [(buf.validate.field).string.email = true];
string name = 2 [(buf.validate.field).string.min_len = 1];
int32 age = 3 [(buf.validate.field).int32 = {gte: 0, lte: 150}];
}
```

No code changes needed — the interceptor validates automatically.

### Custom constraints

Add custom validation options during `init()`:

```go
func init() {
interceptors.SetProtoValidateOptions(
protovalidate.WithCustomConstraints(myConstraints...),
)
Comment thread
ankurs marked this conversation as resolved.
}
```

### Disabling

Set `DISABLE_PROTO_VALIDATE=true` to skip validation entirely.

## Adding custom interceptors to Default interceptors

You can add your own interceptors to the [Default Interceptors] by appending to the list of interceptors.
Expand Down
Loading