golang開發流程及注意事項
golang開發流程及注意事項
1、開發流程
1.1. 複雜框架類服務架構流程
明確整個業務流程
-
劃分獨立處理模組,弄清楚那些模組會出現併發
-
明確基本資料結構
a、request
b、response
c、error錯誤處理
-
抽象介面
針對介面程式設計,我們必須的定義好每一個環節的介面,這裡有一個點必須的注意 :就是我們在實現介面的時候,NewXXX()獲取實現結構型別的返回值必須是藉口物件,便於統一處理
-
明確排程器的職責
-
a、各個獨立模組之間如何通訊,如何統一管理各個木塊之間的通道,通道管理器
b、如何讓各個獨立模組統一聽從排程器的排程,停止訊號處理器、contex包的使用
c、獨立模組的管理和限流,實體池
d、統一的實體標記管理,Id生成器
注意:這裡有一個限流的問題,一般情況下,我們為解決併發效能問題,都有可能限制客戶端的訪問數量,但是我們又不可能不去處理超出我們限制的客戶請求,因此,對於客戶請求,我們一般可以優先放在我們內部的儲存器內,定時的把這些請求重新整理到通道管理器中
-
獨立處理模組的實現
1.2. Api開發流程
-
明確業務,設計資料模型
a、錯誤的響應資料模型
錯誤碼、錯誤資料結構
b、正確的響應資料模型
正確相應編碼,以及資料結構
c、請求Request引數接收資料結構
d、業務資料模型
- 設計錯誤日誌處理方式
- 資料庫操作、orm設計
- 業務邏輯程式碼編寫
- 單元測試
1.3. Api的設計原則
Restful風格
-
資源與URI
https://github.com/git https://github.com/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08
URI設計上的一些技巧:
a、使用_或-來讓URI可讀性更好
b、使用/來表示資源的層級關係
c、使用?用來過濾資源
d、,或;可以用來表示同級資源的關係
-
統一資源介面
RESTful架構應該遵循統一介面原則,統一介面包含了一組受限的預定義的操作,不論什麼樣的資源,都是通過使用相同的介面進行資源的訪問。介面應該使用標準的HTTP方法如GET,PUT和POST,並遵循這些方法的語義。
如果按照HTTP方法的語義來暴露資源,那麼介面將會擁有安全性和冪等性的特性,例如GET和HEAD請求都是安全的, 無論請求多少次,都不會改變伺服器狀態。而GET、HEAD、PUT和DELETE請求都是冪等的,無論對資源操作多少次, 結果總是一樣的,後面的請求並不會產生比第一次更多的影響。
a、GET獲取資源表示
200(OK) - 表示已在響應中發出 204(無內容) - 資源有空表示 301(Moved Permanently) - 資源的URI已被更新 303(See Other) - 其他(如,負載均衡) 304(not modified)- 資源未更改(快取) 400 (bad request)- 指代壞請求(如,引數錯誤) 404 (not found)- 資源不存在 406 (not acceptable)- 服務端不支援所需表示 500 (internal server error)- 通用錯誤響應 503 (Service Unavailable)- 服務端當前無法處理請求
b、POST使用服務端管理的(自動產生)的例項號建立資源、建立子資源、部分更新資源
200(OK)- 如果現有資源已被更改 201(created)- 如果新資源被建立 202(accepted)- 已接受處理請求但尚未完成(非同步處理) 301(Moved Permanently)- 資源的URI被更新 303(See Other)- 其他(如,負載均衡) 400(bad request)- 指代壞請求 404 (not found)- 資源不存在 406 (not acceptable)- 服務端不支援所需表示 409 (conflict)- 通用衝突 412 (Precondition Failed)- 前置條件失敗(如執行條件更新時的衝突) 415 (unsupported media type)- 接受到的表示不受支援 500 (internal server error)- 通用錯誤響應 503 (Service Unavailable)- 服務當前無法處理請求
c、PUT用客戶端管理的例項號建立一個資源、通過替換的方式更新資源
200 (OK)- 如果已存在資源被更改 201 (created)- 如果新資源被建立 301(Moved Permanently)- 資源的URI已更改 303 (See Other)- 其他(如,負載均衡) 400 (bad request)- 指代壞請求 404 (not found)- 資源不存在 406 (not acceptable)- 服務端不支援所需表示 409 (conflict)- 通用衝突 412 (Precondition Failed)- 前置條件失敗(如執行條件更新時的衝突) 415 (unsupported media type)- 接受到的表示不受支援 500 (internal server error)- 通用錯誤響應 503 (Service Unavailable)- 服務當前無法處理請求
d、DELETE刪除資源
200 (OK)- 資源已被刪除 301 (Moved Permanently)- 資源的URI已更改 303 (See Other)- 其他,如負載均衡 400 (bad request)- 指代壞請求 404 (not found)- 資源不存在 409 (conflict)- 通用衝突 500 (internal server error)- 通用錯誤響應 503 (Service Unavailable)- 服務端當前無法處理請求
-
資源的表述
a、Request
GET: https://api.github.com/args/github Accept: application/json
b、Response
HTTP/1.1 200 OK Content-Type:application/json
-
在URI裡邊帶上版本號
http://api.example.com/1.0/foo Accept: vnd.example-com.foo+json; version=1.0 Accept: application/vnd.github.v3
2、字串
2.1. 比較字串
進行比較操作時會產生三個問題:
a、有些Unicode編碼的字元可以用兩個或者多個不同的位元組序列來表示
b、有些情況下使用者希望把不同的字元看成相同的字元,如:搜尋相關
c、有些字元序列和語言相關,如:中文和英文不一樣
2.2. 字元和字串
-
字元
一個單一的字元可以用一個單一的rune(或者int32)來表示。其他相關術語,字元、碼點、Unicode字元、Unicode碼點
-
字元和字串的轉換
vars string = "hello world!" c := []rune(s) s = string(c)
-
字串的聯結
//1、使用+= s := "hello" b := " world!" s += b //2、使用strings.Join()函式,比+=更有效 s := []string{"foo", "bar", "baz"} fmt.Println(strings.Join(s, ", ")) //3、使用bytes.Buffer,比 += 和join更有效 s := "hello" b := " world!" var buffer bytes.Buffer buffer.WriteString(s) buffer.WriteString(b) buffer.String()
-
字串索引和切片
注意:一個英文字元也就是一個Unicode碼點佔用一個位元組[int8|byte]。但是一箇中文字元會佔用三個位元組,因此,我們在迴圈字串的時候,通過索引去取單個字元,如果是英文字元是可以正確取到的;如果是中文字元,則只能取到中文字元所佔三個位元組的第一個位元組地址儲存資料,因此會造成亂碼,所以引出以下幾個問題:
a、字串邊界問題
b、迴圈處理字串亂碼問題,也就是索引取值亂碼
解決辦法:
//1、使用[]rune(s)轉換為unicode字元在根據索引取值 //2、使用strings包和unicode包、utf8包 line L="dffh jj wr發生 大幅度 發t yj fd" i := strings.IndexFunc(line, unicode.IsSpace) firstWord := line[:i] i := strings.LastIndexFunc(line, unicode.IsSpace) _, size := utf8.DecodeRuneInstring(line[j:]) lastWord := line(j+size:) fmt.Println(firstWord, lastWord)
-
字串常用操作包strings
-
字串和其他資料型別進行轉換 strconv包
3、集合型別
3.1. 值、指標、引用型別
-
值
變數持有相應的值,在傳遞給方法或者函式的時候會被複制一次
-
指標
a、因為go語言是基於值傳遞的方式傳遞引數的,因此,對於傳遞比較大的資料物件時,我們可以改為傳遞指標,使得引數的傳遞成本最低,並且內容可以修改
b、當我們需要在一個函式或方法中返回三個及以上值的時候,如果這些值是同一型別,我們最好使用一個切片來傳遞;如果值型別各異,我們最好傳遞一個指向結構的指標。
注意:指標也可以指向一個引用型別,但只對切片有用
-
引用型別
引用型別就是指標
通道、函式、方法、對映、切片、interface介面型別