精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

久久婷婷国产综合国色天香| 亚洲免费影院| 欧美精品一区二区不卡| av7777777| 麻豆视频在线| 99久久精品国产网站| 国产精品老女人精品视频| 青娱乐在线视频免费观看| 国产毛片一区二区三区| 日韩美女一区二区三区四区| 免费观看成人网| 黄色成人在线| 久久精品视频在线看| 99九九视频| 一炮成瘾1v1高h| 久久久久国产精品午夜一区| 美女福利视频一区| 国产一二三四区在线| jizz性欧美23| 欧美一区二区不卡视频| 日韩亚洲在线视频| 男人久久天堂| 亚洲高清视频中文字幕| 色中文字幕在线观看| 国产剧情在线观看| 成人av在线播放网站| 91精品综合久久| 亚洲视频在线观看一区二区| 午夜在线a亚洲v天堂网2018| 久久久久亚洲精品| 在线免费观看亚洲视频| 久久中文字幕av一区二区不卡| 精品一区二区电影| 美女又爽又黄免费| 久久午夜影院| 精品嫩草影院久久| 免费在线观看日韩av| 精品视频在线播放一区二区三区| 欧美日本一区二区在线观看| 日韩肉感妇bbwbbwbbw| 日韩电影网站| 日韩欧美在线视频观看| 欧美亚洲另类色图| 亚洲妇女成熟| 色妹子一区二区| 青青青在线播放| 在线成人av观看| 日韩欧美成人免费视频| 国产成人在线免费看| 蜜桃视频在线网站| 日韩欧美亚洲范冰冰与中字| 国产无套内射久久久国产| 国模精品视频| 色综合久久综合网| 无码内射中文字幕岛国片| 成人啊v在线| 欧美日韩一区在线观看| 色噜噜狠狠一区二区三区狼国成人| 久久人体av| 正在播放亚洲一区| 91成人在线观看喷潮蘑菇| 国产精品久久久网站| 亚洲精品国产免费| 韩国三级hd中文字幕| 热久久天天拍国产| 不卡毛片在线看| 精品一区免费观看| 国产精品五区| 国产欧美欧洲在线观看| 亚洲国产精品久久人人爱潘金莲| 成人美女在线视频| 欧美日韩综合网| 日本在线播放| 亚洲.国产.中文慕字在线| 免费无码av片在线观看| 99久久久国产精品免费调教网站| 欧美一区二区三区在| 国产精品入口麻豆| 久久国产亚洲| 久久久亚洲网站| 91麻豆精品在线| 国产精品亚洲第一区在线暖暖韩国| 国产欧美一区二区在线播放| 国模精品一区二区| 一区二区三区毛片| 久久婷婷国产精品| 国产精品18| 精品亚洲国产成av人片传媒 | 色老头在线视频| 精品一区二区三区在线视频| 国内精品久久久久久久果冻传媒| jizz在线观看| 亚洲成人免费电影| 亚洲 激情 在线| 精品视频高潮| 久久精品国产电影| 亚洲黄色免费观看| 国产精品69久久久久水密桃| 欧美连裤袜在线视频| 91香蕉在线观看| 欧美又粗又大又爽| 欧美深性狂猛ⅹxxx深喉| 久久久久免费av| 国产成人亚洲综合| 人成网站在线观看| 亚洲视频一区二区在线| 精品久久久久久无码国产| 成人午夜网址| 久久精品亚洲一区| 中文字幕 国产| 99久久国产综合精品色伊| 中文字幕99| 精品欧美日韩精品| 日韩高清有码在线| 国产无码精品一区二区| 韩国女主播成人在线| 色一情一区二区三区四区| sm捆绑调教国产免费网站在线观看| 欧美日韩国产欧美日美国产精品| 国产精品一区二区入口九绯色| 欧美成人日韩| 91日韩在线播放| 91激情在线| 日本高清不卡在线观看| 欧美成人三级伦在线观看| 欧美激情亚洲| 亚洲xxx视频| 亚洲婷婷噜噜| 欧美一区二区日韩| 91杏吧porn蝌蚪| 国产一区在线不卡| 国产在线拍揄自揄拍无码| 国产亚洲欧美日韩精品一区二区三区 | 久久久久国产精品熟女影院| 午夜先锋成人动漫在线| 亚洲精品视频在线观看网站| 91麻豆精品国产91久久久使用方法 | 91video| 成人黄色网址在线观看| 少妇久久久久久被弄到高潮| 国产福利一区二区三区在线播放| 亚洲人线精品午夜| 日日夜夜操视频| 久久久亚洲欧洲日产国码αv| 欧美三级在线观看视频| 国产乱人伦丫前精品视频| 欧美激情二区三区| 欧美视频在线观看一区二区三区| 亚洲一区二区精品久久av| 日韩精品国产一区| 99精品国产福利在线观看免费| 国产伦精品一区二区三区照片91 | 亚洲资源在线看| 岛国中文字幕在线| 精品久久久久久久久久久久包黑料| 免费无遮挡无码永久在线观看视频 | 久久一区二区电影| 久久久久久自在自线| 色综合电影网| 在线免费观看亚洲| 久久久久久久爱| 天堂成人在线视频| 日本高清无吗v一区| 欧美特黄一级片| 高清成人免费视频| 男人天堂999| 日本不卡电影| 99中文字幕| 亚洲欧洲高清| xx视频.9999.com| 成人乱码一区二区三区| 欧美日韩午夜激情| 精品少妇一区二区三区免费观| 日本中文一区二区三区| 裸体裸乳免费看| 九九热hot精品视频在线播放| 欧美一级大胆视频| 麻豆网站在线| 亚洲国产精品久久久久秋霞蜜臀 | 国产大学生自拍| 99久久99久久免费精品蜜臀| 激情综合网俺也去| 欧美午夜不卡| 日韩性感在线| 一区二区三区四区高清视频| 日韩美女激情视频| 在线欧美三级| 国产亚洲视频在线| 黄色片网站免费在线观看| 色激情天天射综合网| 欧美成人精品欧美一级私黄| 久久久国产一区二区三区四区小说 | 亚洲天堂色网站| 亚洲黄色一级大片| 欧美性大战久久久| 成人精品免费在线观看| 亚洲天堂免费在线观看视频| 亚洲自拍偷拍一区二区| 国产成人免费视频一区| 在线免费视频一区| 国产欧美一区二区色老头 | 精品一区二区三区蜜桃在线| 国产高清一区日本| 中文字幕第80页| 日韩一区二区久久| 18视频在线观看娇喘| 欧美日韩爱爱| 黑人中文字幕一区二区三区| 成人在线日韩| 国产精品视频一区二区三区四| 123区在线| 久久6精品影院| 日本中文字幕在线看| 亚洲片av在线| 丝袜视频国产在线播放| 精品粉嫩aⅴ一区二区三区四区| 一级片视频播放| 91黄色免费版| 无码人妻久久一区二区三区| 五月婷婷久久综合| 国产一级在线免费观看| 亚洲色图一区二区| 91麻豆精品久久毛片一级| 久久久91精品国产一区二区精品| 日韩aaaaa| caoporn国产一区二区| 深夜视频在线观看| 国产福利电影一区二区三区| 91网址在线观看精品| 紧缚捆绑精品一区二区| 日本 片 成人 在线| 老司机午夜精品视频| 精品无码国产一区二区三区av| 欧美在线视屏| 国产91视频一区| 国产一在线精品一区在线观看| 成人高清dvd| 综合激情网站| www插插插无码免费视频网站| 欧美日韩午夜| 男人添女荫道口女人有什么感觉| 国产精品videosex极品| 国产精品久久国产| 99在线精品免费视频九九视| 日本一道本久久| 国产一区二区三区久久久久久久久| 北条麻妃在线视频观看| 亚洲视频www| 少妇性l交大片| 蜜臀va亚洲va欧美va天堂| 污污的网站18| 国内精品视频666| 精品人妻人人做人人爽夜夜爽| 国产成人福利片| 北岛玲一区二区| 久久综合久色欧美综合狠狠| 神马久久久久久久久久久| 国产精品福利av| 黄色一级视频免费观看| 午夜精品视频一区| 中文字幕免费观看| 宅男噜噜噜66一区二区66| 精品乱子伦一区二区| 亚洲第一区中文99精品| 人成在线免费视频| 久久精品视频在线| 大香伊人中文字幕精品| 国产成人精品a视频一区www| 人人精品久久| 国产专区一区二区| 国产欧美亚洲精品a| dy888午夜| 国产精品美女久久久| 色婷婷狠狠18| 国产福利视频一区二区三区| 泷泽萝拉在线播放| 亚洲人成精品久久久久久| 日韩欧美激情视频| 欧美日韩另类一区| 色香蕉在线视频| 尤物99国产成人精品视频| 亚洲无线看天堂av| 国产精品精品久久久| ady日本映画久久精品一区二区| 日本成人三级| 欧美精品91| 黑人粗进入欧美aaaaa| 国产成人午夜电影网| 中文幕无线码中文字蜜桃| 一区二区三区在线免费播放| 国语对白永久免费| 日韩亚洲国产中文字幕欧美| 九色视频在线观看免费播放 | 一区二区91美女张开腿让人桶| 亚洲精品欧洲| 天天操狠狠操夜夜操| 91久色porny| 九九九在线视频| 欧美三级电影在线看| 婷婷五月综合久久中文字幕| 久久色在线播放| 午夜无码国产理论在线| 国产伦精品一区二区三区| 高h视频在线观看| 国产精品国产三级国产普通话三级 | av在线电影播放| 97视频在线观看视频免费视频| 国产美女视频一区二区 | 欧美在线看片| 亚洲综合激情视频| 久久一区二区三区四区| 国产性猛交普通话对白| 911精品国产一区二区在线| 欧美孕妇孕交| 91精品国产91久久久久久吃药| 欧美高清一级片| 亚洲高清精品中出| 日日骚欧美日韩| 久操视频免费看| 色综合夜色一区| 四虎影院在线播放| 1769国内精品视频在线播放| 91蝌蚪精品视频| 国产一级黄色录像片| 极品销魂美女一区二区三区| 日本人亚洲人jjzzjjz| 色综合久久中文综合久久97 | 九九热hot精品视频在线播放| 日韩精品久久一区二区| 黄页视频在线91| 韩国一级黄色录像| 欧美精品亚洲二区| 黄视频网站在线看| 亚洲一区二区三区视频| 亚洲天堂一区二区三区四区| 奇米影视四色在线| 国产精品久久久久久久久晋中| 中文字幕日韩国产| 深夜福利国产精品| **国产精品| 干日本少妇视频| 国产乱码一区二区三区| 欧美日韩在线视频免费播放| 日韩免费视频线观看| 91超碰免费在线| 久久天天狠狠| 视频一区视频二区中文| 成年人网站免费在线观看| 欧美性精品220| 国产爆初菊在线观看免费视频网站| 国产成人精品综合| 色喇叭免费久久综合网| 在线不卡一区二区三区| 亚洲人成网站在线| 蜜臀久久久久久999| 欧美怡红院视频一区二区三区| 色88888久久久久久影院| 国产精品久久久久9999小说| 国产精品国产三级国产a| 亚洲精品视频专区| 国产91精品久久久| 日韩影院二区| 国产资源中文字幕| 午夜影视日本亚洲欧洲精品| 欧美女优在线| 国产精品天天狠天天看| 欧美高清不卡| 欧美一区二区三区成人精品| 欧美主播一区二区三区| 最新国产在线拍揄自揄视频| 国产一区二区三区黄| 日韩高清电影一区| 国产大片免费看| 亚洲精品第一国产综合精品| 日韩欧美2区| 日韩一级片一区二区| 久久婷婷综合激情| 国产麻豆精品一区| 18久久久久久| 亚洲欧美综合久久久| 三级电影在线看| 欧美日本精品一区二区三区| 国精产品一区一区三区mba下载| 欧美日韩在线一区二区三区| 国产精品资源在线看| 久久国产视频精品| 九色精品免费永久在线| 黄色不卡一区| 黑森林av导航| 欧美日韩精品一区二区三区四区 | 成年人免费观看视频网站 | 日本福利在线观看| 成人在线观看视频网站| 另类天堂av| 精品无码久久久久| 久久人人爽人人爽人人片亚洲 | 伊人伊成久久人综合网小说| 一区中文字幕| 一区二区三区四区毛片| 色先锋aa成人|