2014-08-28 226 views
0

我在節點js中編寫一個REST api,它將執行一個sql查詢併發送結果; 在請求我需要發送WHERE條件;例如:在ajax請求中傳遞查詢條件的最佳做法

GET 127.0.0.1:5007/users   //gets the list of users 

GET 127.0.0.1:5007/users 
     id = 1       //gets the user with id 1 

現在,條件從客戶端傳遞到請求標頭中的其餘api。 在API中,我使用了sequelize,一個需要接收特定形式(對象)中的WHERE條件的ORM;例如:具有條件:

(x=1 AND (y=2 OR z=3)) OR (x=3 AND y=1) 

這需要格式化爲一個嵌套的對象:

     -- x=1 
       -- AND -|   -- y=2 
       |  -- OR ----| 
       |     -- z=3 
     -- OR -| 
       | 
       |  -- x=3 
       -- AND -| 
         -- y=1 

所以對象應該是:

Sequelize.or (
    Sequelize.and (
     {x=1}, 
     Sequelize.or(
      {y=2}, 
      {z=3} 
     ) 
    ), 
    Sequelize.and (
     {x=3}, 
     {y=1} 
    ) 
) 

現在,我試圖通過一個簡單的字符串(比如「(x = 1 AND(y = 2 OR z = 3))OR(x = 3 AND y = 1)」),但是然後我需要一個服務器上的函數,所需的對象(在我看來,這種方法的優勢在於開發人員編寫腳本nt,可以通過簡單的方式傳遞where條件,就像使用sql一樣,並且這種方法也與使用的ORM無關,如果需要更改服務器或使用不同的ORM,則不需要更改客戶端;

將條件字符串讀入並轉換爲對象的函數讓我很頭痛(我試圖寫一個沒有成功,所以如果你有一些關於如何做這樣的事情的例子......)

我想獲得一個航線能夠執行幾乎任何種類的SQL查詢,並給出結果:

現在我對一切不同的路線:

127.0.0.1:5007/users //to get all users 
127.0.0.1:5007/users/1 //to get a single user 
127.0.0.1:5007/lastusers //to get user registered in the last month 

等了我需要查詢的其他表格(一條路線)客戶需要的每種請求); 相反,我想只有一個途徑,是這樣的:

127.0.0.1:5007/request 

(調用這個路線我會通過表名和條件字符串時)

你覺得這個解決方案將是一個好的解決方案,或者你通常使用其他方式來處理這種事情? 關於如何編寫函數將條件字符串轉換爲所需對象,您有任何想法嗎?

任何建議,將不勝感激;)

回答

1

我強烈建議你不要你的數據庫模型的任何部分暴露給你的客戶。這樣做意味着你不能改變任何你沒有破壞客戶的風險。根據您提供的一個建議,您可以並應該使用查詢參數來減少您擁有的端點數量。

GET /users //to get all users 
GET /users?registeredInPastDays=30 //to get user registered in the last month 
GET /users/1 //to get a single user 

顯然「registeredInPastDays」應該重新命名爲更笨拙的東西..這只是一個例子。

至於條件字符串,應該有大量的在線解析器。語法看起來非常簡單。

+0

我同意;構建執行所有類型查詢的單個maxi路由應該是一種將API端點減少爲1的方法(除了其他特殊路由);我正在尋找js表達式解析器;如果你已經使用過其中一些,你能告訴哪一個是你最喜歡的嗎? – 2014-08-29 15:08:19

0

恕我直言,你的解決方案的主要缺點是你正在創建另一個查詢數據的API。爲什麼從頭開始創建sthm?您應該使用現有的成熟查詢API並專注於您的業務邏輯,而不是發明新的sthm。

例如,您可以從Odata獲取查詢語法。很多人長期以來一直在制定這一標準。他們已經考慮了查詢API的不同用例和障礙。

0

資源位於一個URI。您可以使用或混合使用三種方法來解決這些問題:分層次與路徑段的序列

  1. /users/john/posts/4711

  2. 非分層與查詢參數:

    /users/john/posts?minVotes=10&minViews=1000&tags=java

  3. 使用僅影響一個路徑段的矩陣參數:

    /users;country=ukraine/posts

這通常是足夠的不夠好,但它有一個像maximum length限制。在你的情況下,一個問題是你不能容易地用查詢參數來描述andor連接詞。但是您可以使用自定義或標準查詢語法。例如,如果你想找到除卡普里福特所有汽車或車用$ 10000 $ 20000之間的價格谷歌使用的搜索參數

q=cars+OR+vehicles+%22ford%22+-capri+%2410000..%2420000 

(該%22是逃脫",該%24一個逃脫$)。

如果這不適用於您的情況,並且您希望將數據傳遞到URI之外,則格式只是您品味的問題。添加像X-Filter這樣的自定義標題可能是一種有效的方法。我傾向於使用POST。雖然你只是想查詢的數據這仍然是基於REST的,如果你把你的要求爲建立一個搜索結果的資源:

POST /search HTTP/1.1 

your query-data 

你的服務器應該在Location頭返回新創建資源:

HTTP/1.1 201 Created 
Location: /search/3 

結果仍然可以緩存,您可以將其書籤或發送鏈接。缺點是你需要額外的POST