When to use models as parameters over url parameters in API C#

Viewed 771

I have a method within a controller that returns a list of objects. The implementation of the controller is not important. The method is called GetAllTestsByLocationIdAndPollTypeId and returns a list of 'Test' objects. The GET takes 4 parameters, a locationId, pollTypeId, itemsToLoad and a string to search by. I am looking to add more parameters and feel that passing in 6 objects in a url is a bit much. The method signature looks like this:

[HttpGet]
public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId(int locationId, int pollTypeId, int itemsToLoad = 8, string search = "")

Should I pass in a model that contains the values I am currently using for parameters?

EDIT: I can't do a [HttpPost] because POST requests do not get cached and therefore can be expensive and in this case, will be expensive.

EDIT: I solved the filters in the query string using optional parameters to reduce the number of things being passed in.

1 Answers

It is totally upto you but yes when parameters increases & have large size Header size can exceed since it is HttpGet where data is sent in header as Query string parameters.

You can try HttpPost since it sends data in body, also uses class & don't show param values if data is over https:

[HttpPost]
public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId([FromBody]TestLocation request)

Here I am assuming you, you can create class TestLocation or anyname you like with public properties of name of param you need.

Now you need to send JSON object of class after stringify like {'locationId':1, 'pollTypeId':1, 'itemsToLoad':10, 'search': 'your text'} & change ajax to post. Since you have left how you are calling from ajax I leaving that to you

UPDATE


As per feedback by @PanagiotisKanavos(post is not cached) & information from you that querystring is not long, you can try adding route like:

config.Routes.MapHttpRoute("MyRoute", "{controller}/{locationId}/{pollTypeId}/{itemsToLoad}/{search}", new { controller = "Region", action = "GetCountries" })

or Add attribute at controller level if routes/parameters are unique to action methods:

[Route("GetAllTestsByLocationIdAndPollTypeId/{locationId}/{pollTypeId}/{itemsToLoad}/{search}")]
[HttpGet]
public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId(int locationId, int pollTypeId, int itemsToLoad = 8, string search = "")

Now your api call can be like : http://localhost/controller/1/2/10/test

OR

You can try of combination of route and query. e.g. {LocationId}/{pollType}/Tests?itemsToLoad=N&search=X as suggested by @KirkLarkin

Related