diff --git a/docs/src/docs/asciidoc/documenting-your-api.adoc b/docs/src/docs/asciidoc/documenting-your-api.adoc
index 9550aaf5..2dee3919 100644
--- a/docs/src/docs/asciidoc/documenting-your-api.adoc
+++ b/docs/src/docs/asciidoc/documenting-your-api.adoc
@@ -38,6 +38,10 @@ include::{examples-dir}/com/example/restassured/Hypermedia.java[tag=links]
The result is a snippet named `links.adoc` that contains a table describing the resource's
links.
+TIP: If a link in the response has a `title`, the description can be omitted from its
+descriptor and the `title` will be used. If you omit the description and the link does
+not have a `title` a failure will occur.
+
When documenting links, the test will fail if an undocumented link is found in the
response. Similarly, the test will also fail if a documented link is not found in the
response and the link has not been marked as optional.
diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java
index ad12497a..71a2d8dc 100644
--- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java
+++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java
@@ -51,7 +51,9 @@ class AtomLinkExtractor extends AbstractJsonLinkExtractor {
Object hrefObject = linkMap.get("href");
Object relObject = linkMap.get("rel");
if (relObject instanceof String && hrefObject instanceof String) {
- return new Link((String) relObject, (String) hrefObject);
+ Object titleObject = linkMap.get("title");
+ return new Link((String) relObject, (String) hrefObject,
+ titleObject instanceof String ? (String) titleObject : null);
}
return null;
}
diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java
index eb55843a..866a8322 100644
--- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java
+++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java
@@ -67,9 +67,12 @@ class HalLinkExtractor extends AbstractJsonLinkExtractor {
private static Link maybeCreateLink(String rel, Object possibleLinkObject) {
if (possibleLinkObject instanceof Map) {
- Object hrefObject = ((Map, ?>) possibleLinkObject).get("href");
+ Map, ?> possibleLinkMap = (Map, ?>) possibleLinkObject;
+ Object hrefObject = possibleLinkMap.get("href");
if (hrefObject instanceof String) {
- return new Link(rel, (String) hrefObject);
+ Object titleObject = possibleLinkMap.get("title");
+ return new Link(rel, (String) hrefObject,
+ titleObject instanceof String ? (String) titleObject : null);
}
}
return null;
diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java
index c2f11b75..f5493128 100644
--- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java
+++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java
@@ -53,6 +53,10 @@ public abstract class HypermediaDocumentation {
* If you do not want to document a link, a link descriptor can be marked as
* {@link LinkDescriptor#ignored}. This will prevent it from appearing in the
* generated snippet while avoiding the failure described above.
+ *
+ * If a descriptor does not have a {@link LinkDescriptor#description(Object)
+ * description}, the {@link Link#getTitle() title} of the link will be used. If the
+ * link does not have a title a failure will occur.
*
* @param descriptors the descriptions of the response's links
* @return the snippet that will document the links
diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java
index 112886f0..01d5165c 100644
--- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java
+++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java
@@ -29,6 +29,8 @@ public class Link {
private final String href;
+ private final String title;
+
/**
* Creates a new {@code Link} with the given {@code rel} and {@code href}.
*
@@ -36,8 +38,21 @@ public class Link {
* @param href The link's href
*/
public Link(String rel, String href) {
+ this(rel, href, null);
+ }
+
+ /**
+ * Creates a new {@code Link} with the given {@code rel}, {@code href}, and
+ * {@code title}.
+ *
+ * @param rel The link's rel
+ * @param href The link's href
+ * @param title The link's title
+ */
+ public Link(String rel, String href, String title) {
this.rel = rel;
this.href = href;
+ this.title = title;
}
/**
@@ -56,12 +71,21 @@ public class Link {
return this.href;
}
+ /**
+ * Returns the link's {@code title}, or {@code null} if it does not have a title.
+ * @return the link's {@code title} or {@code null}
+ */
+ public String getTitle() {
+ return this.title;
+ }
+
@Override
public int hashCode() {
- int prime = 31;
+ final int prime = 31;
int result = 1;
result = prime * result + this.href.hashCode();
result = prime * result + this.rel.hashCode();
+ result = prime * result + ((this.title == null) ? 0 : this.title.hashCode());
return result;
}
@@ -83,13 +107,21 @@ public class Link {
if (!this.rel.equals(other.rel)) {
return false;
}
+ if (this.title == null) {
+ if (other.title != null) {
+ return false;
+ }
+ }
+ else if (!this.title.equals(other.title)) {
+ return false;
+ }
return true;
}
@Override
public String toString() {
return new ToStringCreator(this).append("rel", this.rel).append("href", this.href)
- .toString();
+ .append("title", this.title).toString();
}
}
diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java
index 7c684ba9..528b444a 100644
--- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java
+++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java
@@ -77,12 +77,6 @@ public class LinksSnippet extends TemplatedSnippet {
this.linkExtractor = linkExtractor;
for (LinkDescriptor descriptor : descriptors) {
Assert.notNull(descriptor.getRel(), "Link descriptors must have a rel");
- if (!descriptor.isIgnored()) {
- Assert.notNull(descriptor.getDescription(),
- "The descriptor for link '" + descriptor.getRel()
- + "' must either have a description or be" + " marked as "
- + "ignored");
- }
this.descriptorsByRel.put(descriptor.getRel(), descriptor);
}
}
@@ -90,14 +84,16 @@ public class LinksSnippet extends TemplatedSnippet {
@Override
protected Map createModel(Operation operation) {
OperationResponse response = operation.getResponse();
+ Map> links;
try {
- validate(this.linkExtractor.extractLinks(response));
+ links = this.linkExtractor.extractLinks(response);
+ validate(links);
}
catch (IOException ex) {
throw new ModelCreationException(ex);
}
Map model = new HashMap<>();
- model.put("links", createLinksModel());
+ model.put("links", createLinksModel(links));
return model;
}
@@ -135,17 +131,48 @@ public class LinksSnippet extends TemplatedSnippet {
}
}
- private List