DATAREST-317 - Support for excerpt projections.

This commit adds a mechanism to define excerpt projections to be rendered for exposed repositories. The main user facing mechanism is the addition of the excerptProjection attribute to @RepositoryRestResource. This attribute takes a type which has to be a projection interface (see DATAREST-221 for more information about the general mechanism).

If such a excerpt projection is in place, it will be used by default when rendering instances of the domain type in _embedded clauses or if it is related to.

class Person {

  String name;
  int age;
  Person father;
  Person mother;
  Set<Person> siblings:
}

interface PersonExcerpt {
  String getName();
}

If PersonExcerpt is now configured as excerpt projection for Person the collection resource for people will return:

{ _embedded : {
    people : [{
      name : "Some name",
      _embedded : {
        mother : { name : "…" },
        father : { name : "…" },
        siblings : [ … ]
      },
      _links : { self : { href : "…" }}
    }, … ]
  }
}

Here you can see how the age property is omitted when rendering a person in a collection. Also each person contains the excerpt projections of related resources and the links to them omitted. If you now follow the link to the item resource, you'll something like this:

{ name : "Some name",
  age : 34,
  _embedded : {
    mother : { name : "…" },
    father : { name : "…" },
    siblings : [ … ]
  },
  _links : {
    self : { href : "…" },
    mother : { href : "…" },
    father : { href : "…" },
    siblings : { href : "…" }
  }
}

Note, that age appears, as the representation is now rendered entirely. We also see the excerpts of related resource but also the links pointing to them in case you want to manage them.
This commit is contained in:
Oliver Gierke
2014-06-10 16:57:46 +02:00
parent a1c54b2475
commit 3969c34940
37 changed files with 904 additions and 120 deletions

View File

@@ -72,4 +72,15 @@ public @interface RepositoryRestResource {
* @return
*/
Description itemResourceDescription() default @Description(value = "");
/**
* Configures the projection type to be used when embedding item resources into collections and related resources.
* Defaults to {@link None}, which indicates full rendering of the items in a collection resource and no inlining of
* related resources.
*
* @return
*/
Class<?> excerptProjection() default None.class;
static class None {}
}

View File

@@ -35,4 +35,12 @@ public interface CollectionResourceMapping extends ResourceMapping {
* @return
*/
ResourceDescription getItemResourceDescription();
/**
* Returns the projection type to be used when embedding item resources into collections and related resources. If
* {@literal null} is returned this will mean full rendering for collections and no rendering for related resources.
*
* @return
*/
Class<?> getExcerptProjection();
}

View File

@@ -169,6 +169,15 @@ class RepositoryAwareResourceInformation implements ResourceMetadata {
return mapping.getItemResourceDescription();
}
/*
* (non-Javadoc)
* @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getExcerptProjection()
*/
@Override
public Class<?> getExcerptProjection() {
return mapping.getExcerptProjection();
}
/*
* (non-Javadoc)
* @see org.springframework.data.rest.core.mapping.ResourceMetadata#getSearchResourceMappings()

View File

@@ -204,4 +204,20 @@ class RepositoryCollectionResourceMapping implements CollectionResourceMapping {
return fallback;
}
/*
* (non-Javadoc)
* @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getExcerptProjection()
*/
@Override
public Class<?> getExcerptProjection() {
if (repositoryAnnotation == null) {
return null;
}
Class<?> excerptProjection = repositoryAnnotation.excerptProjection();
return excerptProjection.equals(RepositoryRestResource.None.class) ? null : excerptProjection;
}
}

View File

@@ -150,6 +150,15 @@ class TypeBasedCollectionResourceMapping implements CollectionResourceMapping {
return fallback;
}
/*
* (non-Javadoc)
* @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getExcerptProjection()
*/
@Override
public Class<?> getExcerptProjection() {
return null;
}
/**
* Returns the default path to be used if the path is not configured manually.
*