Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
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.
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.
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.
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.
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.
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.
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.
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.
Dependency Injection in Depth: Singleton, Scoped and Transient Lifetimes
We cover the lifetime concept at the heart of dependency injection. The difference between singleton, scoped and transient, when to use each, and the subtle bugs a wrong choice causes.
DTO-Entity Conversion: Writing It by Hand or Using AutoMapper?
We discuss the conversion between entity and DTO. The upsides of manual mapping, when AutoMapper is a convenience and when a hidden cost, and a practical look at which to choose in your project.
Is the Repository Pattern Really Necessary? Let's Talk About the Service Layer
We discuss placing a layer between the controller and DbContext instead of using it directly. What the service layer is for, whether the repository pattern is really necessary, and when it pays off.
Introduction to Entity Framework Core: DbContext and Your First Migration
We start storing our data in a real database. What EF Core is, what DbContext represents, how tables are defined with DbSet, and how the database is created with the first migration, step by step.