Reputation: 519
I use Spring Data Rest and I can not understand why my RepositoryRestController does not work. Its code:
@RepositoryRestController
public class Cntrl {
@Autowired
private UserDao userDao;
@RequestMapping(name = "/users/{id}/nameOne",method =
RequestMethod.GET)
@ResponseBody
public PersistentEntityResource setNameOne(@PathVariable("id") Long id, PersistentEntityResourceAssembler persistentEntityResourceAssembler){
User user = userDao.findById(id).orElseThrow(()->{
throw new ServerException("Wrong id");
});
user.setLogin("One");
userDao.save(user);
return persistentEntityResourceAssembler.toFullResource(user);
}
}
And Spring Boot start class:
@SpringBootApplication
@EnableWebMvc
@EnableScheduling
@EnableJpaRepositories
@EnableSpringDataWebSupport
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
When i go to base path (localhost:8080/api) everything is fine, but when send GET to request to localhost:8080/api/users/1/nameOne I get empty response, i dont have other controllers and I have user with id 1, so why it is not working ?
Upvotes: 1
Views: 1252
Reputation: 572
As far as I could figure out, if you use a RepositoryRestController
you must activate the path using a corresponding RestRepositoryResource
, before it's available in a controller, i.e. this would work:
// new code
@RepositoryRestResource(path = "/users")
public interface UserDaoRepository extends Repository<UserDao, String> {}
// your code
@RepositoryRestController
public class Cntrl {
@Autowired
private UserDao userDao;
@RequestMapping(name = "/users/{id}/nameOne",method =
RequestMethod.GET)
@ResponseBody
public PersistentEntityResource setNameOne(@PathVariable("id") Long id, PersistentEntityResourceAssembler persistentEntityResourceAssembler){
User user = userDao.findById(id).orElseThrow(()->{
throw new ServerException("Wrong id");
});
user.setLogin("One");
userDao.save(user);
return persistentEntityResourceAssembler.toFullResource(user);
}
}
Alternatively, you could opt to use a BasePathAwareController
instead of RepositoryRestController
, which does not require a resource.
@BasePathAwareController // <<<< NOT @RepositoryRestController
public class Cntrl {
@Autowired
private UserDao userDao;
@RequestMapping(name = "/users/{id}/nameOne",method = RequestMethod.GET)
@ResponseBody
public PersistentEntityResource setNameOne(@PathVariable("id") Long id, PersistentEntityResourceAssembler persistentEntityResourceAssembler){
User user = userDao.findById(id).orElseThrow(()->{
throw new ServerException("Wrong id");
});
user.setLogin("One");
userDao.save(user);
return persistentEntityResourceAssembler.toFullResource(user);
}
}
Upvotes: 0
Reputation: 350
It doesn't work because the URL structure you are using has already a meaning in Spring Data Rest context.
/{repository}/{id}/{column}
URL is handled at RepositoryPropertyReferenceController.followPropertyReference
method.
/api/users/1/nameOne
means: get the nameOne
column of the user with the id of 1. An important note is that: this column should reference another @Entity
. This means if you have a String
column named "surname" and you hit the URL /api/users/1/name
you will get 404 because this column is not referencing another entity. If you have a column named school which references to a School
entity and you hit the URL /api/users/1/school
you will get the referenced school entity for that user. If the user does not have a school then you will get 404 again.
Also, @RepositoryRestController
can be used for @RequestMapping
if the URL you are giving isn't colliding with Spring Data Rest.
You can test that with the following example:
@RepositoryRestController
public class CustomRepositoryRestController {
@RequestMapping(path = "/repositoryRestControllerTest", method = RequestMethod.GET)
@ResponseBody
public String nameOne() {
return "test";
}
}
Visit http://localhost:8080/repositoryRestControllerTest
I hope this explanation clarifies things for you.
Upvotes: 3
Reputation: 26542
If localhost:8080/api
is your root context, then localhost:8080/api/users/1/nameOne
should be the url you are using for the user GET.
Upvotes: 0