ardalis / ApiEndpoints

A project for supporting API Endpoints in ASP.NET Core web applications.
MIT License
3.13k stars 227 forks source link

shared routing conventions not possible with fluent generics API #93

Closed glitchedmob closed 3 years ago

glitchedmob commented 3 years ago

I might be missing something here but it seems as if it's no longer possible to have any shared routing conventions with the new fluent generics API.

The current version of the docs say to create your own base class that inherits from BaseEndpoint, this is no longer possible since BaseEndpoint (and BaseEndpointAsync) are static classes which cannot be inherited from. Also, even if they could I believe the Route attribute has to be added to a class that inherits from ControllerBase which BaseEndpoint does not.

ardalis commented 3 years ago

Ok, i see what you mean. I was thinking you could add it to BaseEndpointSync but you don't have that code - it's in the package (sorry, multi-tasking). You're right, that's probably a breaking limitation of using that pattern. Let me think about workarounds.

glitchedmob commented 3 years ago

One potential workaround I was just experimenting with was to create a custom route attribute for all the routes that have something shared. For example

using Microsoft.AspNetCore.Mvc;

namespace MySampleApp.Author
{
    public class AuthorRouteAttribute : RouteAttribute
    {
        public AuthorRouteAttribute() : base("authors")
        {
        }
    }
}

You'd then decorate your routes with that attribute instead of the normal [Route].

glitchedmob commented 3 years ago

Another options I was thinking of would be to store all your routes as constants in a static class somewhere and reuse them.

public static class Routes
{
    public const string Authors = "authors";
    public const string Books = "books";
}

[Route(Routes.Authors)]
public class ListAuthorEndpoint : BaseAsyncEndpoint
    .WithoutRequest
    .WithResponse<ListAuthorResponse>
{

} 

Not sure if I like this any better than the previous example but it certainly helps solve the problem of needing to update a bunch or routes at once

ardalis commented 3 years ago

What I typically is similar, but I put the specific route constant on the Request that goes with that endpoint, like this:

    public class CreateAuthorCommand
    {
        public const string ROUTE = "/authors";

        [Required]
        public string Name { get; set; }
        [Required]
        public string PluralsightUrl { get; set; }
        public string TwitterAlias { get; set; }
    }

This is in the latest sample in the repo now.

I don't have a solution to use the [Route] attribute on a base class, though. I need to figure out where I'm saying that in the docs and pull it out.

glitchedmob commented 3 years ago

@ardalis I dig it. Thanks for the update.

P.S thanks for making this library. Such a great idea, I'm hoping to get it in production soon.