精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

別再寫死 URL 了!Spring Boot HATEOAS 教你打造真正自描述 API

開發 前端
有沒有一種方式,讓服務端在返回數據時,順帶告訴客戶端下一步能做什么??有!這就是 HATEOAS 的價值所在 ——?響應本身就攜帶導航信息,告別“后知后覺”的 URL 變更。

在日常開發 RESTful 接口時,你是不是經常看到前端代碼中充斥著類似 "https://yourapi.com/books/101" 這樣的寫死地址?當接口路徑變更,客戶端就像多米諾骨牌一樣全線崩潰。

有沒有一種方式,讓服務端在返回數據時,順帶告訴客戶端下一步能做什么? 有!這就是 HATEOAS 的價值所在 —— 響應本身就攜帶導航信息,告別“后知后覺”的 URL 變更。

HATEOAS 簡介:讓 REST API 具備“自導航能力”

HATEOAS 是什么?

HATEOAS(Hypermedia As The Engine Of Application State)是 REST 架構的高級階段,它的核心理念是:

?? “服務端不僅返回資源數據,還提供訪問該資源相關操作的鏈接。”

換句話說,客戶端拿到數據時,不再需要自己拼接 URL,而是通過服務端提供的鏈接,驅動接下來的請求。

示例:基于在線圖書系統的 HATEOAS 實戰

普通 REST API 響應:

{
  "bookId": 101,
  "title": "Spring Boot Mastery",
  "author": "John Doe"
}

HATEOAS 風格響應:

{
  "bookId": 101,
  "title": "Spring Boot Mastery",
  "author": "John Doe",
  "_links": {
    "self": { "href": "/books/101" },
    "all-books": { "href": "/books" },
    "buy-book": { "href": "/books/101/buy" },
    "reviews": { "href": "/books/101/reviews" }
  }
}

這樣,客戶端馬上知道下一步可以:

  • 再次獲取該圖書信息
  • 查看所有圖書
  • 購買圖書
  • 查看圖書評論

HATEOAS 在 Spring Boot 中的完整開發流程

引入依賴(pom.xml)

<dependencies>
    <!-- Web 核心 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>


    <!-- HATEOAS 支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-hateoas</artifactId>
    </dependency>


    <!-- Lombok(可選) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

創建實體類 /src/main/java/com/icoderoad/api/book/model/Book.java

package com.icoderoad.api.book.model;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
    private Long bookId;
    private String title;
    private String author;
    private double price;
}

控制器實現 /src/main/java/com/icoderoad/api/book/controller/BookController.java

package com.icoderoad.api.book.controller;


import com.icoderoad.api.book.model.Book;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import java.util.List;
import java.util.stream.Collectors;


import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;


@RestController
@RequestMapping("/books")
public class BookController {


    private final List<Book> books = List.of(
        new Book(101L, "Spring Boot Mastery", "John Doe", 29.99),
        new Book(102L, "HATEOAS in Action", "Jane Smith", 24.99)
    );


    @GetMapping("/{id}")
    public EntityModel<Book> getBook(@PathVariable Long id) {
        Book book = books.stream()
            .filter(b -> b.getBookId().equals(id))
            .findFirst()
            .orElseThrow(() -> new BookNotFoundException(id));


        return EntityModel.of(book,
            linkTo(methodOn(BookController.class).getBook(id)).withSelfRel(),
            linkTo(methodOn(BookController.class).getAllBooks()).withRel("all-books"),
            Link.of("/books/" + id + "/buy", "buy-book"),
            Link.of("/books/" + id + "/reviews", "reviews"));
    }


    @GetMapping
    public CollectionModel<EntityModel<Book>> getAllBooks() {
        List<EntityModel<Book>> bookModels = books.stream()
            .map(book -> EntityModel.of(book,
                linkTo(methodOn(BookController.class).getBook(book.getBookId())).withSelfRel(),
                linkTo(methodOn(BookController.class).getAllBooks()).withRel("books")))
            .collect(Collectors.toList());


        return CollectionModel.of(bookModels,
            linkTo(methodOn(BookController.class).getAllBooks()).withSelfRel());
    }


    @ExceptionHandler(BookNotFoundException.class)
    public ResponseEntity<String> handleNotFound(BookNotFoundException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
    }
}

自定義異常類 /src/main/java/com/icoderoad/api/book/controller/BookNotFoundException.java

package com.icoderoad.api.book.controller;


public class BookNotFoundException extends RuntimeException {
    public BookNotFoundException(Long id) {
        super("未找到書籍,ID: " + id);
    }
}

拓展:使用 RepresentationModel 構建更靈活的響應

@GetMapping("/{id}/status")
public RepresentationModel<?> getBookStatus(@PathVariable Long id) {
    RepresentationModel<?> model = new RepresentationModel<>();
    model.add(linkTo(methodOn(BookController.class).getBookStatus(id)).withSelfRel());
    model.add(linkTo(methodOn(BookController.class).getBook(id)).withRel("book"));
    // 可添加自定義狀態字段
    return model;
}

HATEOAS 的優點:不僅僅是“返回鏈接”這么簡單

  • 客戶端無需拼接 URL:前端直接讀取響應體中的鏈接發起請求,減少維護成本。
  • 應對接口演進更穩健:服務端 URL 改變后,客戶端無需改代碼。
  • 符合 RESTful 最佳實踐:實現 Richardson Maturity Model 的 Level 3(最高級別)

那為什么現實中很多項目不采用?

前端開發者其實早就知道要請求哪個接口、用什么方法、發什么數據。 比如:

axios.get("/books/101");
axios.post("/books/101/buy");

一旦 HATEOAS 上線,前端得讀取響應中的 _links 字段,再動態解析后請求新的接口。復雜度上升,不劃算。

結語:HATEOAS 適用于哪里?什么時候用值得深思

現實中,只有當你構建一個高度通用、自動化消費的 API(比如客戶端不固定時),HATEOAS 才真正展現優勢。 否則,對于固定結構的系統來說,明確 URL 并硬編碼在客戶端會更高效

總結一句話:

在大多數真實項目中,HATEOAS 并不是必選項,但它是構建真正 RESTful API 的“最后一公里”。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2020-06-04 09:18:52

CTOif-else代碼

2020-06-15 08:12:51

try catch代碼處理器

2025-09-01 01:33:00

DockerBuild命令

2020-09-01 21:03:10

Springboot格式化方式

2025-10-29 01:45:00

toString()SpringJackson

2025-09-12 07:55:54

2023-08-25 13:34:02

JavascriptWikipediaSlack

2025-11-12 07:50:52

SpringBoot登錄框OAuth2

2025-09-29 01:33:00

Spring初始化Bean

2024-12-20 18:00:00

C++折疊表達式C++17

2025-08-04 01:55:00

2020-12-01 08:32:12

Spring Boot

2025-06-04 02:10:00

2023-05-11 12:40:00

Spring控制器HTTP

2025-09-15 01:55:00

緩存代碼Easy-Cache開發

2023-03-27 08:28:57

spring代碼,starter

2022-04-27 08:55:01

Spring外部化配置

2025-01-15 12:31:46

2023-10-25 12:38:58

交換機指示燈

2017-04-25 10:46:57

Spring BootRESRful API權限
點贊
收藏

51CTO技術棧公眾號

亚洲一区3d动漫同人无遮挡 | 国产丝袜一区二区三区| 日韩a∨精品日韩在线观看| 暖暖视频在线免费观看| 人妖欧美一区二区| 色综合久综合久久综合久鬼88| 最近日本中文字幕| 欧洲亚洲精品| 五月婷婷综合网| 一区二区免费在线观看| 殴美一级特黄aaaaaa| 蜜臀久久久久久久| 97精品视频在线播放| 中国特黄一级片| 欧美天堂社区| 日韩一区二区在线观看视频| 成年人视频观看| 污污视频在线看| 国产精品久久午夜| 欧美日韩日本网| 黄色片一区二区三区| 久久国产夜色精品鲁鲁99| 2018国产精品视频| 免费在线观看黄色av| 日韩欧美网站| 亚洲欧美国产一区二区三区| 一区二区三区四区影院| 视频91a欧美| 欧美亚洲图片小说| av动漫在线看| 丁香花高清在线观看完整版| 亚洲色图在线视频| 亚洲不卡中文字幕| 色综合成人av| www.成人在线| 国产福利一区二区三区在线观看| 亚洲专区在线播放| 免费国产亚洲视频| 日本精品中文字幕| 欧美在线观看不卡| 亚洲一区区二区| 国内自拍欧美激情| 国产精品suv一区二区| 国产综合精品一区| 欧美激情网站在线观看| 美女的奶胸大爽爽大片| 亚洲成人tv| 久久久国产一区二区| 激情高潮到大叫狂喷水| 日韩1区在线| 中文字幕日韩专区| 女教师淫辱の教室蜜臀av软件| 国产不卡一区| 亚洲一级黄色片| 日韩女同一区二区三区| 欧美久久综合网| 中文字幕亚洲一区二区三区五十路| 91l九色lporny| 精品免费一区二区| 日韩在线观看免费全集电视剧网站| 欧美人与性囗牲恔配| 日韩综合一区| 久久精彩免费视频| 免费在线观看一级片| 午夜电影亚洲| 国内成人精品视频| 在线观看日本视频| 秋霞午夜av一区二区三区| 国产精品香蕉国产| 一级黄色片在线| 国产成人在线视频免费播放| 国产在线一区二| 欧美人体大胆444www| 国产欧美综合色| 伊人婷婷久久| 超碰在线中文字幕| 一本久久综合亚洲鲁鲁五月天 | 伊人久久久久久久久久久久 | 亚洲字幕在线观看| 日韩中文字幕影院| 久久久久久免费毛片精品| 亚洲精品一区国产精品| 亚洲区欧洲区| 欧美性xxxxx极品娇小| 欧美午夜aaaaaa免费视频| www.成人| 亚洲男人天堂2023| 男人晚上看的视频| 一区二区高清| 国产欧美精品xxxx另类| 成人免费视频国产免费麻豆| 国产亚洲精品aa午夜观看| 亚洲伊人婷婷| f2c人成在线观看免费视频| 欧美自拍丝袜亚洲| 精品人妻二区中文字幕| 奇米狠狠一区二区三区| 久色乳综合思思在线视频| 国产成人愉拍精品久久| 捆绑紧缚一区二区三区视频| 国产美女精品在线观看| av片在线看| 午夜精品视频一区| 国产成年人视频网站| 秋霞影视一区二区三区| 久久久精品一区二区| 日本特级黄色片| 国产成人在线色| 一区二区不卡视频| 外国成人直播| 亚洲成人精品久久久| 麻豆明星ai换脸视频| 久久动漫亚洲| 国产精品乱码视频| 97caopron在线视频| 欧美中文字幕一区二区三区亚洲| 少妇熟女视频一区二区三区 | 97精品国产91久久久久久| 91成品人影院| 国产日产欧产精品推荐色| 妞干网在线视频观看| 精品网站999| 欲色天天网综合久久| 成人精品在线看| 顶级嫩模精品视频在线看| 综合久久国产| 国产精品一区二区免费福利视频| 日韩高清人体午夜| 国产无码精品视频| 懂色一区二区三区免费观看| 一区二区高清视频| 国语自产精品视频在线看抢先版结局| 日韩成人av一区| 日本一级淫片免费放| 国产精品系列在线播放| 日本福利视频导航| 狠狠久久综合| 在线观看久久久久久| 亚洲黄网在线观看| 国产丝袜在线精品| 精品视频无码一区二区三区| 亚洲永久精品唐人导航网址| 91精品国产免费久久久久久| 蜜桃久久一区二区三区| 一区二区三区在线不卡| aaaaaaaa毛片| 欧美日韩国产一区精品一区| 99精彩视频| 免费男女羞羞的视频网站在线观看| 欧美电影精品一区二区| 久久久久久久久久网站| 国产99久久久国产精品免费看| 热久久最新地址| 中文一区二区三区四区| 欧美激情区在线播放| 免费观看毛片网站| 精品福利在线观看| 色婷婷av777| 青青草伊人久久| 91制片厂免费观看| 91亚洲精品视频在线观看| 91精品国产成人www| 欧美成熟毛茸茸| 欧美美女直播网站| 草视频在线观看| av在线一区二区| 欧在线一二三四区| 性欧美欧美巨大69| 国产精品欧美久久| 欧美色网一区| 久久影院中文字幕| 三级网站免费观看| 一本色道久久综合狠狠躁的推荐 | 日本人dh亚洲人ⅹxx| 狠狠色综合网| 欧美视频小说| 97久久中文字幕| 97热精品视频官网| 高清毛片在线看| 欧美一级专区免费大片| 黄色一级片免费看| 国产精品色婷婷久久58| 黄页网站在线看| 首页国产欧美日韩丝袜| 在线观看三级网站| 久久不见久久见国语| 91精品啪在线观看麻豆免费| 操人在线观看| www.亚洲一区| 视频三区在线观看| 7799精品视频| 国产精品免费av一区二区| 国产精品嫩草99a| 波多野结衣先锋影音| 美女看a上一区| 黄色国产一级视频| 中文字幕日韩一区二区不卡| 欧美日韩国产高清视频| 欧美一级片网址| 国产91色在线|| 福利成人导航| 久久影院资源网| 国产高清免费av在线| 精品国产青草久久久久福利| 特级西西444www高清大视频| 亚洲国产毛片aaaaa无费看| 欧美巨胸大乳hitomi| 99在线热播精品免费| 三级黄色片免费观看| 日韩影院在线观看| 五十路熟女丰满大屁股| 欧美aa国产视频| 亚洲一区二区三区免费看| 欧美男人操女人视频| 亚洲一区二区少妇| 欧美在线se| 国产精品视频公开费视频| 日本在线影院| 久久琪琪电影院| 青青青草视频在线| 久久伊人精品天天| 尤物网在线观看| 国产亚洲精品久久久久久| 人妻无码中文字幕| 精品国产区一区| 动漫av一区二区三区| 日韩一区二区三| 国产乱码一区二区| 欧美精品久久久久久久多人混战| 国产精品久久久久久久久夜色| 午夜欧美在线一二页| 欧美交换国产一区内射| 亚洲激情网站免费观看| 国产黄色小视频网站| 国产精品不卡在线| 手机av在线看| 中文字幕亚洲一区二区va在线| 大胸美女被爆操| 中文字幕精品三区| 国产福利在线导航| 国产精品福利av| 香蕉久久久久久久| 国产精品国产三级国产有无不卡| 美女av免费看| ...xxx性欧美| 五月天丁香激情| 亚洲国产精品久久久久婷婷884 | 成人自拍小视频| 亚洲女人的天堂| 久久国产一级片| 亚洲成人av资源| 97久久久久久久| 一本到高清视频免费精品| 国产情侣小视频| 欧美日本乱大交xxxxx| 97人妻人人澡人人爽人人精品| 6080午夜不卡| 成人av手机在线| 亚洲成人久久电影| 你懂的视频在线免费| 在线日韩第一页| 男人天堂久久久| 欧美猛少妇色xxxxx| h片视频在线观看| 欧美做爰性生交视频| 欧美综合社区国产| 国产99午夜精品一区二区三区| 欧美变态挠脚心| 日韩av电影在线观看| 国产精品99在线观看| 国产xxxx振车| 久久精品日韩欧美| 五月天视频在线观看| 国产成+人+日韩+欧美+亚洲| 好男人香蕉影院| 中文在线免费一区三区高中清不卡| 精品亚洲乱码一区二区| 亚洲成va人在线观看| 日韩一级片中文字幕| 91精品国产美女浴室洗澡无遮挡| 熟妇人妻系列aⅴ无码专区友真希 熟妇人妻av无码一区二区三区 | 亚洲色精品三区二区一区| 狠狠色丁香久久婷婷综合_中 | 国产亚洲短视频| 精品国产精品国产精品| 精品日韩视频在线观看| 亚洲最新av网站| 亚洲国产欧美久久| jizz亚洲| 97视频免费看| 亚洲福利影视| 久久av免费观看| 亚洲激情久久| 日本在线观看免费视频| 粉嫩欧美一区二区三区高清影视| 精品国产成人亚洲午夜福利| 一区二区三区欧美日| 国产精品xxxxxx| 精品久久久久久久久久久久包黑料 | 日韩黄色三级视频| 在线不卡免费av| 欧美日韩影视| 久久久女人电视剧免费播放下载| 国产精品无码久久久久| 欧美精品一区二区三区久久| 欧美a级在线| 日韩精品视频一二三| 91啪九色porn原创视频在线观看| 动漫性做爰视频| 91福利视频久久久久| 男人天堂网在线视频| 久久网福利资源网站| 秋霞国产精品| 久久久久久久有限公司| 国产综合色产| 宇都宫紫苑在线播放| 国产精品久久久久久妇女6080| 亚洲国产av一区二区三区| 亚洲成人精品在线| 黑人玩欧美人三根一起进| 亚洲一区二区三区在线免费观看 | 亚洲中文字幕无码av永久| 精品一区二区三区在线播放| 久久丫精品忘忧草西安产品| 午夜天堂影视香蕉久久| 亚洲精品18p| 欧美乱大交xxxxx另类电影| 亚洲欧美一级| 一本一本a久久| 麻豆精品久久精品色综合| 老熟妇一区二区| 色中色一区二区| 天天摸天天碰天天爽天天弄| 欧美激情欧美狂野欧美精品| 日韩精品三级| 免费的一级黄色片| 国产精品一卡二| 欧美日韩精品亚洲精品| 91精品中文字幕一区二区三区 | 欧美性受xxxx黑人猛交| 国产另类在线| 国产精品无码人妻一区二区在线 | 91制片厂在线| 欧美日韩国产在线观看| 日本a在线播放| 91精品久久久久久久久中文字幕| 成人精品中文字幕| 亚洲免费999| 亚洲视频精选在线| 性少妇videosexfreexxx片| 久久99视频免费| 国产精品网在线观看| 成 年 人 黄 色 大 片大 全| av电影一区二区| 69国产精品视频免费观看| 亚洲片国产一区一级在线观看| 成人在线爆射| 一区二区三区久久网| 国产综合色在线| 国产精品19乱码一区二区三区| 日韩成人在线免费观看| 美女写真久久影院| 亚洲第一页在线视频| 国产成人欧美日韩在线电影| 99免费在线观看| 亚洲美女久久久| 亚洲成人高清| 免费一级特黄毛片| 欧美国产日本视频| 性生活视频软件| 欧美亚洲国产视频| 97人人精品| 制服丝袜在线第一页| 91国偷自产一区二区三区观看| 欧美性天天影视| 国产精品美女黄网| 日本在线不卡视频一二三区| 午夜精品一区二区三区视频| 日韩av在线网| 久久av日韩| 欧美 日韩 亚洲 一区| 欧美激情综合在线| 性欧美一区二区三区| 国产成人一区二区| 红桃视频亚洲| 色一情一交一乱一区二区三区| 日韩一区二区三区精品视频| 午夜影院在线播放| 免费成人深夜夜行网站视频| 99精品一区二区| 国产乱叫456在线| 国产成人涩涩涩视频在线观看| 欧美成人69av| 国产精品一区二区亚洲| 欧美精品一区二区三区视频| 国产麻豆一区| 久久精品午夜福利| 亚洲国产精品久久一线不卡| 婷婷在线视频观看| 欧美精品在线一区|