Technologies
What I work with, and how
The technologies behind my backend and cloud work, grouped by discipline. For each: what it is, and the judgement I apply when using it.
Backend engineering
Where most of my work lives: services and APIs that behave predictably under failure.
.NET and C#
Microsoft’s runtime and language for server-side applications, and the foundation of my backend work.
How I approach it
I lean on the type system to make invalid states hard to represent, keep controllers and handlers thin, and put business rules where they can be tested without infrastructure.
REST APIs
HTTP-based interfaces between services and towards external systems.
How I approach it
I treat an API as a contract: explicit, versioned where it needs to be, and shaped by what consumers need rather than by how the service is built inside.
Cloud & infrastructure
Managed Azure services first, with environments that can be reproduced and reviewed.
Azure Functions
Serverless compute for event-driven and scheduled work.
How I approach it
A good fit for small, single-purpose handlers triggered by messages or events. I keep functions thin and idempotent, because triggers can fire more than once.
Azure App Service
Managed hosting for web applications and APIs.
How I approach it
A sensible default for services that run continuously. I prefer managed hosting to operating infrastructure myself unless there is a clear reason not to.
Azure API Management
A gateway in front of APIs for authentication, routing, throttling and monitoring.
How I approach it
It gives one place to apply cross-cutting policy and observe traffic, so individual services don’t each have to reimplement it.
Infrastructure as code
Defining cloud resources in version-controlled code instead of manual configuration.
How I approach it
Environments should be reproducible and reviewable. A change that can’t be reviewed in a pull request is hard to trust.
CI/CD
Automated build, test and release pipelines.
How I approach it
The pipeline should be the normal path to production, so that releasing is routine and repeatable rather than an event.
Distributed systems
Service boundaries, messaging and data ownership — and being honest about the cost of each.
Microservices
An architecture of independently deployable services, each with its own responsibilities and data.
How I approach it
A trade-off, not a default. They pay off when team structure and domain boundaries justify the operational cost; otherwise a well-structured monolith is often the better choice.
Event-driven architecture
Services communicate by publishing and consuming events and messages instead of calling each other directly.
How I approach it
It reduces coupling and absorbs spikes, but moves complexity into delivery guarantees, ordering and debugging — so handlers must be idempotent and flows observable.
Azure Event Hubs
A high-throughput service for ingesting and streaming events.
How I approach it
Suited to large volumes of events that several consumers read independently. I design consumers to tolerate replays and uneven delivery.
Azure Service Bus
A message broker with queues, topics, dead-lettering and delivery guarantees.
How I approach it
Delivery is at-least-once, so handlers must be safe to repeat.
Related article: Idempotency is not optional
Data ownership and service boundaries
Each service owns its data and exposes it through contracts rather than shared tables.
How I approach it
I draw boundaries around ownership of data and rate of change, which keeps services independently evolvable.
Data & persistence
Relational by default for transactional data.
Azure SQL
A managed relational database service based on SQL Server.
How I approach it
I check the generated queries and indexes early rather than discovering performance problems in production.
Related article: Finding the N+1 queries hiding in your EF Core code
Commerce & integrations
Commerce infrastructure and the integrations around it.
Enterprise and external API integrations
Connecting business systems and third-party services reliably.
How I approach it
External systems fail and change. I isolate each integration behind a stable contract of my own and plan for retries, timeouts and partial failure.
Related article: Stop letting every service talk to the outside world
Optimizely CMS and Commerce
A .NET-based platform for content management and commerce.
How I approach it
Content models are what editors work in every day, so I model them deliberately.