Reputation: 781
I'm using Spring Data REST to expose my JPA repositories as Web Services.
I'm testing each of these Web Services using RestTemplate. I want those tests to be integration tests... meaning that I'm executing each test while my application is running. I don't want to mock anything.
Now what I want to know is how to configure Spring Data REST to return the newly created entity as part of the body when sending an HTTP POST.
I've tried to set the appropriate flags in configuration class RepositoryRestMvcConfiguration, but it doesn't seem to be working.
Here's my configuration class :
@Configuration
public class RepositoryRestMvcConfiguration extends org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration {
@Override
public RepositoryRestConfiguration config() {
RepositoryRestConfiguration config = super.config();
config.setBasePath("/sdr-api");
config.setReturnBodyOnCreate(Boolean.TRUE);
config.setReturnBodyOnUpdate(Boolean.TRUE);
config.exposeIdsFor(Project.class);
config.setDefaultMediaType(MediaType.APPLICATION_JSON);
return config;
}
}
Here's an example of a test I wanna be able to perform :
@Test
@SqlGroup({ @Sql(scripts = "/clear-data.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)) })
public void create() {
final String PROJECT_NAME = "MY_PROJECT";
Project project = new Project();
project.setName(PROJECT_NAME);
ResponseEntity<Project> response = restTemplate().postForEntity(getBaseUrl() + "projects", project, Project.class);
assertThat(response.getStatusCode(), equalTo(HttpStatus.CREATED));
Project projectCreated = response.getBody();
assertThat(projectCreated.getId(), notNullValue());
assertThat(projectCreated.getCreatedBy(), notNullValue());
assertThat(projectCreated.getCreatedDate(), notNullValue());
assertThat(projectCreated.getLastModifiedBy(), notNullValue());
assertThat(projectCreated.getLastModifiedDate(), notNullValue());
assertThat(projectCreated.getName(), equalTo(PROJECT_NAME));
}
This test is failing on the following statement because the ID is null, as well as all the other properties...
assertThat(projectCreated.getId(), notNullValue());
Even when I try to call the WS using curl, it doesn't give the result I expect...
curl -i -X POST -H "Content-Type:application/json" -d '{ "name" : "MY_PROJECT" }' http://localhost:8081/myproject/sdr-api/projects
It should return the newly created entity and it should return the result as application/json and NOT application/hal+json as specified in my configuration class...
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization
Access-Control-Allow-Credentials: true
ETag: "0"
Last-Modified: Tue, 10 Nov 2015 19:59:12 GMT
Location: http://localhost:8081/myproject/sdr-api/projects/4
Content-Type: application/hal+json
Transfer-Encoding: chunked
Date: Tue, 10 Nov 2015 19:59:12 GMT
{
"_links" : {
"self" : {
"href" : "http://localhost:8081/myproject/sdr-api/projects/4"
},
"project" : {
"href" : "http://localhost:8081/myproject/sdr-api/projects/4{?projection}",
"templated" : true
}
}
}
Any idea on what the problem may be?
I've tried many things over the last few hours... with Spring 2.4.0.RELEASE, I've tried using the RepositoryRestConfigurerAdapter
as suggested by
@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class SpringDataRestConfiguration extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/sdr-api");
config.setReturnBodyOnCreate(Boolean.TRUE);
config.setReturnBodyOnUpdate(Boolean.TRUE);
config.exposeIdsFor(Project.class);
config.useHalAsDefaultJsonMediaType(false);
config.setDefaultMediaType(MediaType.APPLICATION_JSON);
}
}
But I'm still getting the same result... the code seems to be executed though as my SDR API is available under /sdr-api.
So I've decided to downgrade the version of Spring Data Rest to 2.3.2.RELEASE. I've modified my configuration class this way :
@Configuration
public class MySDRConfiguration extends RepositoryRestMvcConfiguration {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/sdr-api");
config.setReturnBodyOnCreate(Boolean.TRUE);
config.setReturnBodyOnUpdate(Boolean.TRUE);
config.exposeIdsFor(Project.class);
config.useHalAsDefaultJsonMediaType(false);
config.setDefaultMediaType(MediaType.APPLICATION_JSON);
}
}
And this time, it's working! The result I get is what I was expecting :
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization
Access-Control-Allow-Credentials: true
ETag: "0"
Last-Modified: Thu, 12 Nov 2015 20:55:32 GMT
Location: http://localhost:8081/myproject/sdr-api/projects/3
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 12 Nov 2015 20:55:32 GMT
{
"id" : 3,
"createdBy" : "anonymousUser",
"createdDate" : "2015-11-12T20:55:32.368Z",
"lastModifiedBy" : "anonymousUser",
"lastModifiedDate" : "2015-11-12T20:55:32.368Z",
"name" : "TEST",
"links" : [ ],
"content" : [ ],
"links" : [ {
"rel" : "self",
"href" : "http://localhost:8081/myproject/sdr-api/projects/3"
}, {
"rel" : "testPlans",
"href" : "http://localhost:8081/myproject/sdr-api/projects/3/testPlans"
} ]
}
Am I missing something with the newest version of Spring Data REST?
Upvotes: 3
Views: 8821
Reputation: 360
With Spring:
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
@SpringBootApplication
public class QuizApplication implements ViewProvider {
public static void main(String[] args) {
SpringApplication.run(QuizApplication.class, args);
}
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer(EntityManager entityManager) {
return RepositoryRestConfigurer.withConfig(config -> config.exposeIdsFor(Question.class));
}
}
Upvotes: 0