2013-03-20 70 views
3

我們正在構建一個新的單頁前端以替換我們的Web應用程序的舊靜態html前端(帶有一些jquery)。在這樣做的時候,我們遇到了一個有關從api中獲得的對象類型的問題。在基於REST的Web應用程序中保留繼承的概念

當從我們的PHP後端將數據導出爲JSON時,我們包含一個額外的字段,我們在該字段中放置對象在導出之前所具有的類型。我們可以使用它來處理我們請求的資源的不同子類。

但是有時我們也想區分父類。考慮以下情形:

繼承樹:

Animal 
    Mammal 
     Human 
     Dog 
     ... 
    Reptile 
     Crocodile 
     Snake 
     ... 

GET /動物/

[ 
    {"_type": "Human", "id": 1, "food": "Ice Cream"}, 
    {"_type": "Human", "id": 2, "food": "Steak"}, 
    {"_type": "Human", "id": 3, "food": "Peanut Butter"}, 
    {"_type": "Dog", "id": 4, "food": "Horse Poop"} 
    {"_type": "Crocodile", "id": 5, "food": "Humans"} 
] 

當我有一定的一塊UI,其中我想顯示所有的動物,但爲實例突出顯示所有我有問題的哺乳動物,因爲我已經失去了動物是哺乳動物的知識。

我們提出的最簡單的解決方案是在從後端導出對象時包含繼承鏈。可能是這樣的:

{ 
    "_type": "Human", 
    "id": 10, 
    "food": "Ice Cream", 
    "_parentClasses": "Animal.Mammal.Human" 
} 

雖然我不認爲這是一個特別好的解決方案,它很容易實現和使用,似乎強大。

您認爲這是一個好的/好的/壞的主意,您是如何解決這個問題的?

回答

1

有很多選項。這裏是我沒見過的一個:

讓你的_type一個數組而不是一個字符串,第一個項目包含當前類和其他父類。

{ 
    "_type": ["Human","Mammal","Animal"], 
    "id": 10, 
    "food": "Ice Cream" 
} 

這應該很容易與這個在PHP端來實現:

$_type = array_keys(class_parents($this)); 
array_unshift($_type, get_class($this)); 
0

我可以看到幾種可能的實現方法。您可以開發您的REST服務器來接受URI,例如:

/animals/mammal/humans 
/animals/mammal/dog 
/animals/reptile/crocodile 

或者,您只需返回上述類型的對象即可。建立該類型的對象。

<?php 
    $object = null;  

    switch($_type){ 
     case 'human': 
      $object = new Human(); 
     break; 

     case 'dog': 
      $object = new Dog(); 
     break; 

     case 'crocodile': 
     $object = new Crocodile(); 
     break; 
    } 
?> 

只需我兩分錢就可以解決這個問題。

+0

這並不能解決我的問題,因爲我想獲取(並使用)完整的列表,但仍然需要知道對象具有哪些超類。 – martijnve 2013-03-20 14:12:42

+0

我剛剛更新了我的文章,您可能會想要使用類似於上面的PHP代碼的東西。 – ilikemypizza 2013-03-20 14:15:30

+0

@ilikemypizza我非常不喜歡你的更新方法。這需要類型和父類之間的硬編碼關係,或數據庫查找推斷的關係。這可能不是一個優雅的解決方案。 – 2013-03-20 14:16:17

0

不確定這是否符合答案,真的(或者甚至是問題有資格作爲一個問題!!),但幾年前我在時間管理器上使用了類似的過程;繼承路徑以類似的方式完成。我發現使用起來非常簡單和直觀,而不是一些基本上會導致更多工作的替代品。

爲了擴展簡單性,我還打破了OOP的正常規則,不僅讓父母知道孩子,還讓孩子知道父母。它確實爲代碼添加了一點點,但它是可行的,並且再次使整個過程變得不那麼痛苦。

1

在我看來,引起你心痛的事情是在輸出上展平你的對象。也許GET /動物應更多返回類似如下:

[ 
    {"Mammals": { 
     {"_type": "Human", "id": 1, "food": "Ice Cream"}, 
     {"_type": "Human", "id": 2, "food": "Steak"}, 
     {"_type": "Human", "id": 3, "food": "Peanut Butter"}, 
     {"_type": "Dog", "id": 4, "food": "Horse Poop"} 
    }, 
    {"Reptiles": { 
     {"_type": "Crocodile", "id": 5, "food": "Humans"} 
    } 
] 

如果你能保持輸出的對象的結構,當你發送複雜的對象返回到您的結構應該保持完整的服務器。

+0

我可以做到這一點,但這不會是一個數據集的準確表示(這是一個簡單的列表)會使它很難處理(循環所有元素將需要更多的代碼,甚至需要知道多少級別這個結構有)。 – martijnve 2013-03-20 14:19:13

+0

@martijnve告訴我的是,如果它是一個簡單的列表,它不會正確保存關係。也許重構是爲了。我通常序列化我的整個複雜的對象結構到我的JSON負載,保持順序。不幸的是,我不知道這在PHP中會有多困難,但我想象一下複雜對象有很好的JSON序列化器。我擔心的是,如果你是在一個「單位」的名單上工作,結構已經被破壞 – 2013-03-20 14:21:16

+0

該結構是,應該是一個列表。我的後端知道對象的類型及其繼承。問題是以簡單的方式將信息提供給客戶,而不涉及任何硬編碼。 在PHP中,它只是一個動物數組,當我需要知道列表中的某個動物是否爲哺乳動物時,我可以在其上進行一次instanceOf測試。 – martijnve 2013-03-20 14:24:37

1

許多很好的答案,這裏是你可能要考慮其他的選擇。

您只能通過JSON將子類發送給客戶端,然後客戶端會執行查找,無論其基類是什麼。它從服務器端向客戶端移動一些複雜性,並保持您的JSON消息清潔。