如何快速打造一款釘釘 Go sdk


事情並不簡單

開發須要用到釘釘開放平臺提供的接口,可是釘釘官方並無提供 Go 語言版本的 sdkgit

在 GitHub 逛了一圈後,找不到滿意的開源版本,有些 repo 設計不太規範,有些 repo 只實現了部分功能github

因而,我決定親手擼一個web

但很快,我就發現事情並不簡單:釘釘開放平臺提供了超過 200 個接口!c#

開發一個完整的 sdk 須要閱讀每個接口的文檔,理解各個參數的做用,處理各類異常和接口返回的結果,還有 access_token 管理、數據加解密等細節api

即便是資深開發工程師,在這髒活累活上,恐怕也得耗上半個月的時間服務器

太慢了,這不是我想要的微信

快就一個字

通過 30 分鐘仔細閱讀接口文檔後,我發現了一些規律:架構

  • 服務器地址都是 https://oapi.dingtalk.com/
  • HTTP 請求方法都是 POST 或 GET
  • 全部的請求都須要 access_token 參數
  • 官方文檔針對每個接口都詳細列出了接口簡介、接口地址、Query 參數、Body 參數
  • ...

一個不太成熟的小想法就浮現出腦海:app

  • 搞個爬蟲抓取接口名稱、接口簡介、接口地址、Query 參數、Body 參數 等 API 元信息
  • 一個 API 的規格由其元信息惟必定義
  • 每一個 API 都由一個 func 表示
  • params url.Values表示接口須要的Query 參數
  • payload []byte表示接口須要的Body 參數
  • resp []byte表示接口的返回內容
  • 根據 API 分組狀況,拆分 package
  • 全部 API 請求由統一的 Http Client 模塊處理
  • access_token、錯誤處理和重試邏輯由 Http Client 模塊處理
  • 釘釘服務器發出回調由 Http Server 模塊處理
  • ...

至此,一個簡潔但完整的架構呼之欲出:編輯器

咱們將打造這樣一款 sdk : 介於業務邏輯 和 釘釘 之間,將業務的指令發送到釘釘,將釘釘的響應透傳給業務

魔鬼在細節

按照上 part 咱們的構想,就能夠開始搞了

先看看釘釘文檔頁面結構:

啓動爬蟲抓回來接口元信息:

Api{
    Name: "獲取用戶userid",
    Description: "經過免登受權碼和access_token獲取用戶的userid。",
    Request: "GET https://oapi.dingtalk.com/user/getuserinfo?access_token=access_token&code=code",
    See: "https://ding-doc.dingtalk.com/doc#/serverapi2/clotub",
    FuncName: "GetUserInfo",
    GetParams: []Param{
        {Name: `code`, Type: `string`},
    },
}

格式化成 Go func

package auth

import ...

const apiGetUserInfo = "/user/getuserinfo"

/*
獲取用戶userid

經過免登受權碼和access_token獲取用戶的userid。

See: https://ding-doc.dingtalk.com/doc#/serverapi2/clotub

GET https://oapi.dingtalk.com/user/getuserinfo?access_token=access_token&code=code
*/

func GetUserInfo(ctx *dingding.App, params url.Values) (resp []byte, err error) {
    return ctx.Client.HTTPGet(apiGetUserInfo + "?" + params.Encode())
}

再搞個 testexample 的模板代碼,當爬蟲所有執行完後,咱們就能夠獲得:

├─ai
│      ai.go
│      ai_test.go
│      example_ai_test.go

├─alitrip
│      alitrip.go
│      alitrip_test.go
│      example_alitrip_test.go

├─attendance
│      attendance.go
│      attendance_test.go
│      example_attendance_test.go

......

Wow Amazing! 200 個接口已盡入吾彀中矣

不過,咱們時間很少了:

  • 部分接口文檔頁面不規範,致使爬蟲中斷了 20 分鐘
  • GET|POST 不一樣類型的請求測試函數的差別比較大,耗費了 40 分鐘
  • ...

access_token 管理

全部接口調用最終都由統一的 Http Client 模塊發起

因爲每一個接口調用都須要鑑權,因此咱們把鑑權模塊放在這裏再好不過了

處理方式很是簡單,拿到access_token,加到請求地址後便可:

accessToken, _ := client.Ctx.AccessToken.GetAccessTokenHandler()

newUrl := url + "?access_token=" + accessToken

關鍵在 GetAccessTokenHandler方法,這裏定義瞭如何獲取 access_token

試一試

再處理一下其餘細節,包括錯誤處理、單元測試等,咱們的 sdk 就差很少搞定啦

如今到了 Eating your own dog food環節:

go get github.com/fastwego/dingding
// 建立應用實例
app := dingding.NewApp(dingding.AppConfig{
    AppKey: viper.GetString("AppKey"),
    AppSecret: viper.GetString("AppSecret"),
})

// 調用 api
params := url.Values{} 
params.Add("code", CODE)
resp, err := auth.GetUserInfo(app, params)

若是一切正常的話,接口能夠正確響應咱們的請求

效果好極啦,調用簡單,不只有 Example 引導,還有文檔和連接:

果真仍是本身打造的工具最趁手

纔剛剛開始

在一樣的思路下,我又擼完了企業微信和飛書的 Go sdk

  • https://github.com/fastwego/wxwork
  • https://github.com/fastwego/feishu

to be continue ...



本文分享自微信公衆號 - 追馬Linux(zhuima_k8s)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索