#144 - Added sample for URI customization in Spring Data REST.
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
<module>projections</module>
|
||||
<module>security</module>
|
||||
<module>headers</module>
|
||||
<module>uri-customization</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
||||
34
rest/uri-customization/pom.xml
Normal file
34
rest/uri-customization/pom.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-rest-uri-customizations</artifactId>
|
||||
|
||||
<name>Spring Data REST - URI Customizations Example</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-rest-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<spring-data-releasetrain.version>Hopper-BUILD-SNAPSHOT</spring-data-releasetrain.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-keyvalue</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
25
rest/uri-customization/readme.adoc
Normal file
25
rest/uri-customization/readme.adoc
Normal file
@@ -0,0 +1,25 @@
|
||||
= Spring Data REST URI customizations
|
||||
|
||||
This example shows how to customize which property of the domain type shall be used to create URIs for item resources. This is achieved by implementing an `EntityLookup` and declaring it as Spring bean:
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
|
||||
public class UserEntityLookup extends EntityLookupSupport<User> {
|
||||
|
||||
private final @NonNull UserRepository repository;
|
||||
|
||||
@Override
|
||||
public Serializable getResourceIdentifier(User entity) {
|
||||
return entity.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lookupEntity(Serializable id) {
|
||||
return repository.findByUsername(id.toString());
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
As you can see the customization consists of two methods that need to be symmetric in their functionality. `getResourceIdentifier(…)` returns the property that's supposed to be used in the URI while `lookupEntity(…)` uses the value to lookup an entity via a query method for exactly that property.
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.rest.uris;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.data.map.repository.config.EnableMapRepositories;
|
||||
|
||||
/**
|
||||
* Applicatoin class to bootstrap the app.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableMapRepositories
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Autowired UserRepository repository;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
repository.save(new User("olivergierke"));
|
||||
repository.save(new User("starbucksman"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.rest.uris;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
/**
|
||||
* A {@link User}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Value
|
||||
public class User {
|
||||
|
||||
private final @Id UUID id = UUID.randomUUID();
|
||||
private final String username;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.rest.uris;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.EntityLookupSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Custom {@link EntityLookup} to replace the usage of the database identifier in item resource URIs with the username
|
||||
* property of the {@link User}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
|
||||
public class UserEntityLookup extends EntityLookupSupport<User> {
|
||||
|
||||
private final @NonNull UserRepository repository;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.support.EntityLookup#getId(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Serializable getResourceIdentifier(User entity) {
|
||||
return entity.getUsername();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.support.EntityLookup#lookupEntity(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public Object lookupEntity(Serializable id) {
|
||||
return repository.findByUsername(id.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.rest.uris;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Repository to manage {@link User} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface UserRepository extends CrudRepository<User, UUID> {
|
||||
|
||||
/**
|
||||
* Looks up a unique {@link User} by its user name.
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
Optional<User> findByUsername(String username);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.rest.uris;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Integration tests to make sure the URI customizations are applied.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @soundtrack Clueso - Gewinner (Stadtrandlichter Live)
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
public class WebIntegrationTests {
|
||||
|
||||
@Autowired WebApplicationContext context;
|
||||
@Autowired UserRepository users;
|
||||
|
||||
MockMvc mvc;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
this.mvc = MockMvcBuilders.webAppContextSetup(context).//
|
||||
build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void identifiesResourcesUsingUsername() throws Exception {
|
||||
|
||||
mvc.perform(get("/users/olivergierke")).//
|
||||
andExpect(status().isOk()).//
|
||||
andExpect(jsonPath("$._links.self.href", endsWith("olivergierke")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.restdocs.outputDir=target/generated-snippets
|
||||
Reference in New Issue
Block a user