spring-projects / spring-projects/spring-hateoas

Support custom contextualised deserialisation of HAL embedded values

Open
#725 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.1k
Forks
476
PR merge metrics
No merged PRs in 30d

Description

It would be nice if the HalResourcesDeserializer supported registering a custom, contextual JsonDeserializer for handling the individual values in the HAL _embedded construct.

In the following attempt:

@JsonProperty("_embedded")
@JsonDeserialize(
  using = HalResourcesDeserializer.class,
  contentUsing = MyCustomDeserializer.class,
  contentAs = MyItem.class)
public List<Item> getContent() { return content; }

...the contentAs attribute is honoured, but contentUsing is not. This is because in HalResourcesDeserializer the value deserializer is just determined with:

JsonDeserializer<Object> deser = ctxt.findRootValueDeserializer(contentType);

Would it be desirable to support registering custom deserializers for embedded content?

Use case

In our library Bowman, which makes use of Spring HATEOAS, we create proxies of deserialised model objects so that resources corresponding to objects' HAL links can be transparently retrieved by invoking the objects' accessors.

The easiest way I've found to do this is to register a custom deserializer on model object properties.

It would be good if we could make use of this approach together with HalResourcesDeserializer to support proxying arbitrary _embedded content but this issue prevents this.

Thoughts on an implementation

I'm happy to provide a PR for this functionality if deemed desirable.

  • The content deserializer registered using this annotation seems to be available via JsonDeserializer<?> deser = contentType.getValueHandler();
  • I only require supporting @JsonDeserialize(contentUsing = ...) for my use case, but it may be worth ensuring contentConverter works as well for consistency.
  • The support for these attributes with standard Jackson collection deserialization seems unfortunately spread around BasicDeserializerFactory#createCollectionDeserializer and CollectionDeserializer#createContextual. It may be better to reimplement just the bits we specifically want, or may be better to subclass CollectionDeserializer to leverage this functionality.

Any thoughts on any of this gratefully received.

Thanks

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in HalResourcesDeserializer, especially the content type and value-deserializer lookup using ctxt.findRootValueDeserializer(contentType). Compare that path with Jackson's BasicDeserializerFactory#createCollectionDeserializer and CollectionDeserializer#createContextual to understand how contentUsing is handled. Done means a custom contextual deserializer registered with @JsonDeserialize(contentUsing = ...) is applied to individual HAL _embedded values.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.