4

Grails 2.1.1 アプリケーションで RESTful インターフェイスを構築しています。検索操作をどのように実装すればよいですか? 私の現在の考えでは、膨大な量のコードを繰り返したくありません。

サーバーの構造はごく普通の Grails-MVC です。ドメイン クラスはデータを表し、コントローラーはインターフェイスを提供し、サービスはビジネス ロジックを持ちます。コントローラーでのデータ バインディングにコマンド オブジェクトを使用しますが、サービス メソッドでは使用しません。クライアントは Web UI です。私の目標は、次のような検索 URL を持つことです。

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

(クエリ文字列を使用したこの種の URL の RESTfulness に関する議論については承知しています: RESTful URL design for search。これが私の目的に最適なモデルだと思いますが、API とより良い実装。)

以下のコード例からわかるように、私の問題は 2 番目の種類の URL、フィールド固有の検索にあります。多くのフィールドを持ついくつかのドメイン クラスに対してこの種の検索操作を実装するために、私のメソッド シグネチャは爆発的に増加します。

おそらくこれを行うための「Groovy の方法」があると思いますが、私はまだ細かい 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") {
        // ...
    }
}

URL マッピング:

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"]
        }
    }
}
4

1 に答える 1

1

このすべてのパラメータはparams、次のようにから取得できます。

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

マップの値はすべてparams文字列であるため、コントローラーで適切なデータ構造に変換する必要があります(params.year実際の数値であることを確認することをお勧めします)


アップデート

フィールド名を書きたくない場合は、マップとして渡すことができます。

resutl = carService.search(params)

どこ

List<Car> search(Map params)
于 2012-12-11T10:47:01.120 に答える