Application Development.

Most of my recent work is .NET 8 microservices with an Angular front end, and the plumbing that holds them together.

APIs and gateways.

A single public API in front of the services. It validates every token, checks that the token was issued for this API, and forwards the call to the service that owns the data.

Identity.

Sign-in with OAuth 2 and OpenID Connect on Duende IdentityServer. The browser holds only a session cookie; a backend-for-frontend keeps the tokens on the server. Services take the user's identity from the token and check ownership on every read and write, never from an ID the client sends.

Messaging.

Services publish events over AMQP 1.0 on RabbitMQ. A process manager turns "a bill was created" into "debit these balances", so no service has to call another and wait. Failed messages go to a dead-letter queue instead of disappearing, and handlers are written to be safe when a message arrives twice.

Shared libraries.

The messaging client the services share is my own NuGet package, versioned and released through a pipeline. Finding and fixing a connection leak in it is one of my favourite debugging stories.

Delivery.

Every service builds to a container image and deploys through Azure DevOps pipelines. Changes go in through pull requests, and bugs are tracked with IDs that link the report, the fix and the release.