I know this might feel like a duplicate of this.
When to use @RestController vs @RepositoryRestResource
But I have a few things which were not addressed in that ques
Spring-data-rest is about providing REST endpoints for data repositories and it does provides solid REST with all bells and whistles including ALPS metadata, search endpoints, etc. This usually covers most use cases and provides basis for customisations.
Here're some hints.
Regarding p.1) - Customising exported resources and methods.
You do not need to put @RestResource(exported = false)
on all delete(...)
methods because only one is actually exported: void delete(Product entity)
. Look into relevant documentation chapter and the source code. If i do not miss something, you just need to provide these:
findAll(Pageable)
findOne(id)
save(Entity)
delete(Entity)
A note about exported repository methods. Sometimes it's easier to extend a very basic (empty) Repository
repository interface and provide only methods you allow on the repository, for example:
@RepositoryRestResource
public interface ProductRepository extends Repository {
long count();
Page findAll(Pageable pageable);
Product findOne(String entity);
S save(S entity);
}
Regarding a custom controller. To customise a default behaviour the easiest is to annotate controllers with @RespositoryRestController
. Check-out docs and look into RepositoryEntityController.java - that's the default controller.
Regarding p.2) Returning ResponseEntity from controllers
It's very straingforward. You can wrap entity into Resource
(e.g. using a PersistentEntityResourceAssembler
) and create a ResponseEntity
with it. See RepositoryEntityController.java and some examples, like spring-restbucks.
Regarding p.3) - Testing rest endpoints
REST endpoints that expose the RepositoryRestResource are implemented in the RepositoryEntityController
(part of the spring-data-rest).
If you implement your own custom controller, you can add unit tests as usual but things get more complex if you use PersistentEntityResourceAssembler
.
Unit test example:
public class FooControllerTests {
@Mock
PersistentEntityResourceAssembler assembler;
@Mock
PersistentEntityResourceAssemblerArgumentResolver assemblerResolver;
@Mock
PersistentEntity entity;
@InjectMocks
FooController fooController;
@Mock
FooService fooService;
private MockMvc mockMvc;
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(fooController)
.setCustomArgumentResolvers(assemblerResolver)
.build();
}
@Test
public void test_GetItem_Success() throws Exception {
final Foo foo = new Foo();
when(fooService.findOne(1)).thenReturn(foo);
when(assemblerResolver.supportsParameter(any())).thenReturn(true);
when(assemblerResolver.resolveArgument(any(), any(), any(), any())).thenReturn(assembler);
when(assembler.toResource(foo))
.thenReturn(PersistentEntityResource.build(foo, entity).build());
this.mockMvc.perform(get("/foo/1")).andExpect(status().isOk());
}
}
See also "Building REST services with Spring" tutorial.
Hope this helps.