ardalis / ApiEndpoints

A project for supporting API Endpoints in ASP.NET Core web applications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for custom EndpointsBase class to support ApiVersioning and Routing

JesperKSmith opened this issue · comments

``

I've been trying to convert our existing project to using ApiEndpoints, but I've ran into an issue that I can't seem to wrap my head around.

So in our existing project, we have many different controllers. All of our controllers, inherit from an "ApiControllerBase" class.

[ApiController]
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class ApiControllerBase : ControllerBase
    {
        ...
    }

We make use of the "ApiVersion" assignment here, as well as the Route, to ensure that all of our controllers use a certain api version, as well as a specific path.

However, I can't figure out how I would create such a base class when using ApiEndpoints - I've tried creating a new custom class to override EndpointBaseAsync, but since it's a static class, and since you cannot derive from a static class, that wasn't successful.

I also tried making my custom class static, but as a static class must derive from an object, and you can't create an instance of an object of the EndpointBaseAsync(as it is static), I've sort of hit a brick wall here.

Is there anyway I can create a base class for my ApiEndpoints, in which I can assign most importantly ApiVersion? I would also like to be able to assign the Route attribute, but I can live with having to assign that from within my specific endpoints.

Now I'm not the most experienced dotnet developer just yet, so it could very well be the case that I'm just completely missing something here, and if that is the case I apologize.

No, one downside to the design approach of this library is that, since it uses inheritance to create the EndpointBase class, it makes it largely impossible for you to use a common base class in your app. This is compounded by the "fluent generic" base class pattern used as well. For routes my solution has been to put the full route details in each endpoint, and if I need helpers to ensure routes are consistent I reference them from the endpoint's route directive, rather than relying on controller inheritance for routes. For other attributes like version I don't have a great solution - open to suggestions from others, though.

Allright, that's also been sortof the approach we've been going with so far - Thanks for your swift reply, I was also left with the impression that it wasn't possible to make the endpoint base class, so very comforting hearing that from you as well :)

If we end up coming up with an alternative at some point, I'll be sure to get back to you,

Kind regards,

Jesper

I suppose one option would be to build onto the existing "fluent generics" approach, and make a last method .WithVersion<T> that would add versioning. You might need to make actual types that correspond to the version numbers. Kind of hacky, but just throwing it out there as an idea.