Benzene Cookbooks
Practical recipes for common real-world scenarios using Benzene.
What are Cookbooks?
Cookbooks are step-by-step guides that show you how to solve specific problems with Benzene. Each cookbook focuses on a single use case and provides complete, copy-pasteable code that you can adapt to your needs.
Available Cookbooks
Observability
- Diagnosing Failures - A message failed in production: the recommended middleware stack, the log fields you get, and how a failure shows up across logs, traces, and metrics
- Logging to Application Insights - Send structured logs to Azure Application Insights
- Distributed Tracing with OpenTelemetry - Set up end-to-end tracing across services
- Custom Metrics with OpenTelemetry - Track business and performance metrics
- Structured Logging with Serilog - Rich structured logging with Serilog
AWS
- Handling SQS Message Failures - Implement retry and DLQ patterns for SQS
- SNS Fan-Out Pattern - Broadcast events to multiple Lambda functions
- S3 Event Processing - React to S3 object creation/deletion via
Benzene.Aws.Lambda.S3(see the "S3" section) - API Gateway Custom Authorizers (planned -
Benzene.Aws.Lambda.ApiGateway'sApiGatewayCustomAuthorizersupport exists in source but isn't cookbook-documented yet) - Lambda Cold Start Optimization - Reduce cold start times
Azure
- Service Bus Message Handling - Process Service Bus messages with Benzene
- Event Hub Stream Processing - Handle high-throughput Event Hub streams, batching, and checkpointing boundaries
- Cosmos DB Change Feed Processing - Consume a container's change feed as an ordered document stream
- Managed Identity & RBAC for Azure Resources - Run every Azure integration with no connection strings:
DefaultAzureCredentialwiring for the Service Bus/Event Hubs/Cosmos DB workers, identity-based connection settings for the Functions triggers, and the RBAC roles each one needs
Validation & Error Handling
- FluentValidation with Custom Rules - Cross-field rules, async DB validation, and per-rule status overrides
- Global Error Handling - Centralized error handling and logging
- Request/Response Transformations - Transform messages in the pipeline via
.Convert()/ContextConverterMiddleware
Data & Persistence
- Entity Framework Core Integration - Database access patterns
- Redis Caching - Cache handler responses with Redis
- Transactional Outbox - Publish a handler's event atomically with its DB write by swapping the
IResponseEventPublisherbehindUseResponseEventsfor an outbox table + relay
Configuration & Secrets
- Secrets & Multi-Cloud Configuration - A provider-agnostic
ISecretStoreseam (env vars, mounted files, composed, cached), startup fail-fast validation, and copy-paste Key Vault / AWS Secrets Manager / SSM adapters
Testing
- Integration Testing Lambda Functions - Test Lambda handlers end-to-end
- Mocking External Dependencies - Test message handlers in isolation
- Contract Testing (schema compatibility) - Catch breaking contract changes before they reach consumers, at runtime (schema-hash drift check) and in CI (backward-compatibility gate)
- Schema Registry Integration - Register event payload schemas centrally, frame messages with the Confluent wire format for cross-consumer interop, and gate deploys with a byte-identical compatibility check (structural evolution needs a real registry server or your own checker; with copy-paste Confluent / Azure adapters)
- Contract Testing (conformance) - Verify message contracts between services via the conformance-testing approach
Orchestration
- Sagas (distributed transactions that roll back cleanly) - Run a multi-service operation as all-or-nothing: each step carries a compensation, and any failure rolls the whole thing back in reverse (LIFO) order, leaving no orphaned records
- Response as Event - Republish a request/response handler's response payload as a follow-up event on fire-and-forget transports (SQS
order:create→ broadcastorder:created), declaratively viaUseResponseEvents
Cross-Cutting Concerns
- Request Correlation Across Services - Track requests through distributed systems
- Idempotency (de-duplicating redelivered messages) - Ensure a handler's side effect runs at most once per message on at-least-once transports (SQS, Service Bus, Event Hubs, Kafka), with a pluggable store
- Multi-Tenancy - Attribute every request to a tenant and isolate its data/cache using a scoped
TenantHolderset by a resolver middleware (claim / header / subdomain), with a "tenant required" guard - Rate Limiting (planned)
- Polly Resilience Pipelines (circuit breaker, timeout, hedging, fallback) -
Benzene.Resilienceimplements retry-with-backoff only; the siblingBenzene.Resilience.Pollypackage runs your own PollyResiliencePipelineas middleware (.UseResiliencePipeline(...)) for the full toolkit, and bridges a returned failure result to Polly's outcome model - Request Authentication & Authorization - OAuth2 bearer token (JWT) validation, Basic auth, and scope-based authorization for services with no security-terminating gateway in front of them
- Bring Your Own DI Container - Use Lamar, DryIoc, Grace, or any other container behind Benzene with no Benzene-specific package, by plugging its
IServiceProviderinto the host (Benzene ships adapters only for Microsoft DI and Autofac)
Cookbook Structure
Each cookbook follows this structure:
- Problem Statement - What you're trying to achieve
- Prerequisites - What you need before starting
- Step-by-Step Implementation - Detailed walkthrough with code
- Testing - How to verify it works
- Troubleshooting - Common issues and solutions
- Variations - Alternative approaches or extensions
- Further Reading - Related docs and resources
Request a Cookbook
Don't see a cookbook for your use case? Open an issue describing:
- The problem you're trying to solve
- The AWS/Azure services or patterns involved
- Any specific constraints or requirements
Contributing
Want to contribute a cookbook? Check the Contributing section of the main README and submit a PR following the cookbook template.