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 には独自の内部生成デフォルトがあり、私が提供したビューなどを無視しており、要求されたときにディープ レンダリングを実行していないようです。
私のビュー/テンプレートが期待どおりに呼び出されない理由を誰かが教えてくれますか?