2014-10-30 39 views
1

經過多年的網絡編程後,我現在開始從頭開始編寫新的Web應用程序。我學習了REST的一些技巧,並發現了一些有關好的和不好的「URI風格」的helfful演示和網絡研討會。但是,所有這些教程似乎都假設只有可以映射到數據庫中存在的實體的資源。如果需要GET一個HTML(用戶友好)版本的東西,那麼普遍的答案是通過HTTP頭字段使用內容negiotation。最終目標似乎只有遵循REST範式的URI。REST API和UI網頁的URI模式的最佳實踐

但是,顯示無法映射到實體但仍然需要的網頁的「正確」方式是什麼?

也許我舉個例子來說明我的意思。假設我們有一個集合Persons和實體Person

然後我們有

  • POST /Persons/到集合
  • DELETE /Person/{id}/刪除的人
  • PUT /Person/{id}/到modifiy的人(是的,我知道這也意味着創建一個在創建新的聯繫人)
  • GET /Persons/得到所有人的名單
  • GET /Person/{id}/得到一個人

關於GET操作我通常會發現,使用請求的AcceptX-Requested-With報頭字段來創建響應,要麼在計算機返回「裸露」的人對象的建議可讀代表(即JSON,XML等),或者爲瀏覽器返回完整的網頁。

但是什麼是PUT操作。最終,此操作將發送將要創建的裸人對象(即JSON,XLM),但在此步驟之前,我需要從用戶那裏收集數據。這意味着我需要一些空白的網頁表單,這對於用戶來說只是「眼睛」。當然,我可以忍受像GET /newPersonForm/這樣的東西,但是這似乎與REST哲學相矛盾,因爲/newPersonForm/是一個只指向某個用戶界面元素的URI。

目前我看到的選項:

  1. 使用相同的名稱空間都種的URI:

    • POST /Persons/ - > REST API
    • DELETE /Person/{id}/ - > REST api
    • PUT /Persons/{id}/ - > REST api
    • GET /Persons/ - > REST API或UI(後內容negiotation)
    • GET /Person/{id}/ - > REST API或UI(後內容negiotation)
    • GET /Person/creationForm - >非REST,純UI
    • GET /aboutus - >非-REST,純粹的UI,更多的公司信息
  2. 進行單獨的命名空間:

    • /api/... - >包含家居REST
    • /ui/... - >包含HTML網頁

第一個方法我覺得這是somebit 「不乾淨」。雖然第二種方法看起來更清潔,但我看到兩個問題。首先,如果採用這種方法乾淨利落,可以獲得更多的雙重URI,因爲不需要內容負擔,並且每個REST功能都有一個UI網頁。我有GET /api/Person/{id}/返回一個JSON對象,GET /ui/Person/{id}返回瀏覽器版本。其次,我覺得這種方法與REST哲學相矛盾,因爲搜索範例和網絡爬蟲不能理解網站的結構。

任何建議最佳實踐是什麼?

回答

1

首先,讓我們看看一些誤解。

  1. 任何你可以通過URI識別語義的東西都是一種資源。

  2. HTTP方法不映射到這樣的CRUD操作。閱讀this回答更多。我建議你在繼續閱讀這個答案之前閱讀它。 This one也可能會有幫助。

  3. 有沒有這樣的事情作爲URI遵循REST範式。 REST對URI的唯一約束是它們必須標識一個且只有一個資源,並且它們必須被視爲原子標識符。 URI的語義是無關緊要的,儘管顯然你應該設計對開發者和用戶有意義的URI。

正如你已經想通了,返回的東西一個用戶友好的表示正確的做法是通過經Accept頭談判。不要緊,如果它不是映射到數據庫的東西。這是一個只有服務器知道的實現細節,這就是REST的內容。當您從REST API檢索某些內容時,無論它是來自應用程序服務器,某處緩存還是來自Amazon S3提供的靜態文件,甚至是FTP鏈接。客戶端應該簡單地遵循鏈接,比如當您點擊網頁上的鏈接時,您不關心結果來自何處。

你提出的兩個選項都是有效的,但這與REST無關。在apiui中分開它們是爲你組織事情的一個很好的方式,但是REST真正重要的是客戶端如何獲得這些鏈接。如果他們通過閱讀文檔中的URI並填充值來實現客戶端,那不是REST。

從網頁瀏覽的角度思考它。你如何達到/newPersonForm的html頁面?你在別的地方跟着一個鏈接,上面有一個標籤告訴你點擊它來創建一個新的Person。如果你是一個點擊,它不在於它是否/newPersonForm/forms/newperson或簡單地/persons。 REST的工作方式完全相同。

+0

我閱讀了這兩個鏈接。但是我沒有找到我使用錯誤的HTTP方法映射到CRUD操作的地方。對我來說唯一的新信息是PUSH可以用作任何事情的「後備」方法,因爲它沒有預定義的標準化語義。無論如何,我決定去選項1,以避免過多的雙重URI,並將使用「GET/person/new」來獲得一個空的表單。它最好匹配「GET/person/{id}」,它返回相同的表單,但與用戶數據。 – user2690527 2014-10-31 21:33:42