grails v3.3.9 / jsonViews v1.2.10
使用grailsViews和jsonApi格式处理迷你项目。
因此,视图提供了从域模型生成jsonApi的模板支持,但是我找不到允许您根据发布/修补的数据构建域对象(和树)的逆函数。
我设法使这个笨拙的版本能够正常工作,但是在我上床睡觉之前是一个黑客。
从本质上讲,我不得不重写RestfulController中的createResource方法。这是抓住帖子的正文并对其进行解析。
它浸入json并找到属性,并尝试将bindData用于此简单属性映射。
关系更加困难。我必须遍历这些,看看是否有每个子代都有数据。
然后我必须addTo(如果可以在域模型中找到要添加到集合的实例,则需要为每个条目添加。对于此代码,问题丢失了-但实际上确实可以持久保存新的OrgRoleInstance
//works - needs lots of improvement !! overwites, lookups etc
@Override
protected <T extends OrgRoleInstance> T createResource() {
def instance = super.resource.newInstance()
RequestFacade requestFacade = getObjectToBind()
BufferedReader bodyReader = requestFacade.request.getReader()
long bodyLength = requestFacade.request.getContentLengthLong()
String jsonBody = bodyReader.text
//String strippedBackJson = jsonBody.replaceAll("\\s+","")
JsonSlurper slurper = new JsonSlurper()
def body = slurper.parseText (jsonBody)
def data = body.data
String bodyDataType = body.data.type
//json views api seems to show the class starting in lower case - change to uppercase
String dataType = convertFirstCharToUppercase (bodyDataType)
Map attributes = body.data.attributes
Map relationships = body.data.relationships
//wrap in a try block
//def jsonClassRef = Class.forName(toToBindString) - https://stackoverflow.com/questions/13215403/finding-a-class-reflectively-by-its-simple-name-alone
//assume users know what they are doing ! - just sanity check simple name
String resClassSimpleName = resource.getSimpleName()
assert dataType == resClassSimpleName
//needs a custom bindData
bindData instance, attributes //getObjectToBind()
//process any relationships and bind these
relationships.each {tag, value ->
def dataArray = value.data
for (item in dataArray) {
def jsonType = item['type']
//convert first char to uppercase
String type = convertFirstCharToUppercase (jsonType)
def id = Long.parseLong (item['id'])
//with type and id try and find in existing domain model
def refEntity
Class<?> domainClass = domainClassLookupByName (type)
if (domainClass) {
refEntity = domainClass.get (id)
}
//help cant overwrite foreign key - clone the mag?
if (refEntity) {
def prop = convertFirstCharToUppercase(tag)
instance."addTo$prop" (refEntity)
//if (refEntity.validate())
//refEntity.save (failOnError:true)
}
instance
}
}
//bindData instance, relationships //getObjectToBind()
instance
}
帖子数据看起来像这样(我很漂亮地将get操作的输出打印到了另一个编辑过的记录末端。
请注意,这是一个缺陷-但是类型的jsonapi呈现:对类型使用小写字符,而不是您期望的大写字母-我必须对此进行补偿)
我希望grails团队可能对此有所作为。
否则,我将尝试请求功能增强
答案 0 :(得分:0)
有一些命令对象,从技术上讲,您可以将Domain对象用作命令对象。我不建议将域对象用作玩具应用程序之外的命令对象,因为存在固有的安全风险,这就是为什么我认为域对象不是...
但是我建议您使用命令对象,因为它们以某种方式为您提供了基本的验证并记录了您的控制器API。需要注意的是,我通常尝试使命令对象保持明亮状态,而不添加服务或执行调用,原因与您在域中不执行命令,内存消耗和db调用属于过渡服务中的原因相同。同样,我通常将参数从命令对象传递到“巧妙地”布局的API,除非命令对象代表Jon文档,否则可能会造成麻烦。
还有一个命令插件,可以像其他Grails工件一样为命令对象提供更多的配置约定。我写的,所以可以带一点盐:)