Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
347 posts found
File-Based Integration: Exchanging Files over SFTP and FTP, Watching Folders, Idempotent Processing and Reconciliation
Backend PART 11

File-Based Integration: Exchanging Files over SFTP and FTP, Watching Folders, Idempotent Processing and Reconciliation

In a file-based integration you read a file only once the other side has marked it ready (a .done marker, or upload under a temporary name and rename), verify the host key, and record processed files in a ledger by content hash, so nothing is processed half-written or twice. In Bookstore we fetch the supplier's stock file over SFTP with SSH.NET and the bank's collections file over FTPS with FluentFTP, and reconcile it against orders.

15 Nov 2026 12 min 8
Calling SOAP Services from .NET: dotnet-svcutil, the WCF Client, WS-Security, Certificates and Resilience
Backend PART 10

Calling SOAP Services from .NET: dotnet-svcutil, the WCF Client, WS-Security, Certificates and Resilience

You call a SOAP service from .NET through the interface dotnet-svcutil generates from the WSDL, your own binding and a ChannelFactory; resilience belongs at the operation level, not the HTTP level, because SOAP faults arrive with HTTP 500 and WCF calls take no CancellationToken. In Bookstore we send institutional invoices to a fake e-invoice integrator with a UsernameToken and mTLS, and make retries safe with the invoice's ETTN.

15 Nov 2026 13 min 11
State Across Requests in MVC: TempData, Session, Cookies and Query Strings — Which One When?
Backend PART 15

State Across Requests in MVC: TempData, Session, Cookies and Query Strings — Which One When?

Use the query string for filters, a consented cookie for preferences, a Data Protection cookie for an anonymous cart, session with Redis for a multi-step form and TempData for flash messages. Running Bookstore.Web on two instances, we show with real output how in-memory session silently resets the form, how separate key rings empty the cart and how cookie consent switches off TempData.

15 Nov 2026 14 min 10
Error Pages in MVC and Razor Pages: UseExceptionHandler, Status Code Pages, Custom 404/500 Views and Error Ids
Backend PART 14

Error Pages in MVC and Razor Pages: UseExceptionHandler, Status Code Pages, Custom 404/500 Views and Error Ids

For pages, use UseExceptionHandler and UseStatusCodePagesWithReExecute: the status code is kept and the address doesn't change, while WithRedirects produces a soft 404 with a 302 and a 200. In Bookstore.Web we show a 404 with suggestions, a 503 page with a trace id, ProblemDetails for /api, IExceptionHandler for domain exceptions and the pitfalls where the error page itself breaks, with real output.

15 Nov 2026 12 min 11
Data Access Options in Node.js: node:sqlite, pg, a Query Builder (Kysely) and an ORM (Prisma) — Which One When?
Backend PART 22

Data Access Options in Node.js: node:sqlite, pg, a Query Builder (Kysely) and an ORM (Prisma) — Which One When?

Data access in Node.js comes in four layers: the built-in node:sqlite for tests and tools, plain SQL with pg for full control, Kysely for compile-time type safety, and Prisma for schemas and migrations. With real output: prices concatenated because numeric arrives as a string, text stored in an INTEGER column, a limit that would not run on SQL Server, a relation difference caught by migrate diff, and an N+1 loop running five queries for four books.

15 Nov 2026 13 min 10
CPU-Bound Work with worker_threads: Workers, MessageChannel, Transferables, Worker Pools (Piscina) and How It Differs from cluster
Backend PART 21

CPU-Bound Work with worker_threads: Workers, MessageChannel, Transferables, Worker Pools (Piscina) and How It Differs from cluster

In Node.js you move CPU-bound work to worker_threads, preferably a worker pool such as Piscina, so the event loop never freezes; large data is transferred as an ArrayBuffer instead of copied, and the worker returns only a summary. With real output: a 947 ms event loop stall versus 11 ms, an 11 ms copy versus a zero-copy transfer, a pooled Buffer that cannot be transferred, a counter losing updates without Atomics, and a new worker per task running 40 times slower.

15 Nov 2026 10 min 11
Everyday Cryptography with node:crypto: randomUUID, Hashes, HMAC, Passwords with scrypt, timingSafeEqual and Web Crypto
Backend PART 20

Everyday Cryptography with node:crypto: randomUUID, Hashes, HMAC, Passwords with scrypt, timingSafeEqual and Web Crypto

In Node.js you verify a webhook signature with createHmac over the raw body and compare it with timingSafeEqual, store passwords with scrypt or the built-in Argon2id, and encrypt sensitive fields with AES-256-GCM and a fresh IV every time. With real output: a signature broken by JSON.stringify, SHA-256 at over two million per second versus 169 ms scrypt, 622 MB for 16 concurrent sign-ins, and a phone number recovered without the key from a fixed IV.

15 Nov 2026 14 min 8
Writing Scripts and CLI Tools in Node.js: process, util.parseArgs, Exit Codes, readline, child_process and Signals
Backend PART 19

Writing Scripts and CLI Tools in Node.js: process, util.parseArgs, Exit Codes, readline, child_process and Signals

A Node.js CLI parses process.argv with util.parseArgs, writes results to stdout and errors to stderr, exits through process.exitCode instead of process.exit, and calls external commands without a shell through execFile or spawn. With real output: an export file never created because of process.exit, strict parseArgs catching a typo, a confirmation that does not ask without a terminal, a command injection through exec, and a script that deletes its temp file on SIGINT.

15 Nov 2026 14 min 9
HTTP Clients in Node.js: fetch, undici, AbortSignal.timeout, Keep-Alive, Streaming Bodies and Retries
Backend PART 18

HTTP Clients in Node.js: fetch, undici, AbortSignal.timeout, Keep-Alive, Streaming Bodies and Retries

In Node.js you call external services with the global fetch, but it is not safe without a response.ok check, AbortSignal.timeout, a body that is read or cancelled, and retries that respect idempotency. With real output: a catch that never runs on a 404, a request waiting 301 seconds, a connection lost to an unread body, a file streamed in 131 MB instead of 329 MB, retry waves without jitter, and a carrier tracking client tested with MockAgent.

15 Nov 2026 15 min 7
End to End: Bookstore Order Documents — Invoice PDF, Confirmation Email and the Monthly Excel Report as a Job Chain
Backend PART 09

End to End: Bookstore Order Documents — Invoice PDF, Confirmation Email and the Monthly Excel Report as a Job Chain

Connect the order documents in a two-step Hangfire chain: the invoice job writes the PDF to storage, the continuation puts the confirmation email in the outbox; each step's key is the very thing it writes, so repeats are harmless. In Bookstore only the invoice step was retried while storage was down, the same order placed twice gave one PDF and one email, and the monthly report is a recurring job on Istanbul time.

15 Nov 2026 11 min 12
A File Storage Abstraction: Local Disk, Azure Blob Storage and S3; Direct Uploads with Presigned/SAS URLs
Backend PART 08

A File Storage Abstraction: Local Disk, Azure Blob Storage and S3; Direct Uploads with Presigned/SAS URLs

Keep files behind one IFileStore: validate the path twice on the local disk, hand out SAS or presigned URLs that live a few minutes for downloads and uploads on Azure Blob and S3, and check an uploaded file only in the "complete" step, because storage looks at neither size nor content. Bookstore's invoices and covers were tested with Azurite and RustFS; metadata stays in the database.

15 Nov 2026 12 min 13
Image Processing in .NET: Resizing, Format Conversion, EXIF and Safe Processing with ImageSharp and SkiaSharp
Backend PART 07

Image Processing in .NET: Resizing, Format Conversion, EXIF and Safe Processing with ImageSharp and SkiaSharp

Validate an uploaded image by its first bytes and pixel count first, then apply the EXIF orientation, shrink it and save it as WebP without metadata. Bookstore's cover thumbnails are made with SkiaSharp (MIT); ImageSharp 4 stays in a Debug-only example, because its Release build needs a license key and it keeps metadata by default.

15 Nov 2026 10 min 13
Blog Map