2013-05-28 111 views
9

我正在使用ember-data構建一個EmberJS應用程序。如何用REST api實現複雜的查詢?

我的應用程序中的一些功能需要非常複雜的查詢。

舉個例子,假設我有三個實體 - 學生,老師和班級。如果我想要列出所有1993年以前出生的正在接受老師X教授的課程的學生,我該如何使用RESTful api來做到這一點?在普通的SQL中它很容易,但我不確定將這個實現到我的API中的最佳實踐。

我是否需要與我的基本REST api一起構建自定義端點?

所以我仍然有:

GET /students (which returns all the students) 
GET /students/{id} (which returns a specific student) 
etc 

但然後實現我的「定製」的查詢如下:

GET /students/custom/born_before/{date}/taught_by/{teacher_id} 

還是有這樣做的更規範的方式?

回答

4

一種選擇是讓您的學生有一個可以發佈到的搜索終結點。

所以,你可能有:

POST /students/filter 

過濾對象,你會POST看起來是這樣的:

{ BornBefore:1993, TaughtBy:123 } 

我也看到了一種選擇,其中,代替張貼的是, API有一個過濾器,然後使用查詢字符串。

我更喜歡第一個自己。尤其是如果它可能是一個長時間運行的過程,因爲您的POST可能會返回ID和/或鏈接到API調用的客戶端應用來獲取狀態更新並獲得結果。

所以最後你都會POST /Students/filter,它會迴應回來的/Students/Filter/123 rel和您的客戶端將在/Students/Filter/123做定期GET的,直到它得到的結果對象。當然,對於簡單的簡短查詢,您可以立即返回結果。但如果要花費一兩秒鐘以上,你可以走這條路。

This book by O'Reilly在構建ReSTful API方面有一些很好的信息。

+17

我不喜歡用POST來「獲取」信息,在我看來這不是RESTful。 –

+1

我更新了我的答案,以說明在某些情況下您爲什麼要發佈帖子。實質上,您正在發佈服務器運行的搜索對象,然後稍後再獲取結果。就像您將映像發佈到服務器並稍後檢索它一樣。 – taylonr

+0

那會更像'/ students/filters' - 因爲有很多。無論如何,這不是一般用例的最佳解決方案。不得不提出兩個請求來進行簡單的搜索並將其存儲在後端上,這沒什麼意義。 –

23

您可以將您

GET /students/custom/born_before/{date}/taught_by/{teacher_id} 

GET /students/?born_before={date}&taught_by={teacher_id} 

這是非常類似「舉例查詢」選項:您可以填充與所提供的域模型bean並進行查詢使用它們。田地越少,搜索越廣泛,結果越多。例如,

這是例如JIRA's API works的方式。

+1

這是一個更加標準和更實用的解決方案 –

+3

結果可以被緩存(與'POST'的解決方案相反)。 –