2013-03-14 33 views
10

我正在嘗試構建一個(大部分)寧靜的服務,但我正在努力處理設計的一部分。我們揭露的各種資源,在服務器端的樣子:將驗證信息添加到REST響應

public class Thing1 : Resource { 
    public string ABC {get;set;} 
    public string DEF {get;set;} 
} 

Resource是一個基類:

public class Resource { 
    public List<Link> Links {get;set;} 
} 

Link S,反過來,只要綁定rel S和uri秒。這樣,每個Resource都鏈接到其他資源等,並且消費者可以瀏覽服務提供的各種資源。

一些(但不是全部)資源是可編輯的,所以消費者將檢索資源,對其進行更改,然後PUT這些更改回服務。當然,在這一點上,服務將按需要執行驗證(並處理任何併發問題)。

但是,如果消費應用程序甚至在嘗試PUT請求之前就可以預先執行一些驗證,就可以減少不必要的往返行爲(與我們可能使用JavaScript驗證的方式大致相同即使服務器必須重複它)。

所以,我想在我們的回覆中包含一些驗證信息,以便消費應用程序知道(例如),ABC不能超過6個字符。應該注意的是,目前,消費者可以使用相同的資源類別(它們在一個單獨的程序集中,以及適當的類別) - 添加屬性(例如System.ComponentModel.DataAnnotations.RequiredAttribute)感覺不對,因爲然後消費應用程序最終與他們在共享程序集時的驗證一樣,而不是現在的現在的

還有一些驗證是基於更多策略,其中實際驗證屬性直到運行時才能計算。

tl; dr;

什麼是在REST響應中包含「有用的」驗證信息以及實際資源的好設計,以便消費應用程序可以創建良好的用戶體驗?

回答

1

如果您有足夠的預算(時間,金錢或兩者),請爲資源構建一個metaservice,以便您的其餘部分只返回數據(包含元數據標識符),並且如果客戶端需要它,可以請求驗證元數據剛剛收到的數據。這樣你只能發送客戶需要的東西,並且可以合理地分離蛋黃和白蛋。

作爲實施變體,對於每個請求/some/res/ource,您都可以創建一個夥伴/some/res/ource/meta,該夥伴將返回關於該資源的只讀元。如果路徑幾乎相同,您可以將驗證定義爲類成員上的屬性,metaservice只需從路由中找到一個類,然後從類定義構建驗證信息。

-1

如果我正確理解你的問題,你可以執行這樣的解決方案:

public class ServiceResponse 
    { 
     private List<Exception> exceptions = new List<Exception>(); 

     public List<Exception> Errors { get { return exceptions; } } 

     private string password; 
     public string Password 
     { 
      get 
      { 
       return password; 
      } 
      set 
      { 
       if (string.IsNullOrEmpty(value)) 
       { 
        exceptions.Add(new ArgumentException("Password cannot be empty!")); 
       } 

       if (value != null && value.Length < 10) 
       { 
        exceptions.Add(new ArgumentException("Password is too short!")); 
       } 

       if (exceptions.Count == 0) 
       { 
        password = value; 
       } 
       //else throw an Exception that errors were occured or do nothing 
      } 
     } 
    } 

然後你就可以檢查錯誤,它有任何錯誤,如果它不那麼顯示所有錯誤或任何你想財產。在這種情況下,只有一切正確後才能設置屬性「密碼」。硬編碼錯誤消息可以用資源字符串替換。因此,您發送的響應可以在客戶端正確處理,而不需要任何JavaScript。

3

也許是這樣,

> GET /api/Thing/1 
< 200 OK 
< Content-Type: application/vnd.acme.resource+xml 

<resource> 
    <ABC>blah</ABC> 
    <DEF>blurg</DEF> 
    <links> 
    <links rel="help" href="/api/help/things"/> 
    <links rel="http://acme.com/rels/validationrules" href="/api/validationrules/things"/> 
    </links> 
</resource> 

> GET /api/validationrules/things 
< 200 OK 
< Content-Type: application/vnd.acme.validationrules+xml 

<rules resourceType="thing"> 
    <property name="ABC" MaxLength="6"/> 
    <property name="DEF" MaxLength="8"/> 
</rules> 

我做我自己的API類似的東西。不幸的是,沒有標準的媒體類型,我知道解決這一特定需求的嘗試。我懷疑試圖定義這種類型的媒體類型會導致「廚房水槽」效應,因爲每個人都有不同的要求,他們都會被拋出,最終的結果對每個人來說都太複雜了。

但是,定義適合您特定需求的自己的媒體類型可能是一個非常易於管理的挑戰。

在我看來,這個解決方案的重要之處在於/api/validationrules/things應該很少更改,因此可以由客戶端私下緩存。這意味着客戶爲了將這些信息作爲一種獨特的資源付出了很小的代價。

相關問題