Reputation: 3043
Several RESTful APIs give the caller options for the amount of data they have returned, often by a querystring parameter (eg stackexchange's filter parameter).
I'd like to at least provide some level of configurability to the amount of returned data, maybe not necessarily to the same level of flexibility (though I'd have nothing against it) but to the point where having individual viewmodels would not be a workable solution.
Yet I'm struggling to find a good point in Web API to add some sort of property white/black list. What's the appropriate way to do this?
Upvotes: 1
Views: 247
Reputation: 19311
One way you can accomplish returning a sub-set of fields with a single DTO is by having nullable types for the optional properties in your DTO.
[DataContract]
public class Dude
{
[DataMember]
public int Id { get; set; }
[DataMember(EmitDefaultValue = false)]
public string FirstName { get; set; }
[DataMember(EmitDefaultValue = false)]
public string MiddleName { get; set; }
[DataMember(EmitDefaultValue = false)]
public string LastName { get; set; }
[DataMember(EmitDefaultValue = false)]
public int? IQ { get; set; }
}
You will need to get the list of fields the client will be interested to see in the response and populate only those in the instance of the DTO you return, like this.
return new Dude() { Id = 123, FirstName = "Johnny" };
This will send a JSON like { "Id":123, "FirstName":"Johnny" }
. When another client asks for say LastName
, you will return new Dude() { Id = 123, LastName = "Bravo" };
and JSON will be { "Id":123, "LastName":"Bravo" }
.
This will work for both XML and JSON. If you are okay with only JSON, you don't need to apply the attributes. Just need to instruct JSON.NET to ignore nulls.
config.Formatters.JsonFormatter.SerializerSettings =
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
The final piece of how to get the list of fields will be up to your API design. You can perhaps use an action filter to get those standard fields from the request and use it to get the data from your persistence store.
Upvotes: 1