openapi-tools / jackson-dataformat-hal Goto Github PK
View Code? Open in Web Editor NEWDataformat extension for Jackson to handle HAL JSON
License: MIT License
Dataformat extension for Jackson to handle HAL JSON
License: MIT License
I'm not sure why the openapi-tools repo was forked from my account. But since the openapi-tools repo should probably be the main repo for this, should I just transfer ownership of my repo?
I think that should remove the "forked from" message, though I'm not quite sure. But it shouldn't be too hard to find a way to do this.
i have a resource which will have different links depending on the server side configuration. i want to be able to get all links into a list of Hallink objects. i dont know the link names at build time, but they do match a pattern.
Thanks for a fantastic tool already. Seems like this is growing in popularity and wouldn't be a big lift to add it to the existing library: https://rwcbook.github.io/hal-forms/
Wondering what your thoughts on that are? Would you be opposed to pull requests adding this feature or do you see it as permanently out-of-scope for this library?
Links to Jackson and HAL specification is broken in README.
Thinking about how we might make CURIE generation simpler for this library rather than have to specify them for all of our resources. Thought I'd throw the following idea out there for discussion....
1: Support optional CurieProvider interface to be provided when instantiating HALMapper.
2: CurieProvider interface used in serializer. When a link of the form "foo:bar" detected (contains colon) then CURIE automatically generated by CurieProvider implementation.
This would allow CurieProvider class to turn these three links "foo:bar", "foo:bar2" and "flibble:flip" links into e.g.
"_links": {
"curies": [
{
"name": "foo",
"href": "http://my.api.com/docs/rels/foo-{rel},
"templated": true
},
{
"name": "flibble",
"href": "http://my.api.com/docs/rels/flibble-{rel},
"templated": true
}
]
}
Note that I never had to specify the curies link in my resource class, it just showed up during serialization. It was summoned into existence upon detection of links containing a colon, the serializer then delegated to a CurieProvider implementation.
Thought I'd share the idea in case there is merit in it. Happy to scratch a PR if there is. Feel free to close if you feel like this is a dead-end however.
Currently, whenever you create a HALLink
from a String
with the Builder, the templated
field is set.
I don't have templated links but they are only relative paths and therefore not valid URIs. However, I also don't want to always send the templated
field. What would be the best way to achieve this?
There are many cases in which one want to cache the API results, which is currently not as easy as it could be. To work around the missing Serializable
implementation I had to write custom serialization classes for HALLink
.
Since caching of API results is a very common and implementation is really easy, I recommend making HALLink
implement Serializable
.
Here is an example how to add HAL resource support to an existing application where you already have a large set of domain entities.
The trick is to use a @JsonUnwrapped
around the existing entity. You have a large set of existing classes that you don't want to / or cannot modify. Then, with ResourceSupport
and ResourceCollectionSupport
it becomes easy to add the findAll()
, findOne(ID id)
features.
@Resource
public abstract class ResourceSupport<T> {
@Link
public final HALLink self;
@JsonUnwrapped
public final T domain;
public ResourceSupport(Link self, T domain) {
this.self = self;
this.domain = domain;
}
}
@Resource
public abstract class ResourceCollectionSupport<T> {
@Link
public final HALLink self;
@EmbeddedResource
public final Collection<ResourceSupport<T>> content;
public ResourceCollectionSupport(Link self, Collection<ResourceSupport<T>> domain) {
this.self = self;
this.content = domain;
}
}
public static class Foo {
public UUID id = UUID.randomUUID();
public String foo = "bar";
}
public static class Bar {
public BigInteger bar = BigInteger.ZERO;
}
public static class FooResourceSupport extends ResourceSupport<Foo> {
public FooResourceSupport(Foo foo) {
super(new Link.Builder("/foo/" + foo.id.toString()).build(), foo);
}
}
public static class BarResourceSupport extends ResourceSupport<Bar> {
public BarResourceSupport(Bar bar) {
super(new Link.Builder("/bar/" + bar.bar).build(), bar);
}
@EmbeddedResource(value = "thisIsTheDimensionsObject")
public FooResourceSupport dimensions;
}
public static class FooCollectionResource extends ResourceCollectionSupport<Foo> {
public FooCollectionResource(Collection<Foo> domain) {
super(new Link.Builder("/foo").build(), domain.stream().map(FooResourceSupport::new).collect(Collectors.toList()));
}
}
In my reading of the HAL-draft it is perfectly valid to use CURIE syntax for the link relation type of embedded properties. To serialize the following "hypertext cache pattern" JSON:
{
"_links": {
"curies": [
{
"href": "http://example.org/relations/foo/{rel}",
"templated": true,
"name": "foo"
}
],
"foo:bars": [
{
"href": "http://example.org/bars/248875bd-c7e1-357f-8473-450cc49a8308"
}
],
"self": {
"href": "http://example.org/bars"
}
},
"_embedded": {
"foo:bars": [
{
"_links": {
"self": {
"href": "http://example.org/bars/248875bd-c7e1-357f-8473-450cc49a8308"
}
},
"uuid": "248875bd-c7e1-357f-8473-450cc49a8308"
}
]
},
"count": 1
}
Currently someone needs to provide a fixed CURIE value for the embedded resource:
@Resource
@Curie(prefix = "foo", href = "http://example.org/relations/foo/{rel}"
public class Bars {
private HALLink self;
private List<Bar> barResources;
private List<HALLink> barLinks;
private Integer count;
public (HALLink self, List<Bar> bars) {
this.self = Objects.requireNonNull(self);
this.barResources = Objects.requireNonNull(bars);
this.barLinks = bars.stream().map(bar -> bar.getSelf()).collect(Collectors.toList());
this.count = Integer.valueOf(bars.size());
}
@Link
public HALLink getSelf() {
return this.self;
}
@EmbeddedResource(value = "foo:bars")
public List<Bar> getBarResources() {
return this.barResources;
}
@Link(curie = "foo", value = "bars")
public List<HALLink> getBarLinks() {
return this.barLinks;
}
public Integer getCount() {
return this.count;
}
}
It would be nice if someone could use @EmbeddedResource(curie = "foo", value = "bars")
(as with @Link
).
It seems something is wrong with the GitHub Actions. The build does not seem to start for any of the pull requests. It seems that something needs to be changed in the protected branch settings of the repository:
https://github.community/t/expected-waiting-for-status-to-be-reported/16727
Hope you can fix the settings this since it's blocking any PRs from being merged (by me at least).
Edit: @langecode looks like you can still merge the PRs. So it's less of a problem. Might still want to look into this though.
Annotating a class with @Resource
breaks @JsonView
behavior. Would be very nice, if both work together. Not only for state properties, but also for links and embedded resources.
I've upgraded to Spring Boot 2.2.0 which uses Jackson 2.10.0 but when I do so I get an error when the HAL resources are serialized:
Caused by: java.lang.IllegalStateException: null
at com.fasterxml.jackson.databind.ser.std.NumberSerializer$BigDecimalAsStringSerializer.valueToString(NumberSerializer.java:161)
at com.fasterxml.jackson.databind.ser.std.NumberSerializer$BigDecimalAsStringSerializer.isEmpty(NumberSerializer.java:132)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:711)
at io.openapitools.jackson.dataformat.hal.ser.HALBeanSerializer$FilteredProperties.serialize(HALBeanSerializer.java:191)
I suspect that there's some change in Jackson 2.10 which makes jackson-dataformat-hal
incompatible with this version.
Problem:
We are using polymorphic classes in our API.
Unfortunately the HAL structure don't get created when its come to serialization.
We tried every possible combination of the @JsonTypeInfo annotation and nothing "really" changed.
Maybe you have an Idea or a Solution.
Currently we can't use your Library as it proposed to.
Deserialization is not effected so far.
Related Pull Request: #24
Pipeline is failing as expected, because I added all possible cases for the polymorphic classes
Seems PR #37 resulted in build failures this must be fixed.
Documentation seems somewhat outdated.
@Embedded
. Should be updated to @EmbeddedResource
. This was very confusing when i discoverd this project.HALLink
fields only. Should show that e.g. Collection<HALLink>
is supported as well. Only got this by looking into the code.A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.