GrailsView解析jsonApi帖子数据-Grails团队在jsonViews中做通用解决方案吗?

问题描述 投票:0回答:1

我正在使用grailsViews和jsonApi格式进行项目。我正在使用Grails v3.3.9和jsonViews v1.2.10。

因此,视图为从您的域模型生成jsonApi提供了模板支持,但是我找不到允许您根据发布/修补的数据构建域对象(和树)的逆模型。

我设法使这个笨拙的版本起作用,但这是一个快速的技巧。

本质上,我必须重写RestfulController中的createResource方法。这是抓住帖子的正文并对其进行解析。它浸入json并找到属性,并尝试将bindData用于此简单属性映射。

关系更难。我必须遍历这些内容,看看每个标签是否有包含数据的子级。

然后我必须addTo<Tag>(对于每个条目,如果我可以在域模型中找到要添加到集合的实例。此代码有很多问题-但实际上可以解决持久化新的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团队可能对此有所作为。如果没有,我将请求功能增强。

rest grails controller json-api
1个回答
0
投票

还有一些命令对象,从技术上讲,您可以将Domain对象用作命令对象。我不建议在玩具应用程序外部将域对象用作命令对象,因为存在固有的安全风险,这就是为什么我认为该对象不是...

但是我建议您使用命令对象,因为它们以某种方式为您提供了基本的验证并记录了您的控制器API。需要注意的是,我通常尝试使命令对象保持明亮状态,而不添加服务或执行调用,原因与您在域中不执行命令,内存消耗和db调用属于过渡服务中的原因相同。同样,我通常将参数从命令对象传递到“漂亮的”布局API,除非命令对象代表Jon文档,否则可能会造成麻烦。

还有一个命令插件,可以像其他Grails工件一样为命令对象提供更多的配置约定。我写的,所以你可以加一点盐:)

© www.soinside.com 2019 - 2024. All rights reserved.