Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
4 changes: 3 additions & 1 deletion 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,7 +101,7 @@ Run `buf generate` — it creates typed Go interfaces from your proto definition
│ │ Gateway │──► │ │ │
│ │ (grpc- │ │ ► Response Time │ │
gRPC Request ──► │ │ gateway)│ │ ► Trace ID │ │
│ └─────────┘ │ ► OpenTelemetry │ │
│ └─────────┘ │ ► Proto Validate │ │
│ │ │ ► Prometheus │ │
│ ▼ │ ► Error Notify │ │
│ ┌─────────┐ │ ► Panic Recovery │ │
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Expand Down Expand Up @@ -188,3 +189,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
18 changes: 10 additions & 8 deletions architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,11 @@ When a request arrives at a ColdBrew service, it flows through several layers:
│ │ │ │
│ │ 1. Response Time Logging │ │
│ │ 2. Trace ID Injection │ │
│ │ 3. Prometheus Metrics │ │
│ │ 4. Error Notification (Sentry/Rollbar) │ │
│ │ 5. New Relic Transaction │ │
│ │ 6. Panic Recovery │ │
│ │ 3. Proto Validate │ │
│ │ 4. Prometheus Metrics │ │
│ │ 5. Error Notification (Sentry/Rollbar) │ │
│ │ 6. New Relic Transaction │ │
│ │ 7. Panic Recovery │ │
│ │ (OTEL tracing via gRPC stats handler) │ │
│ │ │ │
│ └────────────────────┬─────────────────────┘ │
Expand Down Expand Up @@ -200,10 +201,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

First, add `buf.build/bufbuild/protovalidate` to your `buf.yaml` deps and run `buf dep update`. Then add 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