kbss-cvut / jb4jsonld

JSON-LD serialization and deserialization for Java REST services.
GNU Lesser General Public License v3.0
10 stars 3 forks source link

Clarification on deserialization #67

Closed ChrisGitWorkshop closed 1 month ago

ChrisGitWorkshop commented 1 month ago

Hi,

Can i check whether a nested object in which the child nodes does only have "@id" without "@type" will perform the deserialization using the jb4jsonld ?

This use case come when, i need to refer an already existing person object in the payload which only have a id.

I saw the config property assumeTargetType = true to deal with this (As per my understanding). But it doesn't work as I expected. I am getting the below error There are unresolved references to objects. (Though i noticed, i am getting the targetted Type in debug, but since its not PersistenceProperties#IDENTIFIER_TYPE, not added).

When i do a quick analysis, i found below.

In javaCollectionDeserializer#resolveValue(Map) , there is a conditiona as below

} else if (value.size() == 1 && value.containsKey(JsonLd.ID)) {
   handleReferenceNodeInCollection(value, targetType);
}

So from the above code, the execution goes all the way to DefaultInstanceBuilder#addNodeForREference(String). From here it check for canDirectlyAddNodeReference (targetType), where it check whther the targetted type is any of PersistenceProperties#IDENTIFIER_TYPE, since its adding to pendingReferenceRegistry.

/**
 * Supported identifier Java types.
 * <p>
 * This set represents the Java types that can be used as entity identifiers or as {@link
 * cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty} property values.
 */
public static final Set<Class<?>> IDENTIFIER_TYPES = Set.of(URI.class, URL.class, String.class);

Example object given below.

{
    "@context": {        
        "example": "https://example.model/data#"
    },
    "@type":"example:SocialMediaAccount",
    "example:profileName": "MyNameIsXYZ",
    "example:bestFriend": {
        "@id": "https://socialmedial/account/person/MyBestiee"
    }
}

Any input would be appreciated.

Thanks in advacne, Chris.

ledsoft commented 1 month ago

Hi Chris, sorry for the delayed response. I think your analysis is pretty much spot on. JB4JSON-LD will assume an object containing only @id is a reference to a fully serialized object. That's why it is put into the PendingReferenceRegistry.

I think it makes sense to be able to circumvent missing @types by using ASSUME_TARGET_TYPE even for objects having only @id. The only question is how to combine it with this reference resolution mechanism, because I don't want to completely disable it when ASSUME_TARGET_TYPE is set to true.

I guess what we can do is register the pending references and after all is deserialized and PendingReferenceRegistry is not empty, check if ASSUME_TARGET_TYPE is true. If so, replace the pending references with objects having only identifier (and being of correct type, of course). If it is false, throw an exception just as we do now. Would this behavior be usable for you?

ChrisGitWorkshop commented 1 month ago

Dear Team,

Many thanks for finding time to look into this issue, appriciate it.

The suggestion you have put forward sounds good to me. Becuase, when i had a quick look at the jsonld doc, it implicitly saying that @type is not a mandatory filed in the object (I am not an expert in this data structure though :) ). Hence this might be helpful if we could implement it (Much better if we have some configuration in place, for instance as you mentioned to make use of ASSUME_TARGET_TYPE property, so that people can make a choice).

Regards, Chris.

ledsoft commented 1 month ago

I created a follow-up ticket for the discussed enhancement - #69.

ledsoft commented 1 month ago

Implemented in 0.15.0.