2015年5月5日 星期二

【Web API】Web API mix with RPC

基本 Web API 是 RESTful 結構,每個 URI 對應的應該要是資源而不是方法(routing 中的 action),但是剛開始學還不太懂,比方如果我同時需要  GetAll()、GetById(int id)、GetFirstByKeyword(string key)、GetByKeyword(string key) 四種,那後三者的 routing 會重複要怎麼解決,以 RPC 的角度就很直觀,但不把 action 加回去還真不知道要怎麼做,不過網路上可以找到的教學還不少,只能說看來跟我有同樣疑問的人還不少。


在 WebApiConfig.cs 加入
  1. config.Routes.MapHttpRoute(
  2. name: "RPCApi",
  3. routeTemplate: "services/{controller}/{action}/{keyword}",
  4. defaults: new { keyword = RouteParameter.Optional }
  5. );

services 是跟 api 的部分做個區隔,這裡要注意 controller 中的參數名稱也要叫 keyword,另外,因為把 action 加了回來所以方法必須標記使用的是 http get。
  1. [HttpGet]
  2. public IHttpActionResult GetFirstProductByKeyword(string keyword)
  3. {
  4. var product = products.FirstOrDefault((p) => p.Name.Contains(keyword));
  5. if (product == null)
  6. {
  7. return NotFound();
  8. }
  9. return Ok(product);
  10. }
  11.  
  12. [HttpGet]
  13. public IHttpActionResult FindProductsByKeyword(string keyword)
  14. {
  15. var resultSet = products.Where((prod) => prod.Name.Contains(keyword));
  16. if (resultSet == null || resultSet.Count() == 0)
  17. {
  18. return NotFound();
  19. }
  20. return Ok<IEnumerable<Product>>(resultSet);
  21. }

這樣在 Jquery 處就可以正確取得服務了
  1. var rpc = 'services/products';
  2. ...
  3. function formatItem(item) {
  4. return item.Name + ': $' + item.Price;
  5. }
  6. ...
  7. function findFirstFitProductByKeyword() {
  8. var name = $('#productName').val();
  9. $.getJSON(rpc + '/GetFirstProductByKeyword/' + name)
  10. .done(function (data) {
  11. $('#displayProduct').text(formatItem(data));
  12. })
  13. .fail(function (jqXHR, textStatus, err) {
  14. $('#displayProduct').text('Error: ' + err);
  15. });
  16. }
  17. ...

完整專案:按我

ref:http://encosia.com/rest-vs-rpc-in-asp-net-web-api-who-cares-it-does-both/

沒有留言:

張貼留言