2017-10-17 75 views
0

我是node.js的新手,並在hapi.js框架中創建了我的第一個node.js Restful API。所有的服務基本上都在做數據庫查詢。該服務的一個例子是這樣的:構建Restful API時選擇哪種HTTP方法

let myservice = { 
    method: "POST", 
    path: "/updateRule", 
    config: { 
     handler: (request, reply) => { 
      updateRule(request.payload) 
      .then((result) => { 
       reply(successResponse(request, result)); 
      }) 
      .catch((err) => reply(failResponse(request, err)).code(500)); 
     }, 
     validate: { 
      payload: { 
       ruleId: joi.number().required(), 
       ruleName: joi.string().required(), 
       ruleDesc: joi.string().required() 
      } 
     }, 
     auth: "jwt", 
     tags: ["api", "a3i"] 
    }, 
} 

updateRule(input): Promise<any> { 
     return new Promise((resolve, reject) => { 
      let query = `select a3i.update_rule(p_rul_id := ${input.ruleId}, p_rul_name := '${input.ruleName}', p_rul_desc := '${input.ruleDesc}')`; 
      postgresQuery(lbPostgres, query, (data, commit, rollback) => { 
       try { 
        let count = data.rows[0].update_rule.count; 
        if (count === 1) { 
         let ruleId = data.rows[0].update_rule.result[0]; 
         let payload: SuccessPayload = { 
          type: "string", 
          content: `Rule ${ruleId} has been updated` 
         }; 
         commit(); 
         resolve(payload); 
        } else { 
         let thisErr = new Error("No rule can be found."); 
         thisErr.name = "4003"; 
         throw thisErr; 
        } 
       } 
       catch (err) { 
        rollback(); 
        if (err.name === "4003") { 
         reject(detailError(4003, err.message)); 
        } else { 
         reject(detailError(4001, err.message)); 
        } 
       } 
      }, reject); 
     }); 
    } 

正如你所看到的,當服務被調用時,它喚起數據庫調用(查詢)和更新指定行中的數據庫表。同樣,我還有其他名爲createRule/deleteRule的服務在數據庫表中創建/刪除記錄。 在我看來,服務之間的區別是做不同的數據庫查詢。我看了這篇文章PUT vs. POST in REST,但在我的情況下看不到任何POST和PUT的區別。

這裏是我的問題:

  1. 我應該在這種情況下使用什麼HTTP方法?

  2. 大部分寧靜的API的例子(例如https://www.codementor.io/olatundegaruba/nodejs-restful-apis-in-10-minutes-q0sgsfhbd)使用不同的HTTP方法相同的URL上相同的「資源」,這在我看來是通常一個數據庫表做不同的操作。與我的慣例相比,這種體系結構的好處是什麼?其中一個URL只有一個HTTP方法,只能執行一種類型的操作?

我知道這個問題沒有提到問題,也沒有具體說明。有些人可能會給它一個倒票。但作爲初學者,我真的很想知道什麼是典型的Restful API,並確保我的API是「最佳實踐」。請幫忙!

回答

2

如果資源已經存在,因此你有一個特定的URI到那個確切的資源,你想更新它,然後使用PUT。

如果資源尚不存在,並且您想要創建它,並且您將讓服務器選擇代表該新資源的URI,那麼使用POST並且POST URI將是一個通用的「創建新資源」URI,不是特定資源的URI,它將創建表示該資源的URI。

如果調用者要創建表示新資源的資源URI,還可以使用PUT創建新資源。在這種情況下,您只需將PUT添加到該新資源中,並且如果具有該URI的資源已經存在,則該資源將被更新,否則將被創建。

您不必同時支持兩者。你可以決定讓你的api工作,你只需要使用一個或另一個。


在您的特定情況下,在你的數據庫中的特定行已經存在將幾乎永遠是一個PUT因爲它已經存在,所以你在做一個PUT到特定URI表示該行的更新。

與我的慣例相比,這種體系結構的好處是什麼?其中一個URL只有一個HTTP方法並且只執行一種類型的操作?

這真的取決於你如何呈現你的API。背後REST的一般概念是,你有幾個組成部分:

resource identifier 
data 
method 

在某些情況下,該方法可以通過GET被納入,PUT,POST或DELETE,所以你只需要資源標識符,數據和GET,PUT, POST或DELETE。

在其他情況下或其他設計中,該方法比僅在PUT或POST中可以表示的方法更詳細,因此實際上在URL中有一個方法,在這種情況下,您可能不需要區分PUT和POST儘可能多。

例如,一個動作可能是「買」。雖然您可以在POST中捕獲該方法,但該方法由URL的其餘部分隱含,但您可能希望實際發佈到其中包含方法的URL:/buy以便清晰起見,然後您可以使用與其他方法相同的端點前綴方法,如/addToCart等......它的確取決於REST設計中的對象以及您想要在其上展示哪些操作。有時候,這些對象只適用於GET,PUT,POST和DELETE,有時候,您希望URL中有更多的信息可以在該資源上執行特定的操作。

+0

看來我不得不向服務路徑添加一個參數,因此每個資源(數據庫表中的一行)都有相應的url。例如,當我想要對記錄執行操作時,我需要將唯一ID作爲url中的參數傳遞。這是正確的嗎? – zhangjinzhou

+0

@ zhangjinzhou - 這將是RESTful的方式。 GET,PUT或DELETE的每個URI應代表一個唯一的資源。 – jfriend00

+0

是的,這是正確的。這被定義爲URL中的可選參數。 – Silencer310

1

如果你想成爲休息兼容,你可以使用PostGet。 如果你想成爲問題的REST,你需要基礎的方法對CRUD

  • 創建 - >發表
  • 閱讀 - >獲取
  • 更新 - >把或補丁
  • 刪除 - >刪除

關於構建完整的API,在相同的URL上使用方法可能更容易建立/理解。所有關於您的user的查詢將位於user網址上,而不是user/getuser/add, user/update ......它讓您擁有相同的功能,沒有太多不同的URL。

當你建立一個API時,你會想要一些日誌,進行統計分析和其他的東西。這樣,如果您使用方法進行分割,則可以只使用篩選器記錄多少Post請求或Get請求。

實際上,您也可以只使用Get請求來構建API。但隨着方法和URL劈裂是避免複合URL(或URL有太大的動作名稱),並有每一個請求,通過你的API去記錄一個最簡單的方法最好的辦法

enter image description here - 列表項

  • 級別1是休息

  • 級別2是REST風格

  • 級別3是HATEOAS

你應該找一些書籍或由Martin Fowler

+0

感謝您的發佈。不同的級別是非常有幫助的!我知道GET通常不足以構建API,因爲您可能想要上傳文件或傳遞流或其他內容。但是,使用POST/PUT創建/更新資源時,我沒有看到任何區別。 – zhangjinzhou

+0

不能像使用POST一樣使用PUT創建新資源,而不指定標識符? – zhangjinzhou

+0

是的,你可以使用這種方式 – sheplu

0

寫的文章裏面更多的信息我最常做的是使用「POST」創建一個新的資源,並使用「PUT」用於更新現有資源。

對於第二個問題,是的,大多數API使用相同的URL在同一資源上執行不同的操作。這可能是因爲您不希望公開您在URL中做什麼(例如/刪除)的安全性。此外,許多框架爲資源(對象類)生成一個自動URL,然後在請求方法上區分它。人們不會傾向於使用自定義網址。