2014-02-11 33 views
3

我試圖在我們爲業務創建的服務中建立編碼模式(一些規則)。 我們遵循apigree爲設計RESTful服務而制定的基本指導。ServiceStack路線和動詞

我們希望採用的規則之一是阻止我們不想支持的某些路線和動詞組合。據推測我們會發回一個HttpStatusCode.NotSupported這些非法的組合,也許是一個人類可讀的消息?

我們也希望支持的法律連擊是:

GET /resource - lists all resources 
GET /resource/{id} - retrieves specific resource by ID 
POST /resource - adds a new resource 
PUT /resource/{id} - updates specific resource by ID 
DELETE /resource/{id} - deletes specific resource by ID 

有一些非法的連擊我們明確地不想支持。

POST /resource 
PUT /resource 
DELETE /resource 

我們對每個支持的路由都有驗證器。 但我們沒有任何在我們的代碼庫中定義的非法路由。

從測試中,我們已經瞭解到,如果客戶端發送一個請求GET /resource/{id}一個空白ID(的String.Empty),然後ServiceStack魔不執行驗證該請求(GET /resource/{id}),而是重定向到GET /資源。我們認爲DELETE /resource/{id}PUT /resource/{id}的確如此。但是,這些'默認'行爲都不是可取的,我們寧願要返回一個HttpStatusCode.NotSupported或者一些標題指向客戶端的API文檔(或一些這樣的指導)。

你能否建議一些選項來在框架中明確地處理這些情況?

歡呼

回答

5

如果只想允許某些調用約定比你應明確在你允許與路由定義,如:

[Route("/resource", "GET")] 
public class GetAllResources {} 

[Route("/resource/{Id}", "GET")] 
public class GetResource 
{ 
    public int? Id { get; set; } 
} 

[Route("/resource", "POST")] 
public class CreateResource { ... } 

[Route("/resource/{Id}", "PUT")] 
public class UpdateResource 
{ 
    public int Id { get; set; } 
    ... 
} 

[Route("/resource/{Id}", "DELETE")] 
public class DeleteResource 
{ 
    public int Id { get; set; } 
    ... 
} 

比你的服務只匹配的動詞你「VE規定:

public class ResourceServices : Service 
{ 
    public object Get(GetResources request) { ... } 
    public object Get(GetResource request) { ... } 
    public object Post(CreateResource request) { ... } 
    public object Put(UpdateResource request) { ... } 
    public object Delete(DeleteResource request) { ... } 
} 

什麼是不匹配的將只是一個404 NOTFOUND,因爲有n o匹配處理請求的路由。

否則,您可以根據需要創建的服務,專門捕獲非法請求,並善待他們,e.g:

[Route("/resource", "DELETE PUT")] 
public class IllegalActions {} 

public class ResourceServices : Service 
{ 
    public object Any(IllegalActions request) 
    { 
     return new HttpError(HttpStatusCode.NotAcceptable, "ActionNotSupported"); 
    } 
} 

Error Handling wiki在顯示所有可用的ServiceStack錯誤定製做得很好。能夠映射C#例外HTTP狀態代碼也可能是有用的位置:

SetConfig(new HostConfig { 
    MapExceptionToStatusCode = { 
     { typeof(NotImplementedException), (int)HttpStatusCode.NotAcceptable }, 
     { typeof(NotSupportedException), (int)HttpStatusCode.NotAcceptable }, 
    } 
}); 
+0

問題是,您的解決方案正是我們(除了我們的Id字段是一個字符串不是一個int)。問題是,當我們調用GET/resource/{Id}並且ID爲空(即string.Empty)時,SS會將調用重定向到Get/resource,而不是404或任何其他驗證。這裏有一些神奇的工作。我們需要控制它。 –

+0

@JezzSantos你的意思是'GET/resource /'重定向?這將是ASP.NET重定向而不是ServiceStack。所以不要依賴'GET/resource'和'Get/resource /'之間的區別,它們都應該表示同樣的東西,即GET所有資源。 – mythz

+0

啊!謝謝你,這是有道理的。我想在路線的盡頭可能會出現某種Trim()嗎? –