DATAREST-762 - Collection resource's base link now forwards parameters.

We now use the current request's URI as base link for all links created for a collection resource. This especially has effect in the creation of pagination links as we now carry potentially applied critierias (induced by our Querydsl based filtering support) forward to the navigation links generated.
This commit is contained in:
Oliver Drotbohm
2020-03-27 11:54:18 +01:00
parent 4c17d54e9a
commit db5995eee0
3 changed files with 54 additions and 4 deletions

View File

@@ -19,15 +19,27 @@ import java.math.BigInteger;
import java.util.List;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
/**
* @author Oliver Gierke
*/
public interface UserRepository extends CrudRepository<User, BigInteger>, QuerydslPredicateExecutor<User> {
public interface UserRepository extends PagingAndSortingRepository<User, BigInteger>, QuerydslPredicateExecutor<User>,
QuerydslBinderCustomizer<QUser> {
List<User> findByFirstname(String firstname);
List<User> findByColleaguesContains(@Param("colleagues") User colleague);
/*
* (non-Javadoc)
* @see org.springframework.data.querydsl.binding.QuerydslBinderCustomizer#customize(org.springframework.data.querydsl.binding.QuerydslBindings, com.querydsl.core.types.EntityPath)
*/
@Override
default void customize(QuerydslBindings bindings, QUser root) {
bindings.bind(root.firstname).first((path, value) -> path.containsIgnoreCase(value));
}
}

View File

@@ -22,9 +22,12 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.math.BigDecimal;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.assertj.core.api.Condition;
import org.junit.After;
@@ -38,10 +41,14 @@ import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkRelation;
import org.springframework.hateoas.TemplateVariable;
import org.springframework.hateoas.TemplateVariable.VariableType;
import org.springframework.hateoas.client.LinkDiscoverer;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
@@ -400,4 +407,36 @@ public class MongoWebTests extends CommonWebTests {
mvc.perform(get(mapLink.expand().getHref()).accept(TEXT_URI_LIST)) //
.andExpect(status().isUnsupportedMediaType());
}
@Test // DATAREST-762
public void paginatedLinksContainQuerydslPropertyReferences() throws Exception {
Map<String, Object> parameters = new HashMap<>();
parameters.put("page", "0");
parameters.put("size", "1");
parameters.put("firstname", "a");
Link receipts = client.discoverUnique("users");
URI firstnameLikeA = receipts.getTemplate() //
.with(new TemplateVariable("firstname", VariableType.REQUEST_PARAM)) //
.expand(parameters);
MockHttpServletResponse response = mvc//
.perform(get(firstnameLikeA)) //
.andReturn() //
.getResponse();
LinkDiscoverer discoverer = client.getDiscoverer(response);
String content = response.getContentAsString();
Stream.of(IanaLinkRelations.FIRST, IanaLinkRelations.NEXT, IanaLinkRelations.LAST) //
.forEach(it -> {
Link firstLink = discoverer.findRequiredLinkWithRel(it, content);
UriComponents components = UriComponentsBuilder.fromUriString(firstLink.getHref()).build();
assertThat(components.getQueryParams().containsKey("firstname"));
});
}
}

View File

@@ -203,8 +203,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
: invoker.invokeFindAll(sort);
ResourceMetadata metadata = resourceInformation.getResourceMetadata();
Optional<Link> baseLink = Optional.of(entityLinks.linkToPagedResource(resourceInformation.getDomainType(),
pageable.isDefault() ? null : pageable.getPageable()));
Optional<Link> baseLink = Optional.of(getDefaultSelfLink());
return toCollectionModel(results, assembler, metadata.getDomainType(), baseLink)
.add(getCollectionResourceLinks(resourceInformation, pageable));