Atle Kristiansen
Atle Kristiansen

Reputation: 707

Get request with multiple inputs in ServiceStack API

I am creating a endpoint that accepts multiple parameters. I was wondering what the proper way of doing this in ServiceStack is, as I know that the routes can be defined like this:

[Route("/Cars/{EquipmentIds}/{ManufacturerIds}/{ColourIds}")]

But does not that mean that EquipmentIds has to be defined before ManufacturerIds and ColourIds, otherwise the API will interpret it incorrectly?

I would like to specify the parameters I use, and then not include the rest when they are not used.

A unclean url would then look like this ?EquipmentIds=1&ColourIds=1

I found the following solution, but this one was from 2011

Multiple Optional Parameters with ServiceStack.Net.

Is there a new solution for this, or is that still the proper way of doing things?

Upvotes: 1

Views: 281

Answers (1)

mythz
mythz

Reputation: 143319

The URL should be a "resource identifier" where any Query String arguments are modifiers to that resource request.

So you shouldn't put complex types in the /path/info which are unlikely to form part of Resource Identifier for that route.

Your route should be self-describing as to what it's a resource identifier of. Stuffing a an anonymous bunch of ids in the URL doesn't make it a clean URL, it still needs to be semantically correct and self-describing at what the different path components contain.

It's hard to know the right Route to use when it's not clear what Service this is used for, but if this was a Car Search Service the appropriate URL would be something like:

/cars/search?EquipmentIds=1,2,3&ManufacturerIds=4,5,6&ColourIds=7,8,9

Just as when you use a Search Service like Google, they don't try to pack everything in the route, which is only used to identify you're making a search request. Everything else including the search query is added to the query string, e.g;

https://www.google.com/search?q=test

Which in ServiceStack would just be defined as:

[Route("/cars/search")]
public class SearchCars 
{ 
    public List<int> EquipmentIds { get; set; }
    public List<int> ManufacturerIds { get; set; }
    public List<int> ColourIds { get; set; }
}

Or it can be easily auto implemented in AutoQuery with:

[Route("/cars/search")]
public class SearchCars : QueryDb<Car> 
{ 
    public List<int> EquipmentIds { get; set; }
    public List<int> ManufacturerIds { get; set; }
    public List<int> ColourIds { get; set; }
}

Upvotes: 2

Related Questions