Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Global Error Handling: Catching All Errors in a Single Place
We cover catching unexpected errors from anywhere in the app in a single place: escaping scattered try-catch blocks, setting up exception middleware, and returning a clean, safe response to the user.
Logging: ILogger, Serilog and Structured Logging
We cover logging: the basics of ILogger, log levels, the difference between plain-text and structured logging, and why Serilog makes this job much more powerful in serious projects.
Configuration and the Options Pattern: appsettings Layers and Separating Settings from Code
We cover separating settings from code: appsettings files and environment layers, managing connection strings safely, reading settings with strong types via the Options pattern, and keeping secrets out of code.
Async/await: Correct Asynchronous Usage in an API
We cover what async/await actually does: the difference between sync and async, what a Task is, why an API should be asynchronous, its effect on scalability, and common mistakes.
Pagination, Filtering and Sorting: Returning Large Lists Efficiently
We cover returning a list with thousands of records efficiently: pagination, filtering, and sorting; the lazy nature of IQueryable, the Skip/Take logic, and running the query in the database.
API Versioning: Evolving Your API Without Breaking Old Clients
We cover how not to break old clients while evolving the API over time: what a breaking change is, why versioning is needed, the URL/header/query methods, and setting up versioning in .NET.
Authentication and Authorization: The Difference Between Identity Verification and Permission
We separate two concepts most developers confuse: authentication (who are you?) and authorization (what are you allowed to do?). The difference, the correct order, and how these are positioned in .NET.
Authentication with JWT: How a Token Is Created and Verified
We cover authentication with JWT: what a token is, what its three parts mean, why it's signed, why the server is stateless, and setting up token creation and verification in .NET step by step.
Role- and Policy-Based Authorization: Deciding Who Is Allowed to Do What
We deepen authorization: what role-based permission is, where it falls short, how the policy and claim-based approach offers a more flexible solution, and how we set these up in .NET.
CORS, Rate Limiting and Security Headers: Hardening the API Against External Threats
We cover three topics that harden the API against misuse: controlling which sites can access it with CORS, limiting requests with rate limiting, and adding basic protection with security headers.
Documentation with Swagger/OpenAPI and Scalar: Make Your API Self-Describing
We cover API documentation: what OpenAPI is, why automatic documentation matters, OpenAPI support in .NET 9, and setting up interactive docs with Swagger UI and a modern alternative, Scalar.
Unit Testing: Testing Pieces of Code in Isolation with xUnit and Moq
We cover unit testing: what testing a unit in isolation means, why we write tests, the test structure with xUnit, faking dependencies with Moq, and the basic principles of writing good tests.