日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

某小公司 RESTful、共用接口、前后端分离、接口约定的实践

發布時間:2025/3/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 某小公司 RESTful、共用接口、前后端分离、接口约定的实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

隨著互聯網高速發展,公司對項目開發周期不斷縮短,我們面對各種需求,使用原有對接方式,各端已經很難快速應對各種需求,更難以提高效率。于是,我們不得不重新制定對接規范、開發邏輯以便快速上線項目。

我們的目標

  • 盡可能的縮小溝通的成本,開最少的會,確定大部分的事。

  • 花最少的時間寫文檔,保證90%的開發人員看懂所有內容。

  • 哪怕不看文檔,也能知道各種接口邏輯。

  • 不重復寫代碼

  • 盡可能的寫高可讀性的代碼

  • 我們做了哪些事

  • 完成了前后端分離

  • Android、ios、web共用一套接口

  • 統一接口規范(post、put、get、patch、delete)

  • 統一了調試工具

  • 統一了接口文檔

  • 之前的我們

    接口是這樣子的:

    接口地址含義請求方式
    …/A項目/模塊1/getProducts獲得產品GET
    …/A項目/模塊1/addProduct添加產品POST
    …/A項目/模塊1/getProductDetail獲得產品詳情GET
    …/A項目/模塊1/editProduct修改產品POST

    客戶端請求是這樣的:

    • …/A項目/模塊1/getProducts?id=1&a=2&b=3&c=4&d=5…………

    • A頁面=====》B頁面(攜帶n個變量)====》C頁面(攜帶m個變量,包含i個A頁面的變量) -------經常n>4

    • 大部分請求是POST,至于put、patch、delete是什么鬼,關我屁事。

    • 關于接口入參使用json,那完全是看開發心情。

    出參是這樣的:

    {"message":"success","code":0,"data":具體內容}
    其中data里包含數組可能是
    [{"a":"1","b":"1"},{"a":"1","b":"1"},{"a":"1","b":"1"},{"a":"1","b":"1"}]
    即使下一個頁面用到也不會使用id,而是把所有字段都傳進去。
    A接口中,返回產品用product;B接口中使用good,多個接口很可能不統一。

    客戶端對接是這樣子的:

    • 安卓、ios一套;部分接口各自用一套;html5端一套。

    • 客戶端和后臺是不停交流的

    接口文檔是這樣的

  • swagger

  • 阿里的rap

  • Word文檔

  • 其它

  • 當然了,我覺得swagger和rap神器都是非常強大的,能夠實現各種功能邏輯,但是考慮到開發人員掌握程度不通,復雜度較高,難以提高效率,我決定初期并不使用這兩樣神器。

    后端是這樣的

    …/A項目/模塊1/getProducts ----接口
    …/A項目/模塊1/Products.html ----頁面
    …/A項目/模塊1/Products.js ----靜態資源

    接口和靜態資源纏在一塊,畢竟很多頁面可能是一位開發人員同時開發前端、后端,這里的弊端是,只需要自己清楚邏輯,很多做法臨時應付,方案并不優雅,別人也很難看懂。一旦這位同事離職,很多說不清的邏輯就留給后人采坑了。

    等等…………

    ?

    重構

    下面步入正題,面對以上眾多問題聊聊我是如何重新制定流程的

    數據庫約定

    約定數據庫里所有表必須包含名為id主鍵字段。
    可能有人會說,正常來說不是每張表里都應該有id主鍵嗎?但是,我們項目中由于之前開發不嚴謹,部分表沒有id主鍵,或者不為id的主鍵。這里我們采用分布式的全球唯一碼來作為id。

    api出參約定

    約定所有出參里含list,且其他請求會用到這組list,則list里所有對象必須含id唯一標識。

    入參約定

    約定token身份認證統一傳入參數模式,后端采用aop切面編程識別用戶身份。其他參數一律為json。

    resultfull接口約定

    首先我們選擇一個名詞復數,比如產品

    post方法

    新增一條XXX
    比如 ……/products 則代表新增一條產品
    入參json如下:

    {"name":"我是一款新產品","price":100,"kind":"我的分類","pic":[一組圖片],等等還有很多}

    java 代碼controller層

    ????@ResponseBody@RequestMapping(value?=?"/A項目/B模塊/products",?method?=?{RequestMethod.POST})public?ResultObject?getProducts()?{//具體邏輯。}

    put方法

    新增某條XXX記錄
    比如 ……/products/1111111111
    入參json如下:

    {"name":"我是一款新產品","price":100,"kind":"我的分類","pic":[一組圖片],等等還有很多}

    表示增加一條1111111111id的記錄
    java代碼controller層

    ????@ResponseBody@RequestMapping(value?=?"/A項目/B模塊/products/{id}",?method?=?{RequestMethod.PUT})public?ResultObject?putProducts(@PathVariable(value?=?"id")?String?id)?{//具體邏輯。}

    get方法

    獲得所有XXX
    ……/products 則代表獲取所有產品
    因為有分頁,所以我們后面加了?page=1&pageSize=50

    我們約定了所有名詞復數,都會返回list,且list每個對象都有字段為id的唯一id。
    比如

    {"data":{"list":[{"id":"唯一id","其他很多字段":""},{"id":"唯一id","其他很多字段":""}],"page":1,其他字段},"code":0,"message":"成功" }

    ……/products/{id} 獲取某個具體產品(一定比列表更詳細)

    比如某個具體產品里還包含一個list,如該產品推薦列表,則:
    ……/products/{id}/recommendations

    假設它包含的不是一個list,而是對象,比如產品傭金信息,則:
    ……/products/{id}/Commission

    這里我們以是否名詞復數來判斷是對象還是list.

    java代碼controller層

    ????@ResponseBody@RequestMapping(value?=?"/A項目/B模塊/products/{id}",?method?=?{RequestMethod.GET})public?ResultObject?putProducts(@PathVariable(value?=?"id")?String?id)?{//具體邏輯。}

    patch 方法

    更新局部XXX產品YYY信息
    入參是post方法時入參的子集,所有支持更新的參數會說明,并不是支持所有變量
    ……/products/{id}

    {"name":"我是一款新產品","price":100,部分變量 }

    java代碼control層

    ????@ResponseBody@RequestMapping(value?=?"/A項目/B模塊/products/{id}",?method?=?{RequestMethod.PATCH})public?ResultObject?putProducts(@PathVariable(value?=?"id")?String?id)?{//具體邏輯。}

    delete方法

    刪除XXX記錄
    ……/products/11111

    刪除11111產品。
    java代碼controller層

    ????@ResponseBody@RequestMapping(value?=?"/A項目/B模塊/products/{id}",?method?=?{RequestMethod.DELETE})public?ResultObject?putProducts(@PathVariable(value?=?"id")?String?id)?{//具體邏輯。}

    其他說明

    我們盡可能少的使用動詞,但有一些行為需要使用動詞,比如登錄等。
    關于版本號,我們打算在模塊后增加/v1/等標識。

    權限約定

    服務端要對用戶角色進行判斷,是否有權限執行某個邏輯。

    前后端分離約定

    后端以開發接口為主,不再參與頁面開發,或者混合式jsp頁面開發,統一以接口形式返回,前端通過js渲染數據以及處理邏輯。

    共用接口

    web、Android、ios使用統一接口,不在因為哪方特殊要求額外開放接口。

    使用統一dao層生成工具

    基于mybatis-generator改造成適合我們項目的dao層以及部分service層,內部共同維護共同使用。

    使用postman最為接口文檔、調試工具

    雖然有上文中介紹的rap和swagger都是特別牛的接口神器,但是我們還是選擇了postman,開發人員將接口名稱、說明、入參、出參,以及各種出參示例都存儲,這樣開發直接可以看得清接口含義。

    我們建議使用瀏覽器插件,這里以360極速瀏覽器為例。
    插件下載地址:https://download.csdn.net/download/qq273681448/10033456

    打開360瀏覽器擴展中心,然后勾選開發者模式,再點擊加載已解壓的擴展程序,選中壓縮包解壓后的目錄,最后點擊運行即可。

    其中出參注釋、及接口說明,寫在tests里:

    /* 這里是接口說明,和每個出參、入參的意思。 */

    接口按模塊劃分為文件夾:

    入參:

    出參示例:

    正常請求:

    開發人員即可直接看到接口示例進行開發,而開發人員開發的時候,自己調用一次即可保存為postman文件,為了加快上線,我們允許將java中實體類變量定義的代碼(含注釋)直接復制粘貼出來。

    js等靜態資源緩存問題

    從短期角度上講,我的要求是減少js文件的變更,如果有變更,務必更改版本號。那么如何減少修改,我們的做法是將一部分js寫在html內,反正前后端分離,大不了刷新一下cdn的節點緩存,畢竟大部分瀏覽器也不會主動緩存html文件(大部分瀏覽器會緩存js等文件)。

    統一js請求框架

    這里我們使用angular js的請求框架,因為我們內部對angularjs使用較多,比較熟悉,封裝后的請求,可以自動彈窗錯誤請求,可復寫錯誤回調。

    目前效果

    目前,我們客戶端看到接口,大概能說出其意思,也能猜出一連串接口的含義,比如
    ……/classes
    可以看出它是獲取班級列表接口,猜到

    ……/classes/id get獲取id為id的班級詳情
    ……/classes/id patch 修改班級信息
    ……/classes/id delete 刪除班級信息

    至于入參,patch是post的子集、put=patch、delete無入參。

    而入參含義,直接打開postman可以直接查看每個字段的含義,并且,可以實時調取開發環境數據(非開發人員電腦),這里我們使用了多環境,詳情可了解我之前寫的一篇
    我是如何重構整個研發項目,促進自動化運維DevOps的落地?

    前端使用統一封裝后的js請求框架也加快了開發進度,不用造輪子。

    開發人員,一般代碼開發寫好,使用postman自我測試,測試完成后,接口文檔也就寫好了。

    測試人員想了解接口文檔的也可以直接使用postman進行導入查看。

    至此,我們交流成本下降了一大半,剩下開會的內容就是按ui分解需求或者按ui施工了。

    總結

    經過一番的折騰,開發進度總算快了點,也一定程度上達到了快速上線項目的效果。關于restful風格api,每個人都有自己的見解,只要內部約定清楚,能盡可能少的減少溝通,我覺得就是好的理解。至于接口工具,可能很多人會說為什么不用之前的,我覺得以后還是會用的,最好能做到插件自動化生成api,但是對java開發注釋要求比較嚴格,隨意慢慢來吧,畢竟后面我們還有很多路要走。

    總結

    以上是生活随笔為你收集整理的某小公司 RESTful、共用接口、前后端分离、接口约定的实践的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。