2013-04-12 59 views
6

我對REST比較陌生,但我一直在做RESTful應該如何做的功課。現在我正在嘗試爲我的模型創建一個實現JSON + HAL序列化器的RESTful api,這些模型與其他模型有關係。
例模型蟒蛇:使用HAL設計RESTful API - 序列化模型關係

class Category(Model): 
    name = CharField() 
    parent = ManyToOneField(Category) 
    categories = OneToManyField(Category) 
    products = ManyToManyField(Product) 

class Product(Model): 
    name = CharField() 
    price = DecimalField() 
    related = ManyToManyField(Product) 
    categories = ManyToManyField(Category) 

讓我們假設有一類「目錄」與子類「食品」產品「漢堡」和「熱狗」,這都是相關的。
第一個問題。類別和產品應該是資源,所以他們需要一個URI,我應該在模型中實現一個uri字段並將其存儲在數據庫中或以某種方式在運行時計算它,那麼多標識符(URI)又如何呢?
第二個問題。 可發現性,在Hal格式中,應該「GET /」和不同的節點返回以使api容易自我發現。

{ 
    "_links":{ 
    "self":{ 
     "href":"/" 
    }, 
    "categories":[ 
     { 
     "href":"/catalog" 
     } 
    ] 
    } 
} 

第三個問題。添加爲屬性,嵌入或鏈接。例如「GET/catalog/food」:

{ 
    "_links":{ 
    "self":{ 
     "href":"/catalog/food" 
    } 
    }, 
    "name":"food", 
    "parent":"/catalog", 
    "categories":[], 
    "products":[ 
    "/products/burger", 
    "/products/hot-dog" 
    ] 
} 

{ 
    "_links":{ 
    "self":{ 
     "href":"/catalog/food" 
    }, 
    "parent":{ 
     "href":"/catalog" 
    }, 
    "categories":[ 

    ], 
    "products":[ 
     { 
     "href":"/products/burger" 
     }, 
     { 
     "href":"/products/hot-dog" 
     } 
    ] 
    }, 
    "name":"food" 
} 

{ 
    "_links":{ 
    "self":{ 
     "href":"/catalog/food" 
    } 
    }, 
    "name":"food", 
    "_embedded":{ 
    "parent":{ 
     "_links":{ 
     "self":{ 
      "href":"/catalog" 
     } 
     }, 
     "name":"catalog", 
     ... 
    }, 
    "categories":[ 

    ], 
    "products":[ 
     { 
     "_links":{ 
      "self":{ 
      "href":"/products/burger" 
      } 
     }, 
     "name":"burger", 
     ... 
     }, 
     { 
     "_links":{ 
      "self":{ 
      "href":"/products/hot-dog" 
      } 
     }, 
     "name":"hot-dog", 
     ... 
     } 
    ] 
    } 
} 

第四個問題。返回結構時應該多深。例如「GET /目錄

​​3210
+0

那你是如何最終處理? –

回答

6

關於第一個問題:我不會存儲在數據庫中的URI您可以輕鬆地計算出它們的運行系統控制器內,它是控制器的責任關心的URI。這樣,您可以保持模型和API的解耦,並且如果您決定在將來更改API結構,則不需要使用新的URI更新整個數據庫。

關於多個標識符,我不知道問題是什麼,但在我看來,它與數據庫無關,它是路由和控制器誰應該關心如何處理任何URI。

關於第二個問題:首先,作爲一個側面說明:我會保持這個詞類別作爲URI的一部分。例如,我有http://domain.com/api/categories/catalog/food。這樣,您可以使您的API更具描述性,更「可破解」,這意味着用戶應該能夠刪除/catalog/food部件,並期望收到包含所有可用類別的集合。

現在,關於什麼GET應該返回到允許可發現性:我認爲它已經從您的URI結構明確。當用戶點擊GET /categories時,他希望獲得一個包含類別(每個類別的名稱和URI,以保持其輕量級)的列表,並且當他跟隨其中一個URI(如GET /categories/catalog)時,他應該收到資源catalog這是一個類別。同樣,當他想要GET /products/burger時,他應該會收到一個包含模型中所有屬性的產品資源。您可能需要檢查this example有關您的回覆結構。

關於第3個問題:再次,the same example可以幫助您形成結構。我認爲你的第二種反應方式更接近於此,但我也會添加一個name字段,而不僅僅是href

關於第四屆問題:當GET請求需要資源的集合(如GET /categories)我建議每個資源只提供必要的,那就是,名稱和URI每個只有當用戶跟隨所需的URI,他可以收到其餘的信息。

在你的榜樣,catalog是一種資源,等等GET /categories/catalog我會包括課程的資源(目錄)和自身環節的name,併爲parentsub-categoriesproducts這都涉及到它,我只想提供每個的名稱和URI,以保持輕量級。 但是:這是關於設計API的一般想法。在你的實際問題中,應該根據你的具體業務問題來決定。我的意思是,如果你的API是關於類別和菜餚的餐廳的菜單,你可能希望不是實際的產品,但對產品的集合響應時,包括價格,或一個小的描述,甚至,因爲可能是你的用戶,這是一個重要的信息。因此,通常,在回覆資源列表時提供所有必要信息(您只知道這些是針對您的問題的),並在回覆特定資源時提供資源的所有詳細信息。

1
  1. 我會在數據庫中存儲一些內容並在運行時計算URI。這樣如果你移動盒子,它不是靜態的。
  2. 創建一個「書籤」頁面。我們創建的頁面只是它們的rels鏈接列表。我相信HAL特別定義了這一點。書籤頁是其他頁面需要了解的唯一頁面
  3. 不確定關於此
  4. 你有多深是由你決定的。現在在我的工作地點有一個很大的爭論,那就是細粒穀粒。我打算用小資源做精細的糧食,以保持api簡單,但隨後使用Expand-ability概念。這是Subbu的REST書第35頁定義的複合資源概念和Netflix使用的擴展概念的結合。 http://developer.netflix.com/docs/REST_API_Conventions