python rdflib doesn't export #context and #graph when serializing with json-ld - serialization

I have created a Graph() in rdflib 6.2.0 and attempting to export it as JSON-LD. My expectation was that I would end up with a #context containing all the namespace prefixes and a #graph containing all the elements. I'm just simply using:
myGraph.serialize(destination = Path(outputpath), format = "json-ld")
But, I just end up with JSON-LD resembling this kind of structure:
[
{
"#id": "urn:uuid:dccc2ddb-7861-47fc-934c-d2a0901e368e",
"#type": "http://xmlns.com/foaf/0.1/Organization",
},
... (more resources in a flat list)
]
The docs (https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.plugins.serializers.html#rdflib.plugins.serializers.jsonld.JsonLDSerializer) do not really clarify the matter at all, and it is very difficult to find any information on how to export a graph with already existing namespace bindings into a proper JSON-LD with #graph and #context parts.
There exists a Context class in https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.plugins.shared.jsonld.html?highlight=shared.jsonld.context#rdflib.plugins.shared.jsonld.context.Context but without any documentation in the sources, it is very difficult to understand how it should be used. What does the method get_graph() do? Apparently I need to pass a Context instance to the json-ld serializer?
What am I doing wrong?

When it comes to the context, reading the source:
If you set the auto_compact argument to True, the JSON-LD serializer will automatically create a context with all namespace bindings from the graph:
myGraph.serialize(destination = Path(outputpath), format="json-ld", auto_compact=True)
Or alternatively, you can pass the JSON-LD context contents as a dict, and the JSON-LD serializer will internally construct the Context object out of it:
context = {"#vocab": "http://xmlns.com/foaf/0.1/"}
myGraph.serialize(destination = Path(outputpath), format="json-ld", context=context)

Related

How to iterate Apache velocity template variable attributes

As title, is there any way to iterate or display Apache velocity template attributes?
for example, I have following code :
<code>
${ctx.messages.headerMessage}
</code>
And I want to know how many other attributes the variable ${ctx} has
It's only possible to discover and to loop on an object properties (that is, the ones with getters and/or setters) if you can add a new tool to your Velocity context. If you can't, you're rather stuck.
There are several ways to do this, I illustrate below how to do this with commons-beanutils.
First, add Apache commons-beanutils in your class path, and add it to your Velocity context from Java:
import org.apache.commons.beanutils.PropertyUtils;
...
context.put("beans", new PropertyUtils());
...
One remark: if you do not have access to the Java part, but if by chance commons-beanutils is already in the classpath, there is one hakish way of having access to it: #set($beans = $foo.class.forName('org.apache.commons.beanutils.PropertyUtils').newInstance()).
Then, let's say that I have the following object:
class Foo
{
public boolean isSomething() { return true; }
public String getName() { return "Nestor"; }
}
which is present in my context under $foo. Using your newly $beans properties introspector, you can do:
#set ($properties = $beans.getPropertyDescriptors($foo.class))
#foreach ($property in $properties)
$property.name ($property.propertyType) = $property.readMethod.invoke($foo)
#end
This will produce:
bar (boolean) = true
class (class java.lang.Class) = class Foo
name (class java.lang.String) = Robert
(you'll need to filter out the class property, of course)
One last remark, though. Templates are for coding the View layer of an MVC application, and doing such a generic introspection of objects in them is rather inadequate in the view layer. You're far better of moving all this introspection code on the Java side.

Ember - different keys for serialization and deserialization

I have an issue where an property needs to be serialized and deserialized using to different keys.
In the serializer, the property addresses the key trade:
'tradeId': { key: 'trade' },
This works when addressing the deserialization endpoint.
However, for serialization, the endpoint property is called trade-identifier, requiring the serializer reference to be changed to the following:
'tradeId': { key: 'tradeIdentifier' },
Is there any way to define seperate keys for serialization and deserialization in an Ember serializer?
Thanks to #handlebears for pointing me in the right direction here.
Simply adding a serialize method to the governing serializer file allowed me to reassign the data to the appropriate JSON property:
serialize(snapshot, options){
let json = this._super(...arguments);
json.tradeIdentifier = json.trade;
delete json.trade;
return json;
}
});

Mirage serializer drop Ids when include and embed some model

I have a problem with mirage.
I am defining a serializer extending ActiveModelSerializer with serializeIds: 'always', in this case the model is serialized with the relations models ids.
But when i want include some model in the serialized content i use include: ['someModel'], in that case the someModel is included succesfully, but the ids of the rest of relationships are ignored.
How can i include the ids too?
Hm, I believe this is the default behavior. To override this you could call super on the Serializer's serialize method and ensure the ids are added to the payload:
serialize(post, request) {
let json = Serializer.prototype.serialize.apply(this, arguments);
json.post.commentIds = post.commentIds;
return json;
}

How do I create hypermedia links in custom serializer with Spring Data Rest

I have a abstract class and two implementations:
public abstract class Attribute {
// some properties
}
public class CustomAttribute extends Attribute{
private String property1;
}
public class DefaultAttribute extends Attribute{
private String property2;
}
There's another class, which includes these attributes:
public class Step{
private List<Attribute> attributes;
}
Now when Step gets serialized, the self link is missing. I need the self reference, since I want to update the attributes. According to the documentation, jackson needs a little help deciding which class to use. But that does not help, because I need to use both classes. So I build a custom serializer (and registered with a module) for Step and now I wonder how I can construct the link myself. I couldn't find anything in the Spring Data Rest docs regarding this. Since Spring Data Rest adds these links automatically, I think there might be a way to have the protocol/hostname/port information available in the JsonSerializer. How do I get the information in my custom serializer?
Ok, now I use the linkTo() function to get the hostname and port and I manually set the rest of the resource URL in my custom serializer.
final Link attributeLink = linkTo(CustomAttributeRepository.class)
.slash("/api")
.slash("customAttributes")
.slash(attribute.getIdentifier()).withSelfRel();
//#formatter:off
jsonGenerator.writeFieldName("_links");
jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("self");
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("href", attributeLink.getHref());
jsonGenerator.writeEndObject();
jsonGenerator.writeEndObject();
//#formatter:on

Per query JSON serializer in Spring Data Rest

Is there any way to define a JSON serializer per query? I would like to be able to define different JSON output for some queries, something similar to this:
#RepositoryRestResource(collectionResourceRel = "people", path = "person")
public interface PersonJpaRepository extends JpaRepository<Person, Long> {
#JsonSerialize(using = SimplePersonSerializer.class)
List<Person> findAll();
#JsonSerialize(using = FullPersonSerializer.class)
List<Person> findByNameOrderByCreationDateDesc(String name);
}
In this scenario, SimplePersonSerializer should be used to serialize a huge list of results and FullPersonSerializer only a few results.
Without any further information it looks like you want projections. Projections define a subset of an entity's properties. The feature is not mentioned in the official documentation, but in the release notes for Spring Data REST 2.1.
You just need to define an interface that contains the subset of properties:
#Projection(name = "simple", types = Person.class)
interface SimplePerson {
String getFirstName();
String getLastName();
}
You don't have to change your repository. The only thing that changes is the URL you are calling: http://myapp/people?projection=simple.