我正在努力获取 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 有自己的内部生成的默认值,并且忽略了我提供的视图等,并且在请求时似乎没有进行深度渲染。
有人会建议为什么我的视图/模板没有按预期调用吗?