Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal call to FastEndpoints endpoint/route

I use Fastendpoints in an ASP.NET Core 9 Web API project.

The endpoint uses dependency injection for several services, in the example a logger.

In another service, I want to make a call to this endpoint. I would prefer it to call the endpoint directly and not using an HttpClient for it.

For this to happen, I either have to

  • use DI in my service for every service that gets injected into the endpoint - which seems unreasonable
  • register every endpoint manually in the setup via builder.Services.AddScoped<MyEndpoint>() - then some internals of the endpoint are null (HttpContext member)
  • use the FastEndpoints.Factory.Create<>() also requires every service to be explicitly instantiated
public class MyWorkerService
{
    public async Task HandleInit()
    {
        // how to call the endpoint?
        await (new GetTestEndpoint()).HandleAsync(new EmptyRequest(), CancellationToken.None);
        var response = GetTestEndpoint.Response;
    }
}

public abstract class GetTestEndpoint : Endpoint<EmptyRequest, TestResponse>
{
    protected readonly SomeService _someService;
    protected readonly ILogger _logger;

    protected GetTestEndpoint(SomeService someService, ILogger logger)
    {
        _someService = someService;
        _logger = logger;
    }

    public override void Configure()
    {
        Get("api/" + RoutePattern);
        AllowAnonymous();
    }

    public override async Task HandleAsync(EmptyRequest emptyRequest, CancellationToken ct)
    {
        await SendAsync(new TestResponse());
    }
}

So how do I make internal calls to the fast-endpoint route (with the request class and getting back a response object?)

like image 807
nonsensation Avatar asked Dec 17 '25 21:12

nonsensation


1 Answers

Better Approach: Extract Business Logic into a Service

Instead of calling the endpoint directly, move the logic from GetTestEndpoint into a separate class, which both the endpoint and the internal caller (MyWorkerService) can use.

Refactored Code

public class TestService
{
    private readonly SomeService _someService;
    private readonly ILogger<TestService> _logger;

    public TestService(SomeService someService, ILogger<TestService> logger)
    {
        _someService = someService;
        _logger = logger;
    }

    public async Task<TestResponse> GetTestDataAsync()
    {
        _logger.LogInformation("Handling test data retrieval");
        // some more logic
    }
}

Updated Endpoint

public class GetTestEndpoint : Endpoint<EmptyRequest, TestResponse>
{
    private readonly TestService _testService;

    public GetTestEndpoint(TestService testService)
    {
        _testService = testService;
    }

    public override void Configure()
    {
        Get("api/" + RoutePattern);
        AllowAnonymous();
    }

    public override async Task HandleAsync(EmptyRequest req, CancellationToken ct)
    {
        var response = await _testService.GetTestDataAsync();
        await SendAsync(response);
    }
}

Calling from Another Service

public class MyWorkerService
{
    private readonly TestService _testService;

    public MyWorkerService(TestService testService)
    {
        _testService = testService;
    }

    public async Task HandleInit()
    {
        var response = await _testService.GetTestDataAsync();
        // Do something with the response
    }
}

Benefits of This Approach

  1. No Need to Instantiate Endpoints - We avoid directly creating endpoints, which require dependencies like HttpContext.
  2. Better Separation of Concerns - The endpoint is now only responsible for handling HTTP requests, while the business logic is in a dedicated service.
  3. Easier to Unit Test - You can now test TestService independently without worrying about ASP.NET Core internals.
  4. Reusability - Any other part of your app (including background services) can use TestService without requiring HTTP calls.
like image 190
Michał Turczyn Avatar answered Dec 19 '25 11:12

Michał Turczyn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!