2016-03-03 66 views
1

我已經計劃構建多個服務端點,例如這些以更新多個實體項目。接受POST請求時添加單個或多個API端點?

/api/order(orderInfo) [httppost] 
/api/orderChangeCurrency(orderCurrency) [httppost] 
/api/orderChangeClientName(orderClientName) [httppost] 

public class orderInfo() 
{ 
public int orderID {get;set;} 
public int orderType {get;set;} 
} 

public class orderCurrency() 
{ 
public int orderID {get;set;} 
public int currencyID {get;set;} 
} 

public class orderClientName() 
{ 
public int orderID {get;set;} 
public string firstName{get;set;} 
public stringlastName{get;set;} 
} 

但它越過我的腦海裏有一個單獨的端點,而不是會做這一切

/api/order(orderExtendedInfo) [httppost] 

public class orderExtendedInfo() 
{ 
public int orderID {get;set;} 
public orderInfo? OrderInfo{get;set;} 
public orderCurrency? OrderCurrency{get;set;} 
public orderClientName? OrderClientName{get;set;} 
} 

在這種情況下,我不得不將根據所提供的信息更新的實體業務邏輯(空值或不)。

在這個特定情況下,API端點是否有推薦的做法或規則?

+0

什麼的 「建議」 的方式,你找什麼?更具體地說 – jpgrassi

+0

我只是在尋找這種特殊情況下的API設計實踐。 – mko

+0

我認爲你的方法沒問題。唯一的一點是,如果你遵循REST,你的方法是錯誤的。其餘的重點是資源,所以你不應該在方法中處理多個資源。但是,這只是「純粹」的REST指導原則,我認爲它在我的日常工作中沒有多大用處。 – jpgrassi

回答

2

的商務三層的方法,這是一個相當寬泛的問題,並可能更適合於http://programmers.stackexchange.com但無論如何,我會掉落一些注意事項。

首先,您的API設計應該面向API的用戶。如果你的API將是一個面向公衆的API,你可能會考慮REST。這是一種廣泛使用(並且有爭議)的架構風格,許多程序員習慣於這種風格。有關設計RESTful API的非常有用的建議列表可以是found here

其次,您應該考慮API的易耗性。以您的設計爲例:消費者逐一更新實體是合乎邏輯的,還是一次更新一個或多個甚至所有實體更符合邏輯?

第三,您必須考慮數據庫事務。當所有實體都應該在一次原子操作中更新時,則不能提供三個端點。

個人而言,我非常喜歡REST,所以我會很樂意爲您的用例提供一個示例。

首先讓我介紹一個新的實體:

public class OrderLine 
{ 
    public int Id {get;set;} 
    public int OrderId {get;set;} 
    public int ProductId {get;set;} 
    public int Quantity {get;set;} 
    public decima Price {get;set;} 
} 

端點

POST /api/orders     # creates a new order 
GET /api/orders     # gets all orders 
GET /api/orders/1    # gets order 1 
POST /api/orders/1/orderlines  # creates a new order line for order 1. 
GET /api/orders/1/orderlines/1 # gets order line 1 of order 1 
GET /api/orderlines/{id}   # gets order line 1 

如果你需要在一個單一操作中更新多個實體,你可以不喜歡它這個:

Cr eate模型的更新:

public class EditOrder 
{ 
    public int orderID {get;set;} 
    public int orderType {get;set;} 
    public int currencyID {get;set;} 
    public string firstName{get;set;} 
    public string lastName{get;set;} 
} 

然後用這個端點

PUT /api/orders/1 

而且這種方法

public IHttpActionResult Put(int id, EditOrder editOrder) 
{ 
    // retrieve current Order, OrderCurrency and OrderClient 
    // update the entities 
    // save entities 
} 
+0

你對所有的事實都是正確的。在更新訂單時,它應該是PUT而不是POST。關於端點的結構,尤其是當以/ api/orders/{id}/orderlines等格式放置順序時(似乎有一個重複/或類似的端點/ api/orders/1/orderlines/1和/ api/orderlines/{id})。我只是不確定是否不需要進行原子更新,在單個操作中更新多個實體或將其分成多個端點(從最終用戶的角度來看)更爲明智。從BL的角度來看,這將是完全不同的問題。 – mko

+0

例如https://developer.zendesk.com/rest_api/docs/core/tickets#update-ticket基本上是更新單個端點內的整個票證(審計,評論等除外),與您的示例中的orderline類似。 – mko

+0

我添加了重複的端點以指示可以通過多個端點訪問資源。 – venerik

1

我想你應該實現一個控制器的操作方法,並在這樣

[HttpPost] 
[Route("api/order")] 
public async Task<IHttpActionResult> SubmitOrder(OrderExtendedInfo info) 
{ 
    var bl = new BusinessLayer(); 
    if(info.orderInfo.HasValue) 
    { 
     bl.UpdateOrderInfo(orderInfo); 
    } 
    if(info.orderCurrency.HasValue) 
    { 
     bl.UpdateOrderCurrency(orderCurrency); 
    } 
    if(info.orderClientName.HasValue) 
    { 
     bl.UpdateOrderClientName(orderClientName); 
    } 
} 
+0

在您的解決方案中,需要三次往返數據庫才能完成所有更新。但讓我們說這不是問題,主要關心它應該有單個或多個API端點。 – mko