Let’s say I have a class that contains a property as below:
List ListOfObjectA;
Object A is defined below:
Class ObjectA:
Prop a
Prop b
ListOfObjectA (returned by an API endpoint as DTO) is to be rendered in UI.
In some instances, a specific ObjectA instance in the list needs to provide addition supportive information (let’s say another object SubObjectA (a complex type), which isn’t common to other items in the list) I.e. n+1 case.
I’m trying to understand the best way to return this information without clogging the DTO with unnecessary information.
One option is to include the SubObjectx in the ObjectA class itself - when it’s null or empty don’t bother otherwise render it. We’d programmatically populate it where needed...
Second option is to perhaps add a url property to the ObjectA class - url can either be empty or point to an endpoint to get additional information and response then can be rendered.
My personal objection with first option is that each object in ListOfObjectA will always contain unrelated information. I like the second option better as it contains a string (endpoint) I.e. if has value where to get the subobject from. But this also means that the client of the API will now have program some logic to hit those endpoints when needed.
I’m wondering if there are other better ways to do this?
Please ask me a question if my attempt at explaining the situation isn’t very good.
Whether you're doing automatic model binding of JSON from the request body or manually using something like JsonConvert
to create your models, your DTO class(es) will need to have all possible properties. There's no real way to instantiate different types of objects from the same set of data, bases on the presence or lack thereof of some particular datum. That said, you can create a custom model binder and some custom JSON resolvers to potentially get the job done, but the amount of work involved for something that's mostly cosmetic is not worth the investment.
For what it's worth, this is only an issue for the DTO classes themselves. You can utilize things in JSON.NET like the JsonIgnore
attribute and the NullValueHandling
and DefaultValueHandling
enums to hide members in the actual JSON, if that's your primary concern. For example:
public class ObjectA:
{
public string A { get; set; }
public string B { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string C { get; set; }
}
Then, when you're serializing your objects, if the C
property is not set, you'll get JSON like:
{
"a" : "foo",
"b" : "bar"
}
And if it is set, you'll get:
{
"a" : "foo",
"b" : "bar",
"c" : "baz"
}
Short of that, I'd say your best bet is links to request additional data if necessary. This is actually a very REST thing to do. It's essentially HATEOAS. However, it's also very chatty. It's going to require many more requests to be made, particularly if you're having to do it for multiple items. It's essentially the N+1 database query problem applied to an API.