Naming minimal endpoints

Naming minimal endpoints for easier link generation

Home DailyDrop

Daily Knowledge Drop

A minimal endpoint can be given a name, which can then be leveraged to automatically generate a link to the endpoint making it easier to be invoked.

The endpoint name metadata is also treated as the operation Id in the OpenAPI specification, which is used by tools which use the swagger file to generate a client.


Named endpoint

The first step is to give the endpoint a name - this is very simply and involves using the WithName method:

// the default sample endpoint
app.MapGet("/weatherforecast", () =>
{
    WeatherForecast[]? forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateTime.Now.AddDays(index),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
// give it a name
.WithName("GetWeatherForecast");

After the body of the minimal API is defined, the WithName method is called, with the endpoint name supplied. In this example the sample /weatherforecast endpoint is given the name GetWeatherForecast.


This endpoint name can now be used to generate a URL to the endpoint - this is done using the LinkGenerator class:

// inject LinkGenerator from DI
app.MapGet("/generateUrl", (HttpContext context, LinkGenerator generator) =>
{
    // use the name to get a link to the GetWeatherForecast endpoint
    return generator.GetUriByName(context, "GetWeatherForecast", null);
});

The above code defines an endpoint, which when invoked will return the URL of the GetWeatherForecast endpoint. Browsing to the /generateUrl endpoint returns the following:

http://localhost:5276/weatherforecast

The full URL (including port etc) is automatically calculated by the LinkGenerator.GetUriByName method, based on the HttpContext and the endpoint name. LinkGenerator is available through the dependency injection container and can just be injected into the relevent constructor/delegate.


Named endpoint invocation

A practical use of this functionality is when an endpoint is required to call another endpoint in the same application:

app.MapGet("/weatherforecastproxy", async (HttpContext context, LinkGenerator generator) =>
{
    HttpClient? client = new HttpClient();

    // get the URL for the "GetWeatherForecast" endpoint
    // and create an HttpRequestMessage for it
    HttpRequestMessage? request = new HttpRequestMessage(
        new HttpMethod("GET"),
        generator.GetUriByName(context, "GetWeatherForecast", null)
    );

    // invoke it
    HttpResponseMessage? response = client.Send(request);
    return await response.Content.ReadAsStringAsync();
});

In this example, calling /weatherforecastproxy will proxy the call to the GetWeatherForecast endpoint and returns the result - this proxy endpoint is not adding much value in this sample, but it could do more complicated logic, such as calling multiple endpoints and reconciling the results, for example.

Using named endpoints and LinkGenerator.GetUriByName is a safer approach to generating the URL, instead of manually trying to build up the URL based on the information extracted from the HttpContext.


Notes

A simple and easy way to name, and then generate a link using the name. If the code is required to call another endpoint in the same application, or will be used with a client generation tool - then all endpoints should be named, and LinkGenerator used when generating the links.


References

Adding Experimental HTTP Methods To ASP.NET Core

Daily Drop 234: 13-01-2023

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net endpoint name linkgenerator