記錄--這個前端Api管理方案會更好?

来源:https://www.cnblogs.com/smileZAZ/archive/2023/10/30/17798496.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 簡介 大家好,前端小白一枚,目前接觸後臺管理系統比較多,經常遇到不同對象的增刪改查的介面,如何對Api進行一個有比較好的管理是個問題。在學習偏函數的時候有了靈感,想到一個不錯的API管理方案,並應用在項目一個模塊當中,並且開發效率和維護性 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

簡介

大家好,前端小白一枚,目前接觸後臺管理系統比較多,經常遇到不同對象的增刪改查的介面,如何對Api進行一個有比較好的管理是個問題。在學習偏函數的時候有了靈感,想到一個不錯的API管理方案,並應用在項目一個模塊當中,並且開發效率和維護性可讀性都很不錯,和大家分享一下~

當前項目的前端API管理方案

// 封裝的介面
export function obj1Func1(){}
export function obj1Func2(){}
export function obj2Func3(){}
export function obj2Func4(){}

// 引入方式
import { obj1Func1, obj1Func2, obj2Func3, obj2Func4 } from 'xxx'

// 使用方式
const params = {...}
await obj1Func1(params)

當介面多了之後,我們管理介面(查找)是一件很麻煩且廢眼睛的事,需要一直翻,註釋看不過來,維護性和可讀性差。

統一export方式

// 封裝的介面
function obj1Func1(){}
function obj1Func2(){}
function obj2Func3(){}
function obj2Func4(){}
// 導出介面
export {
    obj1Func1,//註釋
    obj1Func2,//註釋
    obj2Func3,//註釋
    obj2Func4,//註釋
    ...
}

// 引入方式
import { obj1Func1, obj1Func2, obj2Func3, obj2Func4 } from 'xxx'

// 使用方式
const params = {...}
await obj1Func1(params)

優點

  • 面向對象,不需要每個介面函數都引入,開發時調用方便
  • 簡化操作類型命名,如update -> upd,開發和維護方便

缺點

  • 當模塊涉及的對象很多,則需要建立非常多的文件,當文件名複雜時,難以看懂維護難度up。
  • 當頁面需要引入多個對象,需要引入一個個文件,降低開發效率。
  • 找對象需要拖拽到文件最底部

以面向模塊(對象)的方式

假設當前模塊下涉及到 n 個對象及對應的增刪改查介面, 定義一個映射表

// api映射表
const apiMap = {
    // 公共介面
    common: {
        commonFun1,
        commonFun2,
    },
    //對象1
    dog: {
        //增刪改查
        add: obj1Func1
        get: obj1Func2
    },
    //對象2
    cat: {
        //增刪改查
        upd: obj2Func3,
        del: obj2Func4,
    },
    ...
}

apiMap 對象

一級鍵名是模塊涉及的對象
二級鍵名是對象相關的操作類型,值是對應的介面函數

導出方式1

直接導出各個對象

export default {
    commonApi: apiMap['common'],
    dogApi: apiMap['dog'],
    catApi: apiMap['cat'],
}

import {commonApi,...} from "xxx"

面向模塊(多個對象)

本質就是以對象的方式來進行管理,只不過這裡面向的是模塊。這裡一個模塊只對應一個文件,包含了涉及到的n個對象的介面。因為我覺得一個模塊下建n個對象一長串的Api文件,又沒法對文件名註釋(文件名總有不認識或拼接的單詞吧)只會帶來更大的維護困難

找了幾個不常見的英語名詞,英語爛仔直接帶上痛苦面具
而有了映射表就相當於有了一個目錄(文件最上方一目瞭然, Map下的對象十分清晰還有註釋),
至少目前我是能都秒讀懂介面含義了
也不會出現面對老項目里那種長得拖不完的不知名介面文件的懵逼,點進去還只有幾行代碼(雪花飄飄~)

優點:

  • 同上
  • apiMap變成介面目錄,可讀性和可維護性提高(下方介紹)
  • 涉及同模塊多個對象只需要引入一個文件

缺點:

  • apiMap(目錄)和export的位置一個在文件最上方,一個在最下方,瀏覽時非常不方便,依舊需要經常拖拽

這種方式已經比較好用了,從可維護性和可讀性,拓展性來看我更推薦第二種方式

導出方式2

導出一個訪問映射表的函數,參數是對象及操作類型,如(dog, upd)

// 暴露一個訪問api映射表的函數, 參數是對象和操作
// 這裡沒有錯誤處理,jym看懂就行
export default function api(obj, action) {
    if (action) {
        // 返回某對象某操作的介面函數,如dogUpdate
        return apiMap[obj][action]
    }
    // 返回一個包含多個操作介面函數的對象或公共介面
    return apiMap[obj]
}

// 封裝的介面
function obj1Func1(){}
function obj1Func2(){}
function obj2Func3(){}
function obj2Func4(){}
使用時方式1
import API from 'xxx'
// 沒有錯誤處理,主打看懂
async function getData() {
    const params = {...}
    const data = await API(obj1, 'get')(params)  
    await API(obj1, 'upd')(params)
    await API(obj1, 'del')(params)
}
使用時方式2
import API from 'xxx'
const obj1API = API(obj1)

const data = await obj1API.get(params)  
const data = await obj1API.upd(params)  
const data = await obj1API.del(params)  

api函數

api函數可以複製或者寫在公共模塊引入就行了,實際上工作量只在維護映射表apiMap

現在查找介面原本一個模塊里可能涉及10個對象共100個介面,順序查找最差情況要看100條函數註釋,而根據對象查找最差情況是10(對象)+10(操作類型)即20條函數註釋。

const apiMap = {
    ...
    // 註釋:這是target對象
    targetObj: {
        add: objAddFunc, // 註釋:增刪改查的話可有可無
        upd: objUpdateFunc,
        del: objDeleteFunc,
        get: objGetFunc,
    }
    ...
}

只需要關註目標對象(其實是註釋),清晰且一目瞭然,甚至不需要函數註釋,不需要拖到文件底部

可維護性和可讀性

模塊化

這種方式用對象結構拆分也算是模塊化了,看著不太習慣,但一個文件里對象和介面能都讀懂,維護性和可讀性也更好,即便介面函數再多行數再多,其實也只需要看apiMap

封裝

(接下來開始胡扯~)

api函數封裝了一層,可以統一管理介面提高拓展性和復用性,例如統一給actionget的套一個節流函數

// 暴露一個訪問api映射表的函數, 參數是對象和操作
// 這裡沒有錯誤處理,jym看懂就行
export default function api(obj, action) {
    if (action) {
        if (action === "get") {
          return throttle(apiMap[obj][action], 500); // 設置節流時間為 500 毫秒,期間返回空函數
        }
        return apiMap[obj][action]
    }
    // 返回一個包含多個操作介面函數的對象或公共介面
    return apiMap[obj]
}
或者當模塊下有多個對象需要增刪改查,且只需要一個參數id,那麼只要再加個定製場景的api函數
// 偏函數固定參數,這裡constParams假設為 { id:007 }
export function paramsApi(constParams, obj) {
    // otherParams是額外參數,在各自介面做個合併Object.assign()
    return (action, otherParams) => apiMap[obj][action](otherParams)
}
// 固定參數
const constParams = { id: 007 }
const dogApi = paramsApi(constParams, 'dog')
const catApi = paramsApi(constParams, 'cat')
// 免參數直接調用即可
dogApi('get')
dogApi('update', { color: 6 })
dogApi('delete')
catApi('get')
catApi('update', { color: 6 })
catApi('delete')

這個場景有些理想化,但有一層封裝也確實能夠在需要時方便統一管理

然後這裡 action: objActionFunc這裡也算是一層封裝,方便進行命名簡寫和規範

// xxxModule.js
const apiMap = {
    //對象1
    obj: {
        action: objActionFunc
        add: dogAdd,   // xxx/dog/add
        mAdd: dogImport,   // xxx/dog/import
        upd: dogUpdate,   // xxx/dog/update
    },
}

開發體驗

和同事溝通後,我應用在項目的一個模塊中,感覺很棒!

首先寫介面引入公共模塊的api函數,定義apiMap映射表,正常寫介面,工作量多了一個apiMap罷了

// 引入api,getType函數
import { api } from "common"
// api映射表
const apiMap = {
    ...
}
// 暴露api函數
export default api
// 封裝的介面
...
開發時查找介面就全程對著文件最上方的映射表複製,基本不需要怎麼拖拽,不需要切換文件去找其他對象,也不需要看一堆無關代碼,全程看註釋,大大降低心智負擔,小白上手也能分分鐘找到
// xxxModule.js
const apiMap = {
    //對象1
    dog: {
        add: xxx
        get: xxx
    },
    //對象2
    cat: {
        upd: xxx,
        del: xxx,
    },
}
引入介面時只要一個API函數,調用方式基本大差不差吧,反正都是copy,然後改下操作類型
import API from "@/api/xxx/xxxModule"

// 調用時, 兩種方式,複製個對象名,記住個操作類型,完事
const dogAPI = API('dog')
const catAPI = API('cat')

await dogAPI.get(params)
await dogAPI.upd(params)
await catAPI.get(params)
// 或
await API('dog', 'get')(params)
await API('dog', 'upd')(params)
await API('cat', 'get')(params)

開發效率我覺得和對象方式的API管理方案沒啥區別,都是copy然後改下操作類型,但其實最大的好處還是在可維護性和可讀性上

寫在最後

非常感謝看到最後的jym,這是我本0前端小白通過偏函數產生的一點小想法,感覺挺好用的分享一下(可能場景比較簡單局限後臺系統),歡迎jym多多指點發表建議(玻璃心

本文轉載於:

https://juejin.cn/post/7290558277666930744

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 可能有幾種原因導致這種情況。以下是一些常見的問題和可能的解決方法: 證書驗證問題: 當你使用mitmproxy抓包時,它通常會生成自簽名的SSL證書,以便進行中間人攻擊檢查。但在Python中使用requests庫時,預設情況下,它會驗證SSL證書的有效性。你需要禁用SSL驗證,以便使用mitmpr ...
  • 背景 由於我個人電腦是2020款m1,16G,256G。一方面,平時除了運行多個瀏覽器,還有coding 編輯器等等,記憶體確實很緊張。其次呢,m1 是ARM的架構,所以構建的鏡像是無法在X86的機器上運行的。所以我嘗試將docker引擎和client分開。 第一步:下載二進位docker 客戶端文件 ...
  • Tabby是一個開源免費軟體,支持Windows、macOS和Linux系統。它提供了一個高度可定製的終端界面,可以通過多種方式添加、切換和關閉終端標簽頁。能與 Linux 伺服器輕鬆傳輸文件,支持多種主題,界面炫酷,插件豐富。它還支持通過插件擴展其功能,例如增強的滾動條、批量複製和粘貼等功能。 ...
  • 1. Groovy 1.1. Java編程語言的一個超集 1.2. Gremlin Console的一個特性是能和Groovy配合使用 1.2.1. Gremlin Console會自動地迭代結果 1.3. 從技術上說,Gremlin Console就是Groovy互動式解釋器(read-eval- ...
  • 抄襲轉載的太多,請認準原文鏈接:xtrabackup 的介紹與使用 前言 在網上找到教程都是複製粘貼抄襲的,而且還是陳舊資料,不得不說,當前中文互聯網環境真是每況愈下。 如果你在網上找 xtrabackup 的教程,大概率會為你介紹 innobackupex。但在最新的 2.4 版本中,innoba ...
  • 本文核心內容聚焦為什麼要埋點治理、埋點治理的方法論和實踐、奇點一站式埋點管理平臺的建設和創新功能。讀者可以從全局角度深入瞭解埋點、埋點治理的整體思路和實踐方法,落地的埋點工具和創新功能都有較高的實用參考價值。 ...
  • 本篇文章來源於 ByteHouse 產品專家在火山引擎數智平臺(VeDI)主辦的“數智化轉型背景下的火山引擎大數據技術揭秘”線下 Meeup 的演講,將從 ByteHouse 資料庫架構演進、增強 HaKafka 引擎實現方案、增強 Materialzed MySQL 實現方案、案例實踐和未來展望四... ...
  • 前端標簽 標簽的分類 1. 單標簽 img br hr <img /> 2. 雙標簽 a h p div <a></a> 3. 按照標簽屬性分類 1. 塊兒標簽 # 自己獨自占一行 h1-h6 p div 2. 行內(內聯)標簽 # 自身文本有多大就占多大 a span u i b s div標簽和 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...