2016-12-04 78 views
0

我將從頭開始創建一個REST API的PHP客戶端。我考慮使用Guzzle library什麼是API客戶端的良好體系結構?

我認爲用戶不應該像處理請求對象(甚至是來自自定義的xxxRequest類)那樣處理傳輸事件,而應該只處理業務對象/服務類。但可能是我錯了......

以下是一些可能的架構示例。哪些方面是最佳做法,爲什麼?
隨意改善它們或建議更好的方法。


例1:

class ApiClient { 
    function createBooking (BookingEntity $booking, CustomerEntity $customer) { 
     //... 
    } 
} 

這個例子允許用戶僅使用業務對象,但ApiClient類API是否需要很多方法可以開始髒...除了如果我們想添加功能,必須修改ApiClient。


實施例2:

class ApiClient { 
    function execute(CreateBookingRequest $createBookingRequest) { 
     //... 
    } 
} 

class CreateBookingRequest { 
    private BookingEntity $booking; 
    private CustomerEntity $customer; 
    private $queryParams; 

    public createQueryParams() { 
     // to create the query params (from the attibutes) for the http client 
    } 
} 

在這裏,如果一個新的特徵是需要ApiClient還沒有被修改,僅僅一類新的具有被創建。但是用戶必須處理使用Request後綴命名的類。海事組織他不知道任何關於請求或技術的事情。


實施例3:

class BookingService { 
    function createBooking (BookingEntity $booking, CustomerEntity $customer) { 
    //... 
    } 
} 

該實施例增加一個層。


在所有情況下,ApiClient/Service類中的哪個應該是Guzzle httpClient屬性?或者ApiClient類應該擴展Guzzle客戶端類嗎?

回答

1

那麼,那裏並沒有真正的標準,但這絕對是一個熱門話題,我甚至會說,這不是Guzzle特有的。

簡答:我會根據API的複雜性選擇選項1和3。

更長的答案:如果有不同的資源(如預訂獲取,創建,刪除和更多),那麼我會選擇3.如果只有幾個API調用,那麼我仍然會選擇三,因爲從API的角度來看這是一個更好的表示(你的API客戶端實際上只是API的實現,所以它應該遵循API的約定,術語...至少在理論上),但是選項1可能更快起初更容易理解。如果API變得越來越複雜,那麼維護工作可能會變得很艱難,所以即使最終您也必須將其重寫爲選項3.

配置的Guzzle實例將轉到您的類的構造函數。

如果您擁有資源/服務類(在此情況下,它不會超過您的資源類的配置入口點和工廠),仍然可以擁有API客戶端類。

如果您打算重新使用該客戶端在多個項目中,你可能要考慮使用,而不是暴食的HTTP客戶端的抽象(如HTTPlug,因爲你可能無法在所有這些安裝狂飲6(依賴性的衝突,等等)

最後,但並非最不重要的,你可能要檢查this出這將是整整這些情況下,API基礎/引導(但它尚未完成,所以需要您自擔風險使用它)

+0

非常有趣的是,如果有很多輸入參數,你會提出什麼建議?例2可以將它們作爲屬性放在xxxRequest類中,因爲最好使用一個對象而不是大量的p參數,我們如何重現例1&3?如果我們添加一個類,那麼什麼是一個好的命名約定?我們暫時說xxxParam,其中應該是適配器函數將每個xxxParam屬性轉換爲http客戶端的查詢參數(在本例中爲json主體)? – Kwadz

+0

它完全取決於你的域名。許多參數通常意味着某種數據結構,而不是完全無關緊要的參數。在那種情況下,我會把它們放到模型類中。我可以再次指出這樣一個事實,即客戶端實際上是一個接口的實現,並且API很可能也公開了一個數據模型,您可以按原樣使用它。序列化發生在客戶端本身內部,它知道如何序列化模型。可選的,你可以有一個單獨的序列化層,但它仍然會被客戶端調用。 –

+0

好吧,但如果在createBooking方法中有很多模型對象作爲輸入參數,我認爲將它們包裝在單個對象中是一種很好的做法,我錯了嗎?例如,假設我們有參數:http://pastebin.com/dBKJnk4S我認爲createBooking方法中有9個參數是不可接受的,所以我們必須包裝它們,不是嗎?什麼是這樣做的好方法?爲了保持這些類別的清晰,什麼可能是一個很好的後綴?應該將代碼翻譯成json主體的代碼在哪裏? – Kwadz

相關問題