I'm really new to API design and MVC concepts, but as far as I can tell, something like GET /api/products should return a list of products and GET /api/products/1 should return a single product. In terms of speed my feeling is that /api/products should return less information i.e. just id and name, whereas /api/products/1 should return more i.e. id, name, and description.
As far as I can see, the best way to handle this is to make certain fields of the product class not be returned in the /api/products endpoint. This is especially necessary in the case of /api/products?fields=name . I'm using ASP.Net Web Api 2 and have tried the following:
- http://www.nuget.org/packages/WebApi.PartialResponse/ - installing this package caused an assembly version error.
- Adding ShouldSerialize methods on the Product fields. For reasons I won't go into here, this method is a little cumbersome.
- Looked at ASP.NET Web API partial response Json serialization but there doesn't seem to be a conclusive answer there.
- ASP.NET WebApi and Partial Responses suggests using a product class with all nullable fields. I'm not sure I understand exactly what to do there.
Is there any simple way to do what I'm trying to do?
Otherwise could you suggest a better API design than what I'm doing?
You could also use WebApi.PartialResponse (http://www.nuget.org/packages/WebApi.PartialResponse/). It's a package I wrote which uses LINQ to JSON (Json.NET) to manipulate the returned objects. It uses the fields syntax used by Google in their API's, eg.:
You can find more information on the GitHub project page: https://github.com/dotarj/PartialResponse.
I'd recommend using separate classes to map to when returning a list of entities.
Particularly as the problem is not just what you return to the user, but also what you select from the database.
So, make getting and entity return a Product object, and getting a list of entities return a ProductLink object or something similar.
Edit
As per jtlowe's comment, if you have many different methods returning slight variations of product properties, use anonymous classes (though I'd question whether this is necessarily a good design).
Consider something like this in your action
This:
This doesn't make it easy to pass the result of this statement around to other methods because you can only return it as IEnumerable, object or dynamic. If you are putting this in the controller then it may be good enough. If you are implementing a repository pattern, you'll be unable to return strongly typed lists if you use anonymous types.