1

I have a controller marked with [Route("api/entities")]. There is a method for getting all entities:

[Audit(ActionType.EntityList)] // custom annotation for audit
[Authorize]
[HttpGet]
public IActionResult GetEntities()
{
    // ...
}

As you can see, by using annotations I save the request to some audit and authorize the request only to allowed users.

Now, I want to enhance this endpoint so it can return the top N entities. Example request: /api/entities?top=5. I have found that I should use an optional parameter for the method and use if to detect the case.

However, I need to save such call in audit as differnt type (e.g. [Audit(ActionType.EntityTop)]) and I do not need an authorization there (everyone can fetch the top entities).

How can I map the /api/entities request to one method and /api/entities?top=N to another? In Spring from Java I would use a params field of @RequestMapping.

I do not want to change the URL of this endpoint, because the top parameter modifies only the list that is being returned so one should use GET parameters for that. By having the same URL I also do not change the semantic meaning of the response (it is still list of the same entities). It is important when using RESTful frontend framework like Restangular.

fracz
  • 20,536
  • 18
  • 103
  • 149
  • Why don't you just create another action the has the parameter, uses the different ActionType and doesn't have the Authorise – musefan May 26 '17 at 12:45
  • Do you mean something like `[HttpGet] public IActionResult GetTop(int top)`? Let me try that... – fracz May 26 '17 at 12:46
  • Yeah but I am not really sure how action overloading works in MVC, never done it myself. [Maybe this might be a useful read](https://stackoverflow.com/questions/436866/can-you-overload-controller-methods-in-asp-net-mvc) – musefan May 26 '17 at 12:49
  • @fracz check out OData – Nkosi May 26 '17 at 13:04

1 Answers1

1

Are you sure you need same action? It looks like you want to solve different tasks here, so I'd suggest you to create another action

[Audit(ActionType.EntityTop)]
[HttpGet("top/{top:int}")] //you can specify route via Annotations
public IActionResult GetEntities(int top)
{
    // ...
}

Request with top entities will match /api/entities/top/5

hmnzr
  • 1,390
  • 1
  • 15
  • 24
  • I'm trying to be RESTful here as I'm using Restangular in frontend. When I change the URL to the one you suggest (`/api/entities/top/5`), it semantiaclly means that this endpoint returns list of "fives" associated to with entity "top". – fracz May 26 '17 at 12:50
  • Another option is place optional parameter in main action and try to achieve desired attributes logic by implementing custom authorization filter and audit filter based on query parameters. That way you can save REST filtering and url will be '/api/entities?top=N' – hmnzr May 26 '17 at 13:15