[ECUG專題回顧]《BEEGO設計理念與API開發》-謝孟軍 (BEEGO作者、GO WEB編程作者)

原文:http://blog.qiniu.com/archives/1048

謝孟軍:大家好,我是謝孟軍,我是beego作者。今天我來講一下beego的設計理念和API開發,大家有聽過beego的嗎?有用beego在自己項目裏面做嗎?OK,今天的大綱就大概講一下是這樣,首先我要講一下什麼是beego,然後講一下beego的設計理念,裏面有很多的模塊,每一個模塊怎麼樣設計的,可能會牽涉到一些GO設計的東西,然後講一下插件化的東西,最後講一下API的開發。我個人比較看好Go在API方面應用的開發,當然Go用來開發Web也是OK的,但是沒有用PHP開發那麼方便,但是開發API的話GO是有很多天生的優勢,所以到時候我會講一下,最後我會用一個最近開發的一鍵式的開發工具,大家現在有很多的數據庫,老闆說要基於這個數據庫做一個API,文檔什麼都要有,我先前因爲在上一家公司做這個東西,因爲公司數據庫表有200多個,讓我做我就要寫的瘋掉了,所以我就寫了這個自動化的工具,可以從數據庫自動的生成所有的API加文檔,而且你還可以自動的生成對應的SDK。比如說PHP應該怎麼調用你的API,因爲它那一整套的生態系統已經全部有了,這就是選擇swagger的原因,所以就可以一鍵式的全部生成基於你數據庫表的API應用加文檔。

 

什麼是beego?beego是我進盛大的時候開始做的。當初我最主要的想法是要用Go做一個類似Python的框架,當開始的時候你會發現所有的方法其實跟Python是一樣的,當初差不多就5個文件,然後我說一個框架也寫好了很方便。剛開始我就是很簡單核心的東西,後面隨着我做的東西越來越多、越來越多,所以我就做了很多的模塊,是有很多豐富模塊的框架,但是現在還是保持着很少的核心,通過不斷的增加模塊、不斷的增加一些庫。

 

第二個因爲基於這樣的設計所以是很鬆偶合的框架,很多的東西都是模塊化、插件,都是很容易去組裝起來的。第三個是文檔比較豐富,因爲我知道很多人開源都是扔一個東西出來,但是後面都是很多文檔都沒跟上。因爲這個是我以前做PHP的時候,那個時候就有很大的經驗,就是說你文檔跟不上你的用戶就會有很多的抱怨問題、很多的反饋,你就不能跟用戶很好的互動,而且又會遇到很多問題,如果文檔跟不上你的框架、你的開源產品就沒辦法很快獲得用戶的認同,第四個是RESTFUL的設計,後來我看了很多路由的方式,最近又自己寫了一個基於多叉樹的路由,我是覺得現在市場上有很多路由庫,例如httprouter號稱性能最好,但是你去用它的功能就是一般的功能,我是覺得beego的路由是現在市場上路由支持最好的,同時性能也是佼佼者。接下來就是強大的Namespace,它可以實現你所有獨立的東西,可以把你的代碼全部獨立成一個模塊,把模塊裏面的路由命名成一個Namespace,這樣你想什麼時候增加前綴都很容易,很方便的進行擴展。接着是自動化的API文檔,這是我最近纔開發,最後就是beego框架除了一個框架之外還有另外一個工具叫Bee工具,Bee能夠迅速的幫你創建一個項目的結構,現在我又增加了一個功能,而且可以基於數據庫自動的給你生成所有的東西,你只要命名好輸入就可以了,基本上80%的邏輯代碼都會幫你完成,你只要核心的邏輯稍微自己再修改一下就OK。

 

beego現在已經有很多的用戶在用,這邊是很多的廠商,最近騰訊穿越火線的遊戲現在後端有一部分也是用beego在做。淘寶和遊戲公司都有,他們內部用的東西還是挺多,盛大我以前用beego做了很多開發的東西,zalora是我在新加坡的公司,beego就是用來開發mobile API應用的。

 

接下來開始講一下beego的設計理念,主要是參考了Unix的設計理念,它有幾個點:第一個是模塊化、第二個是分離、第三個是組合。Unix的思想是你要把所有的事情都弄成一件簡單的事情,把這件簡單的事情做好,同時分離是引擎的分離,這個在Go裏面特別重要,我後面會講到。我們設計的時候GO裏面最好的功能就是interface,而且對你測試案例的時候特別有用,最近就是不斷在迭代開發當中,我越來越覺得interface設計的重要性。當一個應用開發完成的時候,但是整個程序會依賴很多的東西,例如數據庫、搜索引擎等各種系統,如果你設計好了interface,那麼就很容易的mock數據,這樣對於整個的應用的測試用例特別有用。第三個是組合,把這些簡單的事情組合成一個東西,到了重要的是less is more,Go可能更極致一點,少即是指數級的多。

 

beego的設計理念就是樂高的概念,大家有玩過樂高嗎?樂高是很簡單的小小片,可以組成一些部件,這個部件就是所謂beego裏面會弄成一個一個的模塊,最後大家可以把它做成一個很大型的系統,基於這些小的模塊做一個大的系統,這就是我所有的理念,就是組合、分離。beego設計的理念跟前面一樣,就是簡單的內核,我還是一直保持了先前的設計風格,就是很簡單的內核然後豐富的模塊就是做了很多的模塊,當然我學習其他很多成功的框架,Flask、Rails、sinatra,我們會參考它的ORM系統,rails裏面我會參考他的I18N的庫,只要是好的東西像PHP裏面一些框架的設計, 只要好的系統我們就去學習他。然後就是提供強大的開發工具,Bee工具是我自己在實戰當中總結出來的工具,開發中有可能就會碰到很多的問題,所以我很想自動化這些越到的問題,所以開發了這個工具。插件化設計是能夠讓我們的程序動態的擴展,最後是Fast、Fast、Fast第一個是我們要做的東西一定要讓用戶學習的快、開發效率快、運行效率快,所以這邊寫了三個。

 

接下來我簡單的演示一下beego的快速入門。這個命令是安裝Bee工具,裝好之後Bee new mygo。這是我所在gopath的目錄,如果要創建一個目錄就ECUG就可以了,這樣的話會幫你生成一個目錄,我們就可以進入到ECUG了,已經幫你自動的生成了很多東西,如果要運行的話就Bee Run就可以了,就自動幫你監控所有目錄下的文件,只要一修改就可以幫你編譯,你就可以在瀏覽器裏面看到這個東西。這個是beego的默認應用的頁面,這個beego的默認頁面是一個用戶最近貢獻給我們,人家前端寫的比較好幫我們改成這樣,很漂亮。

 

beego主要的模塊現在有這些模塊,就是cache、config、Context、httplib,Logs、Orm,sessions,toolbox,validation這些模塊都是獨立的,就是說不管你做什麼應用假如說拿這個來說,你可以直接拿這個Logs去應用,beego框架不強制你用什麼東西。Go裏面有一個庫有很多獨立的庫,beego我爲什麼沒有把這些東西全部分離出去,因爲很多給我提建議,我應該創建一個新的repo,這樣大家可以重新用,但是這樣的話我就沒辦法保證每一個版本出去的時候系統的穩定性和兼容性,我要保證每一個版本的穩定性,假如說我現在光光升級了Httplibs,假如說我現在依賴於Context的,那我升級了這個,那我還要不要升級beego呢?所以我要保證每一個整體的東西都是穩定的,但是獨立的模塊用戶可以直接去用。

 

Cache設計這就是我參考了Go裏面的database/sql設計,就是interface的分離。我現在支持Get、Put、Delete、Incr,這些所有的東西我定義了一個interface有這些方法,然後Memcache也一樣,這樣就保證網友來不斷的貢獻。這個是獨立的應用,就是說我beego的其他東西都不用,那就是可以Cache.NewCache,然後這些都可以用了。Config的設計現在支持Ini、json、Xml、yaml,Config的應用也是這樣,假如說你用Config的包,那我簡單的就可以Config.NewConfig,然後就是你配置的文件,你就可以獲取一個對象,這個對象返回的是一個interface,你就可以用它的方法來進行操作。Context的設計是這樣,在request和response的基礎之上寫了一些很方便的函數,把它變成了Input、Output,我只是寫了一些好的方法。Output也是一樣,我直接輸入一個Json就可以省去了很多的方法,因爲這邊沒有多引擎的說法,用的話就直接這樣用,就是分的很清。一個是Input進來的數據流,另外一個是我要輸出的數據流。你說Input裏面要獲取用戶輸入的IP這些東西就去Input裏面找,那就有很多的方式和方法讓你獲得這些數據,Output就是我要輸出的東西。

 

Httpliibs是用來模擬客戶端請求,現在支持Https、Debug還有超時支持文件的上傳,這些就很方便。這個是簡單的例子,假如說我要請求這個get的請求,那就是HttpBin.ORG,我要Post的數據就先Httpliibs.Post。Logs和前面的設計是一樣的,就是支持interface引擎的分離,Logs現在支持四種引擎,我支持Cosole、CONN就是網絡,還有File和Smtp,比如說我碰到一個紅色警報我就需要發到我的郵箱裏面報警給我,因爲我這個設計的時候除了interface和引擎的分離之外,同時支持輸出到這四個裏面,因爲我用了channel的方式。每個引擎就訂閱日誌信息,每個引擎可以收到相應的日誌信息,每個引擎又有不同的等級,我要搜到什麼樣的等級就是類似這樣的。File就是支持你按天分、按大小分、保存多少天、保存多少條數這些東西都可以,就是很容易應用的東西性能也很高,因爲你可以自己根據應用來自定義。

 

類似這樣用就是Logs.NewLogger,然後Setlogger就是說我要Set哪些引擎進去,這個是我可以把你調用Logger文件的行數給輸出來,這樣我就可以分析到你調的Logger的行數和文件,這樣的話就有利於你定位那個是哪個文件包出來的,這些是基本的操作,就是Logger不同等級的操作。

 

大家可以看到,我這邊最後寫一個Time Sleep,如果我直接結束掉了可能這一條就沒有輸出,你實際應用的時候需要考慮安全的關閉,我在beego裏面已經幫你考慮了,我會去判斷那裏面是不是已經等於零了,如果不等於零還會輸出,直到你的Logs全部輸出爲止,當然你獨立應用的時候還要注意一下這個問題。

 

ORM的設計,目前支持的數據庫是MySQL、POstgreSQL和Shlite3。ORM的特性第一是支持鏈式的API、支持數據關係,這是我們最引以爲豪的,因爲我們剛開始做的時候是beedb,其實支持了很多的數據庫和引擎,基本上是MSSQL、Oracle這些引擎全都支持了,但是有一個問題是隻是支持單表的,如果關聯了另一個表那是不支持的。所以我那時候就開始考慮,因爲我以前做PHP的時候,我們寫的應用就是關聯數據庫很簡單,我覺得關聯這個是很大的需求,所以我一定要重新寫、重新搞,所以我們開始設計ORM的東西,劉鵬幫我們寫了很多ORM的代碼,他現在應該去七牛了 。

 

Struct我們就支持和Table一對一,簡單的Crud的類型,你定義好直接在裏面幫你把東西創建到你的數據庫表,自動的關聯創建,可以直接使用Rawsql,有時候你很複雜關聯的東西就可以自己去寫、自己去運行,但是返回來我們有很多的函數可以用到Struct,這些代碼都是有完整的測試代碼,就是我們只要github一遞交,在drone那邊全部的CI就會自動運行。

 

CRUD我們看一個例子,我們這邊定義了一個User的結構體,ID、Birthday、Age、Name,我們首先要把它註冊好,因爲我們第一步就是說我們會掃描整個的Struct把它緩存起來,本身Go裏面也不允許這你個結構體動態創建,所以我們就讓你註冊一下,我們就知道你這個結構體是在哪裏的,你的字段都已經OK了,先前我們有做過一個ORM的測試,beegoORM測試的性能最好,我覺得最大的原因就是我們用了緩存的機制。第二個是RegisterDataBase,假如說你有三個數據連接你就可以註冊三個,你需要哪一個的時候就切換到哪一個去用。默認是一個default,這個就是你數據庫的連接地址。

 

這是我們簡單的連接應用,User就是先建一個,然後你再更新就讀取然後再接着就是刪除,很多例子我們的文檔裏面都有,我可以說這個文檔是有但是不夠詳細,很多人都反饋這個問題,我們下一步很多的文檔都會更詳細、說的更明白一點,當然我新加坡有一個同事現在也在寫一本書,因爲以前是做前端的東西,現在也想學beego,他現在把很多學習的步驟給記錄下來,但是我也會指導他一些,這本書裏面什麼都會介紹,因爲有一整套的方案,就是API怎麼設計、JS怎麼調API、用戶權限怎麼弄、數據設計的時候怎麼弄,因爲他是比較有典型性的例子,他現在對beego文檔屬於知道了的級別,但是真正做出項目來整個過程要記錄下來,這樣的話希望對很多的用戶是有用的。

 

Sessios的設計跟前面的設計是一樣,就是interface和引擎的分離。我剛開始其實只是Cookie、File,後面的引擎是網友貢獻的。如果你要獨立使用的話,有很多人經常會搞混,就是說beego裏面用其實你不需要這樣用,因爲beego裏面這些已經會幫你定義,如果你不用beego的邏輯,因爲現在Go沒有session模塊,那beego的模塊很多人就拿去獨立用,比如說你有一個應用但是你想用beego的模塊,那你獨立應用的話就初始化一個讓他操作就可以了,後面是你要用的引擎和配置文件。簡單應用的話就是你每個request進來然後就SessionStart,我剛開始做的時候我是讀了PHP的原碼,所以我就是用Go重新寫了一遍C。一個老外說你這個是多此一舉,說PHP本身不是很安全,因爲Go裏面已經是很隨機的數,我又在隨機數上加上了時間進行了加密的操作,他覺得這樣反而會增加不安全性,但是我又不能說服他這個爲什麼沒有安全性,他也不能說服我這個是不安全的,後來我又把這個問題發到Go的羣組裏面,有一個安全專家說你這樣的話不一定有安全性,但是會有潛在的安全性,你增加了穩定參數,所以你還不如直接用rand,代碼就變得很簡單,因爲Go裏面已經實現了所有隨機的功能,如果用的話就是GetSession(key),然後就可以操作這個東西。beego裏面還有一個強大的工具叫Toolbox,toolbox是一個網友給我提的一個建議,說你在beego裏面是不是能夠加入一些管理工具,healthcheck就是我一個應用起來之後我應用裏面的數據庫連接是不是正常,其他應用的程序和邏輯是不是符合我的需求,然後一個Profile就是當我運行的時候我可以在線的時候看我的CPUprofile,還有一些東西我在線的看,Statistics是達達,他是廈門那邊做神仙道的主程,他統計的時候就跟我說你可以把這個東西加到你的裏面,我看了一下設計的東西我覺得不錯,用戶請求的每一條數據最小的花費時間、最大的花費時間、每個人的平均時間,特別是你設計API的時候,我今天請求了1萬次,平均我最小的一次是100毫秒,最大的一次300毫秒,平均可能是150,那300爲什麼會高,那你就可以對你的性能有一個分析。

 

這個是Toolbox的後臺,我剛開始做只是做了命令行的東西,出來的時候是文本Txt類型。後來說新加坡的同事是做前端的,他幫我把所有的東西都做了美化,你就可以看得到請求了哪些東西,然後最小時間是花費了多少這樣。可以在線運行的時候直接進行這些性能的分析,這些特別有用,當你一個程序遇到性能問題的時候,你的Cpuprofile對你調優特別有效,建議大家都去用一下。這裏可以看得到你現在程序裏面路由的設置,你的配置文件怎麼設的是設了多少,這些都可以在這裏看得到。這個模塊雖然集成到beego裏面了,你也可以用到你自己的程序裏面去,因爲裏面的很多函數都是很方便的,因爲這些都是模塊化設計。

 

最後就是validation的設計,我們定義一個結構體然後V,然後Required這些配置的規則你就可以進行判斷。這是其中一種方式,還有一種方式是把配置文件寫在tag裏面,然後模塊開發計劃,接下來要做三個東西,第一個是Testing,其實我一直在思考怎麼樣更好的做好這個事,因爲Testing分兩塊,一種是白盒測試還有一種是黑盒測試,還有一種是基於函數的測試,那我接下來第一步可能做的是基於結果的測試,我只是根據你應用裏面的路由可以幫你自動的生成所有邏輯化的的東西。第二個是blueprint,因爲Go裏面的RPC的功能很強大了,我就想我在模塊化和模塊化之間通過RPC的方式來做。Zero-downtime我打算獨立做成一個模塊。

 

beego裏面有很多的插件,最近做了這三個,後面兩個是用戶做的。一個是Apiauth,亞馬遜裏面有一個驗證,就是你有一個AppID然後再你本機把要請求的東西進行加密,這個是你做之前引入怎麼用Plugins的東西,然後就插件化插入一個東西。這個是BeforeRouter就是在路由之前進行驗證,大家可以看到這邊的文檔,這個就是ippid,你要允許用戶用的appid和appkey,如果我開發一個app是提供給很多的商家用。還有另外一個函數,它裏面就是你可以自己去指定APPid和appkey的映射關係,你可以來源於你的數據庫、來源於你其他的配置文件,你就有很多個都可以支持,因爲裏面只是一個驗證的過程。這個是AUTH的插件,你可以簡單的加上這一句就可以實現你的Basicauth的功能了,用戶只有輸入用戶名才能登陸這個網頁。你可以用cors的插件,你在beforeRouter前面設定哪些域名可以訪問這是很容易的測試,這些文檔都可以看得到,我就寫的很詳細。gorelic是國外的應用,我在新加坡的時候我們用的很多,國外人有一個思路,就是人家一個產品做的好他們就拼命去用,而且就即使收錢也會用,就是相互之間的依靠關係很好。假如說你公司產品做的很好我用你產品,假如說我公司產品用的很好你用我的產品,他們的生態環境我覺得比國內好很多。這是一個性能監控的軟件,你可以在這個裏面去監控你的內存使用量有多少、CPU使用量有多少它可以全部的幫你接入進去。那Pongo是一個模板引擎,現在用的人挺多,有一個用戶貢獻了一個插件就可以在beego裏面實現去調用支持這個Pongo的模板引擎。

 

我接下來要做這三個事情,第一個是auth2,是auth的插件。第二個是RBAC、第三個是ACL。Utils庫現在除了這些剛纔所謂的模塊化和插件的功能之外,我還有一個庫,就是方便其他開發的庫,包括驗證碼、發送郵件、測試、Slice,比如說交集和比較都有,然後File判斷文件是不是存在和文件的屬性,Pagination就是分頁操作應用。總結一下,beego的設計理念就是一個組合框架,就是我有很多的設計模塊,然後beego的核心應用就是基於這些之上,其實beego有一個很好的設計是你裝beego的時候,其他的組件是一個都不會依賴的,就是你用什麼你裝什麼。第二個是高度的鬆耦合,第三個是Interface和negine的分離,我現在寫代碼都是先定Interface然後再寫其他的代碼,因爲Interface實在太好用了,Interface定義完之後你很容易的去實現擴展這些東西,太方便了。第四是模塊豐富,beego已經很多的產品在線上跑,而且都是很高性能的應用。第四個是插件設計,可以很容易的動態擴展系統。

 

接下來是講一下API開發,我們API開發因爲移動互聯網大家知道發展的非常迅速,但是你看到移動互聯網企業裏面,他們基本上是API的模式,所以說我們後端程序員爲什麼吃香?因爲我們任何一個時代我們後端的程序員,都是不管前端怎麼變,我們後端應用的東西都得我們來做。API現在也變得越來越重要了,就是很多人都是先開發API再開發別的,像我如果開發一個app的話那我首先是先開發API,然後先定一個文檔再基於這個東西來做,即使在網頁端用這些東西來渲染後端定義一個API,這樣就很容易擴展。API開發我覺得需要關注幾個點,第一個是RestFul的方式,然後文檔太重要了,特別是你人多了之後大家協同合作的時候,你如果沒有文檔那簡直是效率極低,如果你找不到一個東西但是我又不知道返回是什麼、請求參數是什麼這些東西都是一個問題。第三個是效率,我們都希望自己開發的API可以抗高併發,能夠輕鬆達到2-3w的併發。第四個是維護,假如說公司我走了公司的人是不是有人能夠維護,第五個是部署,我覺得應用方便部署很重要,當然現在有了docker之後部署就更方便了。這些我覺得beego和Go的結合都很好的解決了這幾個問題,第一因爲beego就是支持天然支持的,第二個是文檔我會給大家演示如何自動化的文檔,第三個是效率,因爲beego就是可以秒殺很多的動態語言。第四個因爲beego的結構化很清晰就很容易維護,beego爲什麼會有自動化文檔?因爲有很多註釋,然後基於這些註釋我來自動的生成文檔,爲什麼有了註釋就容易維護呢?我們都知道有註釋的代碼大家看了這個東西邏輯就很清楚,我函數的處理邏輯是怎麼樣子的。最後部署的話Go編譯之後就是一個二進制文件,扔到系統就部署完畢了。

 

下面是DemoTime,我給大家看一下,我現在的數據庫裏面有兩張表,一張是Customers表,一張是Orders表,現在我要做一個API的應用,我怎麼做呢?大家看到,我現在只要做一個命名就OK,Bee這個是工具,API就是要創建一個API,這個Bcloud是我創建的應用名字,你可以換任何的名字但是這兩個是固定的,Conn是我要去連接的數據庫,現在我要連接數據庫就是本機的,這個連接的地址就是Go裏面一個連接的格式。這個是我要去連接的點,本機是3306然後Test這個數據庫我點一下他就給我生成了這個就是自動化生成所有的代碼,它所有的代碼都生成了,然後我剛剛輸入的連接地址它也會幫我自動生成,還有路由、ORM的東西都會引入,這個我們可以看一下這邊生成了兩個Model,數據我們數據庫裏面的資料是一一對應的,就是會把你數據庫裏面所有的東西都反射過來,Order也是一一對應,然後這些東西都是會自動引入,你看Add、get、getall這些方法是全部寫好了的,大家可以看一下所有的函數,我們可以看一下這些方法全部已經幫你寫好了,我們看一下運行的效果。大家可以看看我就運行了一條命令我就完成了所有API的工作,從數據庫到API所有的東西都有,這裏網絡有問題我沒辦法下載包,所以我先前已經下好了我這邊直接拷過來,不然會自動去下,Swagger是HTML的東西,這樣的話我就把它拷過來,我們可以看一下,當大家不知道命令怎麼用的時候,大家可以用一下Bee Help,如果我自己下的話他就會自己去下,我昨天試了一下,在這邊它不能下,我不知道爲什麼。大家可以看到剛纔在這個裏面大家可以看到有很多的註釋,這些beego會分析所有的東西來生成文檔,然後會自動生成文檔,我們看一下,它已經運行起來了,大家可以看到這個就是我們生成的文檔,beego Test API,這是API的描述,再下面就是Customed,然後你可以再點一下可以看到這可以傳一個Body,然後返回的信息是什麼,我可以創建一個東西過去,這邊是獲取,我放一個1這樣大家可以看得到,就可以直接進你就測試你所有的API,可以把這個東西丟給你調用API的人,說我的API就是這樣子的,他就可以完全知道應該怎麼樣操作。這個是獲取,我可以拷過來這個,我把它改一下,ID其實可以刪掉,因爲它會自動搜索,因爲POST相當於創建一個,我放過去他給我的返回是會返回2,我們來看一下數據庫裏是不是已經有了,在這邊就已經插入進去了,然後我可以修改  也可以獲取,我就不一一演示了。這是GET所有的東西,PUT是去修改,Delete這個你點一下其實也是所有的類似的操作,這樣就一個命令可以把我數據庫兩張表全部生成了一個應用,調我的API文檔,我所有的東西都做好了,但是還有很多個性化的應用東西我沒有所有的數據庫類型都測試過,但是我在我們公司200、300張表上面都測試過,所以那些上面的性能和功能上我都測試過,很多的類型我也都測試上。基本上就是這樣,這是我們社區,大家可以有問題可以在上面提問,有Golang的、有beego的大家都可以去上面交流,這是我們的QQ羣、這是我們的微信羣大家有興趣可以去溝通一下

發佈了16 篇原創文章 · 獲贊 5 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章