SpringBoot之:SpringBoot的HATEOAS基礎

flydean 發表於 2022-06-17
Spring

簡介

SpringBoot提供了HATEOAS的便捷使用方式,前面一篇文章我們也講了如何在SpringBoot中使用HATEOAS。本文將會對這些內容進行擴充套件深入,詳細講解SpringBoot提供的這些基本方法。

連結Links

HATEOAS的一個非常重要的特徵就是在resources資源中包含超媒體,而超媒體最簡單的表示就是連結。

Spring HATEOAS為我們簡化了封裝Links的功能。

我們看一個HTML中的link標籤的例子:

<head>
<link rel="stylesheet" type="text/css" href="theme.css" />
</head>

可以看到一個link有兩個比較重要的屬性,一個是href代表link的連結,還有一個屬性是rel表示的當前文件與被連結文件之間的關係。

我們看下Link中的關鍵方法:

    public static Link of(String href) {
        return new Link(href);
    }

    public static Link of(String href, String relation) {
        return new Link(href, relation);
    }

    public static Link of(String href, LinkRelation relation) {
        return new Link(href, relation);
    }

可以傳入href和relation來構建一個Link物件。

看下面的例子:

Link link = Link.of("/something");

link = Link.of("/something", "my-rel");

其中LinkRelation是關聯關係的一個封裝介面,注意,它是一個介面,我們可以使用IanaLinkRelations中的具體實現來對其賦值,如下所示:

LinkRelation REL_SELF = IanaLinkRelations.SELF;
LinkRelation REL_FIRST = IanaLinkRelations.FIRST;
LinkRelation REL_PREVIOUS = IanaLinkRelations.PREV;
LinkRelation REL_NEXT = IanaLinkRelations.NEXT;
LinkRelation REL_LAST = IanaLinkRelations.LAST;

URI templates

上面的例子中link是指定好的,是靜態的。有時候我們希望link可以根據引數進行變換,那麼這樣的link就是動態的link,我們可以通過定義URI模板來實現。

所以Link還可以通過UriTemplate來構建:

    public static Link of(UriTemplate template, String relation) {
        return new Link(template, relation);
    }

    public static Link of(UriTemplate template, LinkRelation relation) {
        return new Link(template, relation);
    }

UriTemplate是對URI模板的封裝,我們看一個使用的例子:

Link link = Link.of("/{segment}/something{?parameter}");

Map<String, Object> values = new HashMap<>();
values.put("segment", "path");
values.put("parameter", 42);

assertThat(link.expand(values).getHref()) 
    .isEqualTo("/path/something?parameter=42");

上面的例子中,通過string來構建一個link,然後呼叫expand傳入引數對應的map,來構建真實的href值。

除了直接使用string之外,還可以傳入UriTemplate:

UriTemplate template = UriTemplate.of("/{segment}/something")
  .with(new TemplateVariable("parameter", VariableType.REQUEST_PARAM);

assertThat(template.toString()).isEqualTo("/{segment}/something{?parameter}");

Link relations

Link relations指的是link中的ref屬性。代表的是當前文件與被連結文件之間的關係。Spring HATEOAS中有一個LinkRelation類來表示。

IANA(Internet Assigned Numbers Authority)預定義了一些relations,可以通過IanaLinkRelations這個類來獲取,如下所示:

Link link = Link.of("/some-resource"), IanaLinkRelations.NEXT);

assertThat(link.getRel()).isEqualTo(LinkRelation.of("next"));
assertThat(IanaLinkRelation.isIanaRel(link.getRel())).isTrue();

Representation models

我們需要訪問的是一個個的資源,然後需要在一個個的資源中加入link,Spring HATEOAS為我們提供了一個簡單的類叫做RepresentationModel。它包含了Links和一些很方便的方法來幫助我們建立帶連結的資源。

最簡單的使用方法就是建立一個RepresentationModel的子類:

public class BookModel extends RepresentationModel<BookModel> {

    private final Book content;

}

我們通過add方法來對其新增link:

bookModel.add(linkTo(methodOn(BookController.class).getBook(id)).withSelfRel());
注意,在這種情況下,我們的Accept型別應該是application/hal+json。

對於簡單型別,我們可以直接使用EntityModel對其進行封裝:

Person person = new Person("Dave", "Matthews");
EntityModel<Person> model = EntityModel.of(person);

對於集合,可以使用CollectionModel:

Collection<Person> people = Collections.singleton(new Person("Dave", "Matthews"));
CollectionModel<Person> model = CollectionModel.of(people);

總結

上講解的Link,URI templates,Link relations和RepresentationModel就是Spring HATEOAS的基礎,掌握了他們基本上就掌握了Spring HATEOAS。

更多內容請參考 http://www.flydean.com/00043-springboot-hateoas-fundamentals/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!