Grails v3.3.9 / jsonViews v1.2.10
работа над мини-проектом с использованием grailsViews и формата jsonApi.
поэтому представления предоставляют поддержку шаблонов для генерации jsonApi из модели вашего домена, но я не могу найти обратное, которое позволяет вам строить объект (и дерево) домена из данных, которые публикуются / исправляются.
Мне удалось заставить эту неуклюжую версию работать, но она взломана, прежде чем я лег спать.
по сути, мне пришлось переопределить метод createResource в RestfulController. Для этого нужно взять тело сообщения и проанализировать его.
он погружается в 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, возможно, что-то сделала для этого.
Если нет, я попытаюсь запросить улучшение функции