【问题标题】:Spring REST HATEOASSpring REST HATEOAS
【发布时间】:2017-03-28 07:33:55
【问题描述】:

我正在尝试遵循最佳实践,想象一个带有 /books 端点的基本 API。

我有以下课程: 书 BookRepository(PagingAndSortingRepository 但未导出!!) BookController(这是服务类) BookResource(“代表状态转移”中的书的“代表”) BookResourceAssembler

我的 BookController 如下所示:

@RequestMapping(path="/{id}", method = RequestMethod.GET)
    public ResponseEntity<?> getBook(@PathVariable Long id) {
        Book book = bookRepository.findOne(id);
        BookResource bookResource = this.bookResourceAssembler.toResource(book);
        return ResponseEntity.ok(bookResource);
    }

我的 BookResource 如下所示:

public class BookResource extends ResourceSupport{
    public String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

BookResourceAssembler:

@Component
public class BookResourceAssembler extends ResourceAssemblerSupport<Book, BookResource> {

      public BookResourceAssembler() {
        super(BookController.class, BookResource.class);
      }


    @Override
    public BookResource toResource(Book entity) {
        BookResource resource = createResourceWithId(entity.getDbid(), entity);
        return resource;
    }
}

我想我的第一个问题很容易解决,标题没有初始化,所以当我调用 /books/1 时,我得到 title: null。

第二个也是更重要的问题是我如何进行内容协商和版本控制,这是 RESTful API 的一个非常重要的方面。我应该如何引入 BookResourceV2 以及我应该在哪里协商它?假设我想要

"Content-Type: application/vnd.company.book+json.v2"

我在哪里说明这一点?我应该添加哪些新类/函数来处理同一资源的 v2?

我找不到涵盖所有方面的好教程。

【问题讨论】:

    标签: java spring rest spring-hateoas


    【解决方案1】:

    我猜我的第一个问题很容易解决,标题不是 已初始化,因此当我调用 /books/1 时,我得到 title: null。

    您以错误的方式使用 BookResource。 我假设您的域对象(书)看起来像:

    public class Book {
        public String title;
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
    }
    

    BookResource 是一个包装器,可将链接添加到域对象并以 RESTful 方式呈现...

    public class BookResource extends Resource<Book> {
    
        public BookResource(Book content, Link... links) {
            super(content, links);
        }
    
    }
    

    为了记录,在这种情况下,您甚至不需要自定义 Resource 和 ResourceAssembler 类:

    @RequestMapping(path="/{id}", method = RequestMethod.GET)
    public ResponseEntity getBook(@PathVariable Long id,
        PersistentEntityResourceAssembler assembler) {
        Book book = bookRepository.findOne(id);
        if (null == book) {
            throw new ResourceNotFoundException();
        }
    
        return ResponseEntity.ok(assembler.toResource(book));
    }
    

    在这个非常简单的情况下(没有对 Book 实例进行特殊处理),您甚至不需要这个端点,因为 Spring 会为您生成它。

    第二个也是更重要的问题是我如何进行内容协商 和版本控制,这是 RESTful API 的一个非常重要的方面。如何 我应该介绍 BookResourceV2,我应该在哪里协商?

    您需要定义一个RepositoryRestController 并使用RequestMapping 注释控制器端点的produces 参数,类似于我在此post 中解释的内容。

    【讨论】:

      猜你喜欢
      • 2013-10-31
      • 2011-11-02
      • 2014-03-07
      • 2014-08-16
      • 2016-05-23
      • 2014-07-05
      • 2018-07-23
      • 2018-11-26
      • 2015-12-03
      相关资源
      最近更新 更多