0

我正在努力获取 JSON API,并为域类渲染 json。我正在使用 Grails v3.3.3 和 JsonViews 1.2.7

如果我使用 @Resource 注释公开域类,则会自动生成控制器和“默认”json 输出。

但是,我想对正在发生的事情进行一些控制,所以我有另一个域类(客户和我的演示应用程序中的站点,其中客户有许多站点)。

我不在这些域类中使用 @Resource 注释。

我手动创建了两个名为 CustomerRestController 和 SiteRestController 的控制器 - 并使用 UrlMappings 来公开 URI。(一个使用“(资源:控制器)”形式,另一个使用声明的显式控制器和操作:

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”网址时,我得到了这个。这只是一个标准渲染,不使用 _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