Rest Controllers vs spring-data-rest RepositoryRestResource

前端 未结 1 1277
天命终不由人
天命终不由人 2021-01-05 15:48

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

1条回答
  •  太阳男子
    2021-01-05 15:54

    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.

    0 讨论(0)
提交回复
热议问题