2012-12-10 61 views
4

我在Grails 2.1.1應用程序上構建了一個RESTful接口。我應該如何實施搜索操作?我不想重複我目前的想法所需要的大量代碼。在Grails上搜索RESTful接口的實現

服務器結構非常正常Grails-MVC:域類表示數據,控制器提供的接口和服務都有業務邏輯。我使用命令對象在控制器中進行數據綁定,但不使用服務方法。客戶端是一個Web UI。我的目標是有這樣的搜尋網址:

/cars/?q=generic+query+from+all+fields 
/cars/?color=red&year=2011 

(我知道對這種與查詢字符串的URL的RESTfulness辯論:RESTful URL design for search雖然我覺得這是我的目的的最佳模式,如果他們使API和實現更好,我願意接受替代方案。)

正如您從下面的代碼示例中看到的,我的問題是第二種URL特定於字段的搜索。爲了對包含大量字段的幾個域類實現這種搜索操作,我的方法簽名會爆炸。

有可能是一個 「常規的方式」 來做到這一點,但我還是有點的n00b的更細的Groovy技巧:)

域:

class Car { 
    String color 
    int year 
} 

控制器:

class CarsController { 
    def carService 
    def list(ListCommand cmd) { 
     def result 
     if (cmd.q) { 
      result = carService.search(cmd.q, cmd.max, cmd.offset, cmd.order, cmd.sort) 
     } 
     else { 
      result = carService.search(cmd.color, cmd.year, cmd.max, cmd.offset, cmd.order, cmd.sort) 
     } 
     render result as JSON 
    } 

    class ListCommand { 
     Integer max 
     Integer offset 
     String order 
     String sort 
     String q 
     String color // I don't want this field in command 
     int year // I don't want this field in command 

     static constraints = { 
      // all nullable 
     } 
    } 
    // show(), save(), update(), delete() and their commands clipped 
} 

服務:

class CarService { 
    List<Car> search(q, max=10, offset=0, order="asc", sort="id") { 
     // ... 
    } 

    List<Car> search(color, year, max=10, offset=0, order="asc", sort="id") { 
     // ... 
    } 
} 

UrlMappings:

class UrlMappings { 
    static mappings = { 
     name restEntityList: "/$controller"(parseRequest: true) { 
      action = [GET: "list", POST: "save"] 
     } 
     name restEntity: "/$controller/$id"(parseRequest: true) { 
      action = [GET: "show", PUT: "update", POST: "update", DELETE: "delete"] 
     } 
    } 
} 

回答

1

您可以從params得到這一切的參數,如:

result = carService.search(params.color, params.year as Integer, cmd.max, cmd.offset, cmd.order, cmd.sort) 

params地圖的所有值都是字符串,所以你應該把它轉換成合適的數據結構控制器(和它的更好地檢查params.year是實際數)


更新

如果你不想作家字段名,你可以把它作爲一個Map:

resutl = carService.search(params) 

其中

List<Car> search(Map params) 
+0

我想通過對搜索方法所有字段,而明確寫入方法簽名。如果服務方法簽名具有字段,那麼在更改域對象中的字段時,我將不得不更改服務接口。 我也可以使用服務接口的REST接口命令對象,但它感覺不對。 – apa64

+1

將它作爲地圖傳遞 –

+0

似乎將params地圖傳遞給服務方法是最簡單的方法。我的服務方法簽名是: 'List search(params = null,max = 10,offset = 0,order =「asc」,sort =「id」)' 我刪除了控制器參數需要搜索: 'params?.remove(「action」)' 稍後,我從param成員中構建一個'findAllWhere()'查詢,我想在搜索中使用它。 – apa64