I’ve searched around and gotten pieces from here and there on the topic. I’m hoping this thread can serve as the be-all-end-all thread for the discussion, for myself and for others.
For reference, I’ve looked here: Passing complex DTO in Postman
And here: Swagger ui and complex types
But this SO thread is the most on point for what I’m trying to do: https://stackoverflow.com/questions/22412886/complex-array-in-servicestack-request
Namely, I have a complex request DTO that has an array of FilterItem. I know I can do Filters=[{JSV}, {JSV}], etc. But that, to me, leaks implementation.
I’d rather use more “standard” querystring formats, like MVC. I know there are a few flavors of that for working with arrays and complex objects, but let’s just assume the MVC flavor.
Is there any way to FormData-style naming conventions in the URL instead? filters[0].prop1=…&filters[0].prop2=…&filters[1].prop1=…
I’m also looking at using POST with X-HTTP-Method-Override: GET as an alternative. Not sure how this will translate to JSON clients and such, though. I’m not even sure how JSON clients handles
Looking at swagger docs, looks like there’s some support for serialization in the URL (particularly, deepObject), but I don’t see array serialization, just object serialization. https://swagger.io/docs/specification/serialization/
So basically, I’ve researched this up and down. For ServiceStack or otherwise, I can’t find a best practices way of handling things, and the only way I’ve found to do it SS-specific is to use JSV or a custom serializer, which I don’t love.
How SHOULD this feature be implemented? Should we not really use complex objects in GETs? How should we do it instead?
Here’s my sample code for reference:
[Tag("Assets")]
[Route("/assets/master-grid/query", HttpMethods.Post)]
public class QueryAssetMasterGrid : RequestWithFiltersBase, IPost, IPagedRequest, IReturn<PagedDataTableResponse>
{
public int? PageIndex { get; set; }
public int? PageSize { get; set; }
public List<string> SelectFields { get; set; }
public List<string> GroupFields { get; set; }
public List<QueryField> AggregationFields { get; set; }
public List<OrderByQueryField> OrderByFields { get; set; }
}
public enum AggregationType
{
SUM,
COUNT,
AVG,
MIN,
MAX,
}
public class OrderByQueryField
: QueryField
{
public bool Descending { get; set; }
}
public class QueryField
{
public string Field { get; set; }
public AggregationType? Aggregator { get; set; }
public string Alias { get; set; }
public bool HasAlias { get; set; }
public bool IsAggregate { get; set; }
public string AliasOrField { get; set; }
}