So far the Kladde works only when someone opens a page or asks an endpoint. In this module it gets work that happens without a request, and connections to other systems: at night it fetches public tenders of the EU from TED, and after a booking it sends a confirmation by mail with a link. Both sound simple. It gets hard when something goes wrong: the external API doesn't answer, answers nonsense or redirects to a sign-in page; the process dies between saving and sending; a retry sends the same mail twice. These cases are what the five lessons are about.
In this first lesson, the Kladde builds a client for TED's search API. You learn how .NET manages HttpClient objects, how to meet an
external answer, and how to test all of that without a test needing the network.
An HttpClient, but done right
In module 1.9 you queried an address with HttpClient. In a program that runs once and ends, it doesn't matter how you create the client. In
a web app that runs for weeks, there are two traps:
- A new
HttpClientfor every call opens its own connections every time. AfterDispose, the operating system's ports stay occupied for a while. Under load they run out, and calls fail with aSocketException. - A single
HttpClientfor the whole runtime keeps its connections open and never asks for the DNS name again. If the external service moves to another address, the app keeps talking to the old one.
The HttpClientFactory solves both. It manages the parts that hold connections (the HttpMessageHandlers), keeps them in a pool and
replaces them after a while, by default after two minutes. An HttpClient from the factory, on the other hand, is light: you may fetch it
often and throw it away.
Most convenient is a typed client: a class of its own that gets a ready-configured HttpClient in its constructor and offers
business-level methods to the outside, such as SearchAsync instead of PostAsJsonAsync. You register it with AddHttpClient<T>. The
factory creates it anew for the container on every request (lifetime Transient, lesson 2.3.3). A rule follows that becomes important in lesson
2.8.2: A typed client never belongs in a singleton. There it would live forever, and the factory could no longer replace its connections.