Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Api multiple get with same signature routing

I'm building a web api that has multiple get/post calls that have the same signatures. Now I know that in the case of multiple identical calls, you generally have 2 options: separate into different controllers, or use {action} in your routes. I have gone the {action} method as it fits best I believe in most of my controllers. However, in one of my controllers I would prefer not to use the action method.

I have a call like so:

[HttpGet]
public Program Program(string venue, string eventId)
//api/{controller}/{venue}/{eventId}

Now I need a new call

[HttpGet]
public Program ProgramStartTime(string venue, string eventId)
//api/{controller}/{venue}/{eventId}

I know I can add an action name to this and call i.e

api/{controller}/{action}/{venue}/{eventId}

But I feel like it breaks the expected. Is there a way that I could some something like

api/Content/LAA/1/PST
api/Content/LAA/1?PST

Also if I have to go the action route, I currently already have a route I use for other controllers, but it simply uses {id} as its only parameter. Will a new route conflict with this one? Is there a better way to setup my routes?

config.Routes.MapHttpRoute(
   name: "...",
   routeTemplate: "api/{controller}/{action}/{id}",
   defaults: new {id = RouteParameter.Optional}
);

config.Routes.MapHttpRoute(
   name: "...",
   routeTemplate: "api/{controller}/{action}/{venue}/{eventId}/{...}/{***}/{###}",
   defaults: new {### = RouteParameter.Optional}
);

config.Routes.MapHttpRoute(
   name: "...",
   routeTemplate: "api/{controller}/{action}/{venue}/{eventId}/{...}",
   defaults: new {... = RouteParameter.Optional}
);

config.Routes.MapHttpRoute(
   name: "...",
   routeTemplate: "api/{controller}/{action}/{venue}",
   defaults: new {venue = RouteParameter.Optional}
);

I expect at least one method that would have up to 5 parameters

like image 594
Zholen Avatar asked May 21 '26 22:05

Zholen


1 Answers

Here's the answer I found and it does pretty much exactly what I wanted:

        config.Routes.MapHttpRoute(
            name: "VenuesAllOrStream",
            routeTemplate: "api/Racing/{action}",
            defaults: new { controller = "Racing", action = "Venues" },
            constraints: new { action = "Venues|All|Streaming" }
        );

        config.Routes.MapHttpRoute(
            name: "VenueOrVideo",
            routeTemplate: "api/Racing/{venue}/{action}",
            defaults: new { controller = "Racing", action = "RaceNumbers" },
            constraints: new { action = "RaceNumbers|Video" }
        );

        config.Routes.MapHttpRoute(
            name: "ProgramOrMtp",
            routeTemplate: "api/Racing/{venue}/{race}/{action}",
            defaults: new { controller = "Racing", action = "Program" },
            constraints: new { action = "Program|Mtp", race = @"\d+" }
        );

It is important that the VenuesAllOrStream is first as otherwise the VenueOrVideo picks up the route. I most likely will extract out the action constraints into enums later.

Brief note : Setting the action default allows for the route to basically make it an optional parameter. So each route works without the {action} actually being set.

like image 114
Zholen Avatar answered May 23 '26 14:05

Zholen



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!