2011-04-12 64 views
4

我想知道是否有創建REST API和ASP.NET MVC 3的最佳做法?目前我正在考慮爲每個版本的REST API創建一個控制器。例如,到目前爲止我有:使用ASP.NET MVC 3構建REST API的版本控制 - 最佳實踐

public class V1Controller : Controller 
{ 
    public V1Controller() 
    { 
    } 

    public ActionResult GetUser(string userId, IUserRepository userRepostory) 
    { 
     //code to pull data and convert to JSON string 
     return View("Results"); 
    } 

    public ActionResult GetUsersByGroup(string groupId, IUserRepository userRepostory) 
    { 
     //code to pull data and convert to JSON string 
     return View("Results"); 
    } 
} 

然後對於意見我覆蓋_ViewStart.cshtml以除去佈局,然後我有Results.cshtml,僅僅輸出被在控制器動作被格式化的數據,右現在JSON。在一個控制器中進行每個REST調用似乎有點太多,但這是我能想到的最好方式,以便我可以保持單獨版本的API的清晰,以便在創建API的第2版時,我可以創建一個V2Controller並且不要打破現有的API,讓人們有時間切換到新的API。

有沒有更好的方法來創建ASP.NET MVC 3的REST API?

+0

似乎你想問關於版本控制。我認爲'V1Controller'不是一個好習慣。您將一個'Controllers'中的所有版本混合到一個MVC項目中。我認爲版本應該是來自源代碼管理歷史的標記/分支。這不應該成爲僅服務REST服務的問題,但MVC包含網站+ REST。那麼,我怎麼發佈REST的版本,而網站只使用最新的REST?然後,我創建了2個MVC項目,一個用於網站,另一個用於REST服務(但爲什麼不是WCF?)。 MVC應該在一個項目中同時處理,我再次回到原來的想法! – CallMeLaNN 2011-04-22 03:04:48

回答

1

如果您要返回的是JSON,則不需要視圖。 Jusr返回

new JsonResult(){Data = Data}; 

請看here


另外在版本控制方面,版本可以作爲不同的控制器或作爲同一控制器中的額外方法來實現。但是不知道爲什麼你需要版本,爲什麼你的客戶(我認爲是瀏覽器)需要知道版本問題並不清楚你的問題。

+2

那麼「客戶」就是任何使用API​​的人。具有版本能力的原因在於,我做出了改變,迫使我改變API。如果我有API的版本,這將幫助我否定打破每個使用舊版API的人(不是100%,但是絕大多數人)的可能性。 – ryanzec 2011-04-12 12:05:17

+0

版本控制在企業場景中至關重要。具有多個客戶端的多個環境分佈在企業中,而在一個服務器場中具有多個服務器幾乎是必要的 – 2012-06-07 17:03:05

0

控制器(例如您在示例代碼中發佈的控制器)應始終保留您現在使用的方法,例如GetUsersByGroup()具有相同的簽名。我不明白該方法可能有不同的版本。

輸入是組和存儲庫(我相信它來自DI)。輸出是JSON格式的用戶列表。這對API的用戶來說很重要。你在這個方法裏做的是沒有人的事。

你應該考慮更多的輸入和輸出。除非真的需要這樣做,否則您不應該更改現有操作的簽名。

從實現接口的角度考慮控制器類。你有一個接口和控制器類是它的實現(我的意思是你不需要它,但只是想到這一點)。一旦一個或幾個類實現它,你將很少改變接口。但是您可以將方法添加到它。這隻需要實施類的更改 - 它不會破壞API的功能,每個使用它的人都可以繼續使用它。

2

我能夠找到一個體面的解決方案,使用MVC的區域使用。

首先,我想讓我的API遵循這個網址定義:

http://[website]/[major_version]_[minor_version]/{controller}/{action}/... 

我也想打破在單獨的項目文件的不同版本,並在每個版本中使用相同的控制器名稱:

"../v1_0/Orders/ViewOrders/.." => "../v2_3/Orders/ViewOrders/.." 

我四處搜索,發現了一個可行的解決方案,使用MVC區域。

我在我的解決方案稱爲「Api.Controllers.v1_0」創建新項目,並作爲測試,把SystemController.cs文件中有:

using System.Web.Mvc; 

namespace Api.Controllers.v1_0 
{ 
    public class SystemController : Controller 
    { 
     public ActionResult Index() 
     { 
      return new ContentResult() {Content = "VERSION 1.0"}; 
     } 
    } 
} 

然後我加入v1_0AreaRegistration.cs文件:

using System.Web.Mvc; 

namespace Api.Controllers.v1_0 
{ 
    public class v1_0AreaRegistration : AreaRegistration 
    { 
     public override string AreaName 
     { 
      get{ return "v1_0";} 
     } 

     public override void RegisterArea(AreaRegistrationContext context) 
     { 
      context.MapRoute(
       "v1_0", 
       "v1_0/{controller}/{action}/{id}", 
       new { controller = "System", action = "Index", id = UrlParameter.Optional } 
      ); 
     } 
    } 
} 

我通過相同的步驟如對上述走「..v1_1」項目與其中的相應文件,將項目添加到我的「Api.Web」MVC項目中並關閉並運行。

+1

另外我想補充一下,考慮讓更高版本的控制器從低版本控制器繼承,這樣他們只需要實現已經改變的行爲,而不是重複行爲。也考慮對模型對象使用相同的方法。 – 2012-06-07 17:01:56