REST控制器与Spring Data REST RepositoryRestResource [英] Rest Controllers vs spring-data-rest RepositoryRestResource

查看:230
本文介绍了REST控制器与Spring Data REST RepositoryRestResource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这可能像是它的重复.
何时使用@RestController与@RepositoryRestResource
但是我有一些问题没有解决.

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 question.

  1. 对于@RepositoryRestResource,默认情况下公开每个方法.我觉得有点烦.如果我在这里错了,请纠正我.例如,在以下情况下

  1. With @RepositoryRestResource, every method is by default exposed. Which I feel is a bit annoying. Correct me if I am wrong here. For example in the below case

@RepositoryRestResource  
public interface ProductRepository extends MongoRepository<Product, String> {} 

如果我只想公开findAll()和findOne(),而不要公开其他任何方法,尤其是删除.为了实现这一点,我需要做这样的事情

If I want only findAll() and findOne() to be exposed and not any other methods, especially delete. To achieve this I need to do something like this

    @RepositoryRestResource
    public interface ProductRepository extends MongoRepository<Product, String> {
      @RestResource(exported = false)
      @Override
      default void delete(String s) {
      }
      @RestResource(exported = false)
      @Override
      default void delete(Product product) {
      }
      @RestResource(exported = false)
      @Override
      default void delete(Iterable<? extends Product> iterable) {
      }
      @RestResource(exported = false)
      @Override
      default void deleteAll() {
      }
    }

我觉得确实有很多不需要的代码.最好使用Rest Controller方法

Which I feel is really lot of unwanted code. This is much better to do with Rest Controller approach

  1. 我相信最好使用ResponseEntity从REST端点返回任何值.但是,使用spring-data-rest方法,我不确定该怎么做.

  1. I believe it is better to return any value from REST endpoints using ResponseEntity. But with spring-data-rest approach, I am not sure how to do it.

我找不到任何方法来对RepositoryRestResource公开的REST端点进行单元测试(非IT).但是使用REST控制器方法,我可以使用MockServletContextMockMvcMockMvcBuilders

I could not find any way to unit test(Not IT) REST endpoints exposed by the RepositoryRestResource. But with REST controller approach, I can test my REST endpoints using MockServletContext, MockMvc, MockMvcBuilders

鉴于所有这些,使用sping-data-rest(HATEOS除外)是否仍然有优势?
请澄清

Given all these, is it still advantageous to use sping-data-rest(except for HATEOS)?
please clarify

推荐答案

Spring-data-rest是为数据存储库提供REST端点,它确实提供了包括所有内容的可靠REST,包括ALPS元数据,搜索端点等.通常,这涵盖了大多数用例,并为定制提供了依据.

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.

这里有一些提示.

关于p.1)-自定义导出的资源和方法.

Regarding p.1) - Customising exported resources and methods.

您不需要将@RestResource(exported = false)放在所有delete(...)方法上,因为实际上只导出了一个:void delete(Product entity).查看相关文档章节和源代码.如果我没有错过任何事情,您只需要提供以下内容即可:

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)
  • findAll(Pageable)
  • findOne(id)
  • save(Entity)
  • delete(Entity)

关于导出的存储库方法的说明.有时,扩展非常基本的(空)Repository<Product, String>存储库接口并仅提供您允许在存储库中使用的方法会更容易,例如:

A note about exported repository methods. Sometimes it's easier to extend a very basic (empty) Repository<Product, String> repository interface and provide only methods you allow on the repository, for example:

@RepositoryRestResource
public interface ProductRepository extends Repository<Product, String> {
  long count();
  Page<Product> findAll(Pageable pageable);
  Product findOne(String entity);
  <S extends Product> S save(S entity);
}

关于自定义控制器.要自定义默认行为,最简单的方法是使用@RespositoryRestController注释控制器.签出文档并查看

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.

关于p.2):从控制器返回ResponseEntity

Regarding p.2) Returning ResponseEntity from controllers

这非常艰巨.您可以将实体包装到Resource<T>中(例如使用PersistentEntityResourceAssembler),并使用它创建ResponseEntity.参见

It's very straingforward. You can wrap entity into Resource<T> (e.g. using a PersistentEntityResourceAssembler) and create a ResponseEntity with it. See RepositoryEntityController.java and some examples, like spring-restbucks.

关于p.3)-测试其余端点

公开RepositoryRestResource的REST端点在RepositoryEntityController(spring-data-rest的一部分)中实现.

REST endpoints that expose the RepositoryRestResource are implemented in the RepositoryEntityController (part of the spring-data-rest).

如果实现自己的自定义控制器,则可以照常添加单元测试,但是如果使用PersistentEntityResourceAssembler,事情会变得更加复杂.

If you implement your own custom controller, you can add unit tests as usual but things get more complex if you use PersistentEntityResourceAssembler.

单元测试示例:

public class FooControllerTests {

  @Mock
  PersistentEntityResourceAssembler assembler;

  @Mock
  PersistentEntityResourceAssemblerArgumentResolver assemblerResolver;

  @Mock
  PersistentEntity<Foo, ?> 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());
  }
}

另请参见使用Spring构建REST服务"教程.

希望这会有所帮助.

这篇关于REST控制器与Spring Data REST RepositoryRestResource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆