A middleware is a pass through component that can inspect the route and modify the request and response as needed. Middlewares are chained together to form the pipeline. Each middleware is able to choose whether to pass the request to the next component and decide what actions to take before and after that.
The main method of the
Startup class is the entry point of the application and calls
ConfigureServices defines the features available to the application (in this example caching and scoped dependency injection for the QRCode generator) whereas
Configure defines the middlewares that make up the pipeline. The
MapWhen method sets up the QRCode middleware based on a condition (request path and verb) to be satisfied by the predicate. If that condition is not met, the next middleware is invoked to return 400 bad request status code and a message about how to properly use the api.
The QR code middleware is handled in a separate class which follows the Explicit Dependencies Principle and exposes its dependencies in the constructor. It does not inherit from or implement other types. All the dependencies are resolved by the DI container at runtime if they are properly registered. The middleware class defines an async Invoke method which will be called by the underlying infrastructure to fulfill its task.
In this api, the Invoke method parses and validates the query string parameters before using them to build the QR code as an Image, which it then adds to the response's body. The QR code generator uses QRCode.Net to build the image.
Once an image is generated, it is cached for subsequent requests. The api can be referenced directly in the src of an img tag. The full source code is available on my github repo.