HTTP Extension
HTTP requests are a must in every app. The Shiny Mediator HTTP extension eliminates the boilerplate of creating mediator contracts, request handlers,
and manual HttpClient usage for every API call. Instead, you define a simple contract with attributes and let Mediator handle the rest.
Why Use the HTTP Extension?
Section titled “Why Use the HTTP Extension?”- Zero boilerplate - Stop writing repetitive request handlers for every API call. Define a contract, decorate it with attributes, and you’re done. No handler class, no manual
HttpClient, no serialization code. - AOT-ready out of the box - All generated code is fully AOT compliant, including optional source-generated JSON serializers. No reflection surprises at runtime.
- Full middleware pipeline - Every HTTP request flows through the Mediator pipeline, giving you access to caching, resilience, offline support, performance logging, and any custom middleware you’ve built.
- DI-powered request decorators - Inject services like authentication providers, device info, or telemetry into HTTP decorators that automatically enrich every outgoing request with headers, tokens, and more.
The Problem
Section titled “The Problem”Consider what you’d normally have to write for every HTTP call:
public class MyHttpRequest : IRequest<MyResponse>{ public string SomeArg { get; set; }}
public class MyHttpRequestHandler(IConfiguration config) : IRequestHandler<MyHttpRequest, MyResponse>{ public async Task<MyResponse> Handle(MyHttpRequest request, IMediatorContext context, CancellationToken cancellationToken) { var baseUri = config.GetValue<string>("HttpUri"); var httpClient = new HttpClient(); var json = JsonSerializer.Serialize(request); var content = new StringContent(json); var message = new HttpRequestMessage(HttpMethod.Post, baseUri + "/somerequest"); // what about headers and auth? OMG... too much
var response = await httpClient.PostAsync(message); response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsStringAsync(cancellationToken); var result = JsonSerializer.Deserialize<MyResponse>(responseJson);
return result; }}The Solution
Section titled “The Solution”With Shiny Mediator HTTP, the same thing becomes:
[Http(HttpVerb.Post, "/somerequest")]public class MyHttpRequest : IHttpRequest<MyResponse>{ [HttpBody] public string SomeArg { get; set; }}
// No handler needed! Just send the request:var response = await mediator.Request(new MyHttpRequest { SomeArg = "value" });Getting Started
Section titled “Getting Started”-
Install the Shiny.Mediator NuGet package (the HTTP extension is included)
-
Define your request contract with HTTP attributes
using Shiny.Mediator;using Shiny.Mediator.Http;[Http(HttpVerb.Post, "/api/users")]public class CreateUserRequest : IHttpRequest<UserResponse>{[HttpBody]public CreateUserDto Body { get; set; }} -
Configure the base URI in your
appsettings.jsonor other configuration provider{"Mediator": {"Http": {"MyApp.Contracts.*": "https://api.myapp.com"}}} -
Send the request through Mediator
var response = await mediator.Request(new CreateUserRequest{Body = new CreateUserDto { Name = "John", Email = "john@example.com" }});
How It Works
Section titled “How It Works”Internally, Shiny Mediator registers a covariant request handler that listens for any IHttpRequest<TResult> contract. When you send a request:
- The handler reads the
[Http]attribute to determine the HTTP verb and route - Path, query, and header parameters are extracted from properties marked with
[HttpParameter] - The body (if any) is serialized from the property marked with
[HttpBody] - The base URI is resolved from configuration
- Any registered decorators run to modify the
HttpRequestMessage(e.g. adding auth tokens) - The request is sent and the response is deserialized back to your result type
AI Coding Assistant
Section titled “AI Coding Assistant”An AI skill is available for Shiny Mediator (including the HTTP extension) to help generate contracts, handlers, and scaffold projects directly in your IDE.
Claude Code
claude plugin add github:shinyorg/skillsGitHub Copilot — Copy the shiny-mediator skill file into your repository’s custom instructions.
What’s Next
Section titled “What’s Next”| Topic | Description |
|---|---|
| Request Contracts | Deep dive into IHttpRequest, [Http], [HttpParameter], and [HttpBody] attributes |
| Decorators | Add authentication, custom headers, and other cross-cutting concerns to all HTTP requests |
| OpenAPI Generation | Generate contracts automatically from OpenAPI/Swagger specifications |
| Configuration & AOT | Base URI resolution, debug mode, timeouts, and AOT/JSON source generation |