在 Java 中構(gòu)建高效 REST API 的四大關(guān)鍵技巧

作者:jiasheng · 2024-10-14 · 閱讀時(shí)間:7分鐘
本文將提供四個(gè)關(guān)鍵技巧,以改進(jìn) REST API。假設(shè)已經(jīng)熟悉 Richardson 成熟度模型,尤其是達(dá)到 2 級(jí),這是良好 API 的最低要求。

提升 Java REST API 的關(guān)鍵技巧

在使用 Java 創(chuàng)建可靠的 REST API 時(shí),不僅需要對(duì) HTTP 請求和響應(yīng)有基本了解,還需確保 API 設(shè)計(jì)良好、可維護(hù)且安全。本文將提供四個(gè)關(guān)鍵技巧,以改進(jìn) REST API。假設(shè)已經(jīng)熟悉 Richardson 成熟度模型,尤其是達(dá)到 2 級(jí),這是良好 API 的最低要求。如需快速了解理查森成熟度模型,建議閱讀 Martin Fowler 的文章《理查森成熟度模型》。

在了解上述先決條件后,接下來將深入探討這些技巧。為便于說明,以下示例來自探險(xiǎn)領(lǐng)域。盡管不會(huì)詳細(xì)探討實(shí)體和層,但假設(shè)存在以下實(shí)體類:

public class Expedition {
    private String name;
    private String location;
    private LocalDate date;

    public Expedition(String name, String location, LocalDate date) {
        this.name = name;
        this.location = location;
        this.date = date;
    }

    public String getName() {
        return name;
    }

    public String getLocation() {
        return location;
    }

    public LocalDate getDate() {
        return date;
    }
}

術(shù)語和資源命名的一致性

設(shè)計(jì)良好的 REST API 的關(guān)鍵之一是確保術(shù)語的一致性,并仔細(xì)關(guān)注服務(wù)的詞匯。首先應(yīng)遵循通用命名約定,然后再向更具體的術(shù)語細(xì)化。可以借助領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)原則,從主域出發(fā),逐步細(xì)化到子域。

一個(gè)簡單的經(jīng)驗(yàn)法則是使用復(fù)數(shù)名詞表示資源,例如:

  • GET /expeditions – 返回所有探險(xiǎn)
  • GET /expeditions/{id} – 通過 ID 檢索特定探險(xiǎn)

示例代碼:

@Path("expeditions")
public class ExpeditionResource {

    @GET
    public List<Expedition> list() {
        // 實(shí)現(xiàn)代碼
    }

    @GET
    @Path("/{id}")
    public Expedition get(@PathParam("id") String id) {
        // 實(shí)現(xiàn)代碼
    }

    @GET
    @Path("/search")
    public List<Expedition> mine() {
        // 實(shí)現(xiàn)代碼
    }
}

有關(guān)保持一致性的更詳細(xì)指南,請參考《REST API 設(shè)計(jì)規(guī)則手冊》。

可維護(hù)性、可擴(kuò)展性和文檔

隨著 API 的復(fù)雜性不斷增加,維護(hù)和擴(kuò)展變得至關(guān)重要。確保可維護(hù)性的一種有效方式是提供適當(dāng)?shù)奈臋n。盡管文檔可能不是許多開發(fā)人員最喜歡的任務(wù),但它是不可或缺的。OpenAPI 是一個(gè)優(yōu)秀的工具,能夠自動(dòng)生成和增強(qiáng)文檔。欲了解更多信息,請?jiān)L問 OpenAPI。

另一個(gè)關(guān)鍵方面是版本控制。版本控制可以確保向后兼容性,并實(shí)現(xiàn)不同 API 版本之間的平滑過渡。它允許同時(shí)支持新舊版本,從而鼓勵(lì)用戶在方便時(shí)遷移到最新版本。在 Java 中,可以通過為每個(gè)版本使用單獨(dú)的包構(gòu)建代碼,并創(chuàng)建適配器層來管理版本之間的交互,來實(shí)現(xiàn)這一點(diǎn)。

示例:

package os.expert.demo.expeditions.v1;

@Path("/api/v1/expeditions")
public class ExpeditionResource {
    // 實(shí)現(xiàn)代碼
}

package os.expert.demo.expeditions.v2;

@Path("/api/v2/expeditions")
public class ExpeditionResource {
    // 實(shí)現(xiàn)代碼
}

安全性:永遠(yuǎn)不要信任用戶

安全性是任何 API 的基本組成部分。一般原則是永遠(yuǎn)不要信任用戶;始終驗(yàn)證其訪問所請求資源的權(quán)限。采用身份驗(yàn)證的方法,可以確定用戶可以訪問哪些探險(xiǎn),而無需依賴用戶提供的 ID。

示例:

@GET
@Path("/my-expeditions")
public List<Expedition> myExpeditions() {
    // 用戶已通過身份驗(yàn)證,無需請求 ID
    // 實(shí)現(xiàn)代碼
}

這一原則同樣適用于編輯或刪除資源等其他操作。在繼續(xù)執(zhí)行之前,務(wù)必驗(yàn)證權(quán)限。

異常處理與正確的 HTTP 狀態(tài)代碼

設(shè)計(jì)良好的 API 應(yīng)具備強(qiáng)大的異常處理機(jī)制,將錯(cuò)誤映射到正確的 HTTP 狀態(tài)代碼。例如,如果未找到探險(xiǎn),API 應(yīng)返回 404 Not Found 狀態(tài),以確保 Java 代碼與 REST API 語義之間的一致性。

示例:

@Provider
public class ExpeditionNotFoundExceptionMapper implements ExceptionMapper<ExpeditionNotFoundException> {

    @Override
    public Response toResponse(ExpeditionNotFoundException exception) {
        return Response.status(Response.Status.NOT_FOUND)
                       .entity(exception.getMessage())
                       .build();
    }
}

結(jié)論

總之,創(chuàng)建可靠的 REST API 涉及幾個(gè)關(guān)鍵步驟:

  1. 了解基礎(chǔ)知識(shí):熟悉理查森成熟度模型。
  2. 使用一致的術(shù)語:遵循清晰一致的資源命名約定。
  3. 關(guān)注可維護(hù)性和文檔:使用 OpenAPI 等工具實(shí)施版本控制并生成文檔。
  4. 優(yōu)先考慮安全性:始終驗(yàn)證用戶權(quán)限。
  5. 實(shí)施正確的異常處理:確保 API 返回適當(dāng)?shù)?HTTP 狀態(tài)代碼。

通過遵循這些技巧,能夠順利地使用 Java 開發(fā)可靠且可維護(hù)的 REST API,即使是經(jīng)驗(yàn)豐富的開發(fā)人員也可能面臨這一挑戰(zhàn)。

原文鏈接:Four Essential Tips for Building a Robust REST API in Java