0

JSON API の取得と、ドメイン クラスの json のレンダリングに苦労しています。Grails v3.3.3 と JsonViews 1.2.7 を使用しています

@Resource アノテーションを使用してドメイン クラスを公開すると、コントローラーと「デフォルト」の json 出力が自動的に生成されます。

ただし、何が起こっているのかをある程度制御したいので、別のドメイン クラス (Customer と、Customer hasMany Sites のデモ アプリの Site) があります。

これらのドメイン クラスのいずれでも @Resource アノテーションを使用しません。

CustomerRestController と SiteRestController という 2 つのコントローラーを手動で作成し、UrlMappings を使用して URI を公開します。(1 つは '(resources: controller)' フォームを使用し、もう 1 つは宣言された明示的なコントローラーとアクションを使用します。

class UrlMappings {

    static mappings = {

        "/api/customers"(resources:"customerRest")

        //or try to declare with explicit mappings
        "/api/sites" (controller: "siteRest", action: "index")
        "/api/sites/$id" (controller: "siteRest", action: "show", view: "show")

        "/$controller/$action?/$id?(.$format)?"{
            constraints {
                // apply constraints here
            }
        }

        "/"(view:"/index")
        "500"(view:'/error')
        "404"(view:'/notFound')
    }
}

まず、SiteRestController で何が起こるかを見てみましょう (単純なデバッグ println を使用して、コンソールで呼び出されていることを示します)。私は GORM データ サービス モデルを使用し、サービスでインターフェイスを定義し、Grails に serviceImpl を自動構築させ、これをコントローラーに挿入しました。応答フォーマットを [json] と宣言しました

@CompileStatic
class SiteRestController extends RestfulController {

    static responseFormats = ['json']

    SiteService siteService

    SiteRestController() {
        super (Site)
        println "siteRest default constructor controller created"
    }


    def index (Integer max)/*(@PathVariable String manufacturerName)*/ {
        println ("site.index: invoked index action on customer restful controller ")
        respond siteService.list([:]), model:[siteCount: siteService.count()]

    }


    def show(Long id) {
        println "site.show: show on SiteRestController called with $id"
        respond siteService.get(id)
    }


}

/views/site/_site.gson、index.gson、および show.gson を手動で作成しました

//_site.gson
import model.Site
println "_site template called "  //added to check that template is being called 

model {
    Site site
}

json jsonapi.render (site)

ビューが無視されていることを示すために、次のように show.gson を編集しました

import model.Site

model {
    Site site
}

json g.render ([name:"will"])

および index.gson ビューとして

import model.Site

model {
    List<Site> siteList
    Long siteCount
}
println "index.gson more data"
json {
    name  "hello william"
}

したがって、アプリを起動して「/api/sites」URL を呼び出すと、これが表示されます。これは単なる標準的なレンダリングであり、_site.gson を使用せず、index.gson を無視します

[
    {
        "id": 1,
        "name": "headoffice",
        "customer": {
            "id": 1
        }
    }
]

そして、「/api/sites/1」を呼び出すと、次のようになります (これは明らかに _sites.gson テンプレートを呼び出していますが、「show.gson」はテンプレートを使用しないように変更されており、これは明らかに無視されています)

_site template called 
{
    "data": {
        "type": "site",
        "id": "1",
        "attributes": {
            "name": "headoffice"
        },
        "relationships": {
            "customer": {
                "links": {
                    "self": "/customer/show/1"
                },
                "data": {
                    "type": "customer",
                    "id": "1"
                }
            }
        }
    },
    "links": {
        "self": "/site/show/1"
    }
}

また、このような顧客ビュー テンプレートからディープ レンダリングを実行しようとしました

import model.Customer


model {
    Customer customer
}

json jsonapi.render (customer, [deep:true, jsonApiObject:true])

/api/customers/1 をクエリすると、ディープ レンダリングに関するサイトの詳細が無視されます。サイトにはデフォルトの ID が表示されているだけで、_site.gson を呼び出していないように見えることに注意してください。

{
    "jsonapi": {
        "version": "1.0"
    },
    "data": {
        "type": "customer",
        "id": "1",
        "attributes": {
            "name": "hsbc"
        },
        "relationships": {
            "sites": {
                "data": [
                    {
                        "type": "site",
                        "id": "1"
                    }
                ]
            }
        }
    },
    "links": {
        "self": "/customer/show/1"
    }
}

だから私はここで何が起こっているのか理解していません。Grails には独自の内部生成デフォルトがあり、私が提供したビューなどを無視しており、要求されたときにディープ レンダリングを実行していないようです。

私のビュー/テンプレートが期待どおりに呼び出されない理由を誰かが教えてくれますか?

4

0 に答える 0