Skip to content

Commit ae7ee11

Browse files
committed
#482 - Add support for Collection+JSON media type
Introduce support for media type application/vnd.collection+json. Collection+JSON doesn't allow metadata at the top, so paging data can't be covered, however, everything else fits.
1 parent f7a1d96 commit ae7ee11

30 files changed

+1796
-36
lines changed

pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@
3131
</roles>
3232
<timezone>+1</timezone>
3333
</developer>
34+
<developer>
35+
<id>gturnquist</id>
36+
<name>Greg Turnquist</name>
37+
<email>gturnquist(at)pivotal.io</email>
38+
<organization>Pivotal, Inc.</organization>
39+
<roles>
40+
<role>Contributor</role>
41+
</roles>
42+
<timezone>-6</timezone>
43+
</developer>
3444
</developers>
3545

3646
<licenses>

readme.adoc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
= Spring HATEOAS
2+
3+
This project provides some APIs to ease creating REST representations that follow the http://en.wikipedia.org/wiki/HATEOAS[HATEOAS] principle when working with Spring and especially Spring MVC. The core problem it tries to address is link creation and representation assembly.
4+
5+
== Working with Spring HATEOAS
6+
7+
Since all commits are headlined with its github issue, git will treat it as a comment. To get around this, apply the following configuration to your clone:
8+
9+
[source]
10+
----
11+
git config core.commentchar "/"
12+
----
13+
14+
== Resources
15+
16+
* Reference documentation - http://docs.spring.io/spring-hateoas/docs/current/reference/html/[html], http://docs.spring.io/spring-hateoas/docs/current/reference/pdf/spring-hateoas-reference.pdf[pdf]
17+
* http://docs.spring.io/spring-hateoas/docs/current-SNAPSHOT/api/[JavaDoc]
18+
* https://spring.io/guides/gs/rest-hateoas/[Getting started guide]

readme.md

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/main/java/org/springframework/hateoas/MediaTypes.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*
2323
* @author Oliver Gierke
2424
* @author Przemek Nowak
25+
* @author Greg Turnquist
2526
*/
2627
public class MediaTypes {
2728

@@ -34,4 +35,14 @@ public class MediaTypes {
3435
* Public constant media type for {@code application/hal+json}.
3536
*/
3637
public static final MediaType HAL_JSON = MediaType.valueOf(HAL_JSON_VALUE);
38+
39+
/**
40+
* A String equivalent of {@link MediaTypes#COLLECTION_JSON}.
41+
*/
42+
public static final String COLLECTION_JSON_VALUE = "application/vnd.collection+json";
43+
44+
/**
45+
* Public constant media type for {@code application/vnd.collection+json}.
46+
*/
47+
public static final MediaType COLLECTION_JSON = MediaType.valueOf(COLLECTION_JSON_VALUE);
3748
}

src/main/java/org/springframework/hateoas/Resource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* A simple {@link Resource} wrapping a domain object and adding links to it.
3030
*
3131
* @author Oliver Gierke
32+
* @author Greg Turnquist
3233
*/
3334
@XmlRootElement
3435
public class Resource<T> extends ResourceSupport {
@@ -38,7 +39,7 @@ public class Resource<T> extends ResourceSupport {
3839
/**
3940
* Creates an empty {@link Resource}.
4041
*/
41-
Resource() {
42+
protected Resource() {
4243
this.content = null;
4344
}
4445

src/main/java/org/springframework/hateoas/alps/Alps.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
*/
1616
package org.springframework.hateoas.alps;
1717

18+
import java.util.List;
19+
1820
import lombok.Builder;
1921
import lombok.Value;
2022

21-
import java.util.List;
22-
2323
import org.springframework.hateoas.alps.Descriptor.DescriptorBuilder;
2424
import org.springframework.hateoas.alps.Doc.DocBuilder;
2525
import org.springframework.hateoas.alps.Ext.ExtBuilder;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.hateoas.collectionjson;
17+
18+
import java.util.List;
19+
20+
import lombok.Builder;
21+
import lombok.Data;
22+
import lombok.Singular;
23+
import lombok.Value;
24+
25+
import org.springframework.hateoas.Link;
26+
27+
import com.fasterxml.jackson.annotation.JsonCreator;
28+
import com.fasterxml.jackson.annotation.JsonProperty;
29+
30+
/**
31+
* Representation of a Collection+JSON.
32+
*
33+
* @author Greg Turnquist
34+
*/
35+
@Data
36+
@Value
37+
@Builder(builderMethodName = "collectionJson")
38+
public class CollectionJson<T> {
39+
40+
private String version;
41+
private String href;
42+
private List<Link> links;
43+
@Singular private List<Item<T>> items;
44+
45+
@JsonCreator
46+
public CollectionJson(@JsonProperty("version") String version, @JsonProperty("href") String href,
47+
@JsonProperty("links") List<Link> links, @JsonProperty("items") List<Item<T>> items) {
48+
this.version = version;
49+
this.href = href;
50+
this.links = links;
51+
this.items = items;
52+
}
53+
54+
public static Item.ItemBuilder item() {
55+
return Item.builder();
56+
}
57+
58+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.hateoas.collectionjson;
17+
18+
import org.springframework.hateoas.LinkDiscoverer;
19+
import org.springframework.hateoas.MediaTypes;
20+
import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
21+
22+
/**
23+
* {@link LinkDiscoverer} implementation based on JSON Collection link structure.
24+
*
25+
* @author Greg Turnquist
26+
*/
27+
public class CollectionJsonLinkDiscoverer extends JsonPathLinkDiscoverer {
28+
29+
public CollectionJsonLinkDiscoverer() {
30+
super("$.collection..links..['%s']..href", MediaTypes.COLLECTION_JSON);
31+
}
32+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.hateoas.collectionjson;
17+
18+
import java.util.List;
19+
20+
import lombok.Data;
21+
import lombok.Value;
22+
23+
import org.springframework.hateoas.Link;
24+
25+
import com.fasterxml.jackson.annotation.JsonCreator;
26+
import com.fasterxml.jackson.annotation.JsonProperty;
27+
28+
/**
29+
* Wrapper to embed a JSON Collection inside a top-level "collection" attribute.
30+
*
31+
* @author Greg Turnquist
32+
*/
33+
@Data
34+
@Value
35+
public class CollectionJsonWrapper<T> {
36+
37+
private final CollectionJson<T> collection;
38+
39+
public CollectionJsonWrapper(CollectionJson<T> collection) {
40+
this.collection = collection;
41+
}
42+
43+
@JsonCreator
44+
public CollectionJsonWrapper(@JsonProperty("version") String version, @JsonProperty("href") String href,
45+
@JsonProperty("links") List<Link> links, @JsonProperty("items") List<Item<T>> items) {
46+
this.collection = new CollectionJson(version, href, links, items);
47+
}
48+
49+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.hateoas.collectionjson;
17+
18+
import java.util.List;
19+
20+
import lombok.Builder;
21+
import lombok.Data;
22+
import lombok.Singular;
23+
import lombok.Value;
24+
25+
import org.springframework.hateoas.Link;
26+
27+
import com.fasterxml.jackson.annotation.JsonCreator;
28+
import com.fasterxml.jackson.annotation.JsonProperty;
29+
30+
/**
31+
* Representation of an item in a JSON Collection.
32+
*
33+
* @author Greg Turnquist
34+
*/
35+
@Data
36+
@Value
37+
@Builder
38+
public class Item<T> {
39+
40+
private final String href;
41+
@Singular("data") private final List<T> data;
42+
private final List<Link> links;
43+
44+
@JsonCreator
45+
public Item(@JsonProperty("href") String href, @JsonProperty("data") List<T> data,
46+
@JsonProperty("links") List<Link> links) {
47+
48+
this.href = href;
49+
this.data = data;
50+
this.links = links;
51+
}
52+
53+
}

0 commit comments

Comments
 (0)