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 加入
config.Routes.MapHttpRoute(
    name: "RPCApi",
    routeTemplate: "services/{controller}/{action}/{keyword}",
    defaults: new { keyword = RouteParameter.Optional }
);

services 是跟 api 的部分做個區隔,這裡要注意 controller 中的參數名稱也要叫 keyword,另外,因為把 action 加了回來所以方法必須標記使用的是 http get。
[HttpGet]
public IHttpActionResult GetFirstProductByKeyword(string keyword)
{
    var product = products.FirstOrDefault((p) => p.Name.Contains(keyword));
    if (product == null)
    {
        return NotFound();
    }
    return Ok(product);
}

[HttpGet]
public IHttpActionResult FindProductsByKeyword(string keyword)
{
    var resultSet = products.Where((prod) => prod.Name.Contains(keyword));
    if (resultSet == null || resultSet.Count() == 0)
    {
        return NotFound();
    }
    return Ok<IEnumerable<Product>>(resultSet);
}  

這樣在 Jquery 處就可以正確取得服務了
var rpc = 'services/products';
...
function formatItem(item) {
    return item.Name + ': $' + item.Price;
}
...
function findFirstFitProductByKeyword() {
    var name = $('#productName').val();
    $.getJSON(rpc + '/GetFirstProductByKeyword/' + name)
    .done(function (data) {
        $('#displayProduct').text(formatItem(data));
    })
    .fail(function (jqXHR, textStatus, err) {
        $('#displayProduct').text('Error: ' + err);
    });
}
...

完整專案:按我

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

沒有留言:

張貼留言