spring-projects / spring-projects/spring-hateoas

org.springframework.hateoas.Resources should serialize content as arrays, not lists.

Open
#650 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Jackson is better at serializing arrays than lists since there is no type erasure. When a GET method returns a Resources object, I see something like:

{ 
    "_embedded": {
        "hashMapList": [
            {
                "fld1": "a",
                "_links": {
                    "self": {
                        "href": "http://..."
                    }
                }
            }
        ]
    }
}

The "hashMapList" sticks out. I would rather see this:

{
    "content": [
        {
            "fld1": "a",
            "_links": {
                "self": {
                    "href": "http://..."
                }
            }
        }
    ]
}

In retrospect, Resources.getContents() should have probably returned T[] instead of Collection<T>.

My workaround was to create a class called ArrayResources that extended Resources with the following code:

	@Override
	@JsonIgnore
	public Collection<T> getContent() {
		return super.getContent();
	}
	
	@XmlAnyElement
	@XmlElementWrapper
	@JsonProperty("content")	
	@SuppressWarnings("unchecked")
	public T[] getContentArray() {
		Collection<T> content = getContent();
		return content == null ? null :
			(T[]) content.toArray();
	}

I also had to write ArrayPagedResources that duplicated most of the code in PagedResources. Finally I provided static initializers that I use in my Controller classes right before returning.

ArrayResources.from(Resources)
PagedArrayResources.from(PagedResources)

Not the most elegant solution, but it got me what I want. Ideally, I would like to see the code for Resources changed as shown above. If maintaining backward compatibility is vital, perhaps a mixin similar to ResourcesMixin could provide this as an optional feature. (I tried to do this myself, but I never got it to work.) If a mixin could be developed perhaps an attribute would be appropriate, e.g., @EnableResourcesArraySerialization.

If there is an easier way to accomplish this that I am missing, I welcome suggestions. Kudos for all your great work.

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 by reading Resources, PagedResources, and ResourcesMixin, then reproduce the reported Jackson serialization of Resources content. Decide how array-shaped serialization can be provided without breaking the existing API or requiring duplicated resource classes. Done means the desired JSON is produced and the compatibility behavior is covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.