How to do partial responses using ASP.Net Web Api

2020-02-25 23:00发布

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:

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?

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-02-25 23:31

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.:

  • fields=items/id,playlistItems/snippet/title,playlistItems/snippet/position
  • fields=items(id,snippet/title,snippet/position)
  • fields=items(id,snippet(title,position))

You can find more information on the GitHub project page: https://github.com/dotarj/PartialResponse.

查看更多
该账号已被封号
3楼-- · 2020-02-25 23:31

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

return from p in this.context.Products
       select new
       {
           p.Id,
           p.Name,
           p.SKU
       };

This:

  • Only selects the columns you need from the database.
  • Needs no additional classes defined for new variations of the product

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.

查看更多
登录 后发表回答