go?REST?API設(shè)計(jì)模式和反模式示例解析
REST API設(shè)計(jì)模式
RESTful API已經(jīng)成為構(gòu)建現(xiàn)代網(wǎng)絡(luò)應(yīng)用的事實(shí)標(biāo)準(zhǔn)。它們?cè)试S一個(gè)靈活和可擴(kuò)展的架構(gòu),可以很容易地被廣泛的客戶端所消費(fèi)。然而,設(shè)計(jì)一個(gè)既健壯又可維護(hù)的REST API是很有挑戰(zhàn)性的,特別是對(duì)于剛?cè)胄械拈_發(fā)者。
1.以資源為導(dǎo)向的架構(gòu)(ROA)
面向資源的架構(gòu)(ROA)是一種設(shè)計(jì)模式,強(qiáng)調(diào)資源在RESTful API中的重要性。資源是RESTful API的關(guān)鍵構(gòu)件,它們應(yīng)該被設(shè)計(jì)成易于消費(fèi)和操作的方式。
在Golang中實(shí)現(xiàn)ROA的一種方式是使用gorilla/mux
包進(jìn)行路由。這里有一個(gè)例子:
r := mux.NewRouter() r.HandleFunc("/users/{id}", getUser).Methods("GET") r.HandleFunc("/users", createUser).Methods("POST") r.HandleFunc("/users/{id}", updateUser).Methods("PUT") r.HandleFunc("/users/{id}", deleteUser).Methods("DELETE")
在Open API Schema中,你可以使用path
參數(shù)來定義資源。下面是一個(gè)例子:
paths: /users/{id}: get: … put: … delete: … /users: post: …
2. HATEOAS
超媒體作為應(yīng)用狀態(tài)的引擎(HATEOAS)是一種設(shè)計(jì)模式,允許客戶動(dòng)態(tài)地瀏覽RESTful API。API提供超媒體鏈接,客戶可以按照這些鏈接來發(fā)現(xiàn)資源并與之互動(dòng)。
為了在GoLang中實(shí)現(xiàn)HATEOAS
,你可以使用go-jsonapi
包。這里有一個(gè)例子:
type User struct { ID string `json:"id"` Name string `json:"name"` Links *Links `json:"links,omitempty"` } type Links struct { Self *Link `json:"self,omitempty"` } type Link struct { Href string `json:"href,omitempty"` } func getUser(w http.ResponseWriter, r *http.Request) { userID := mux.Vars(r)["id"] user := User{ID: userID, Name: "John Doe"} user.Links = &Links{ Self: &Link{Href: fmt.Sprintf("/users/%s", userID)}, } jsonapi.MarshalOnePayload(w, &user) }
在Open API Schema中,你可以使用links
參數(shù)來定義超媒體鏈接。這里有一個(gè)例子:
paths: /users/{id}: get: responses: '200': content: application/json: schema: $ref: '#/components/schemas/User' links: self: href: '/users/{id}'
REST API反模式
1.RPC式的API
遠(yuǎn)程過程調(diào)用(RPC)風(fēng)格的API是RESTful API設(shè)計(jì)中一個(gè)常見的反模式。RPC風(fēng)格的API暴露了直接映射到底層實(shí)現(xiàn)的方法,而不是專注于資源。
下面是一個(gè)GoLang中RPC風(fēng)格API的例子:
func getUser(w http.ResponseWriter, r *http.Request) { userID := r.FormValue("id") user := userService.GetUser(userID) json.NewEncoder(w).Encode(user) }
在Open API Schema中,你可以使用operationId
參數(shù)來定義RPC風(fēng)格的API。下面是一個(gè)例子:
paths: /users: get: operationId: getUser
2.過度的工程設(shè)計(jì)
過度工程是RESTful API設(shè)計(jì)中另一個(gè)常見的反模式。當(dāng)開發(fā)者試圖預(yù)測(cè)每一個(gè)可能的用例并建立一個(gè)復(fù)雜的API來適應(yīng)它們時(shí),就會(huì)出現(xiàn)過度設(shè)計(jì)。
這里有一個(gè)Golang中過度工程的例子:
func getUser(w http.ResponseWriter, r *http.Request) { userID := mux.Vars(r)["id"] user, err := userService.GetUser(userID) if err != nil { handleError(w, err) return } json.NewEncoder(w).Encode(user) } func createUser(w http.ResponseWriter, r *http.Request) { var user User err := json.NewDecoder(r.Body).Decode(&user) if err != nil { handleError(w, err) return } user.ID = uuid.New().String() user.CreatedAt = time.Now() user.UpdatedAt = time.Now() err = userService.CreateUser(user) if err != nil { handleError(w, err) return } json.NewEncoder(w).Encode(user) } func updateUser(w http.ResponseWriter, r *http.Request) { userID := mux.Vars(r)["id"] var user User err := json.NewDecoder(r.Body).Decode(&user) if err != nil { handleError(w, err) return } user.ID = userID user.UpdatedAt = time.Now() err = userService.UpdateUser(user) if err != nil { handleError(w, err) return } json.NewEncoder(w).Encode(user) } func deleteUser(w http.ResponseWriter, r *http.Request) { userID := mux.Vars(r)["id"] err := userService.DeleteUser(userID) if err != nil { handleError(w, err) return } w.WriteHeader(http.StatusNoContent) } func handleError(w http.ResponseWriter, err error) { w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w, err. Error()) }
在Open API Schema中,你可以使用x-go-genie
擴(kuò)展定義過度工程。這里有一個(gè)例子:
paths: /users/{id}: get: x-go-genie: serviceName: UserService methodName: GetUser put: x-go-genie: serviceName: UserService methodName: UpdateUser delete: x-go-genie: serviceName: UserService methodName: DeleteUser /users: post: x-go-genie: serviceName: UserService methodName: CreateUser
總結(jié)
設(shè)計(jì)一個(gè)既健壯又可維護(hù)的RESTful API可能具有挑戰(zhàn)性,但通過遵循最佳實(shí)踐并避免常見的反模式,開發(fā)人員可以創(chuàng)建易于消費(fèi)和操作的API。在這篇文章中,我們探討了一些常見的REST API設(shè)計(jì)模式和反模式,并提供了GoLang和Open API Schema的代碼片段來幫助說明這些概念。
以上就是go REST API設(shè)計(jì)模式和反模式示例解析的詳細(xì)內(nèi)容,更多關(guān)于go REST API設(shè)計(jì)模式反模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
GoLang?socket網(wǎng)絡(luò)編程傳輸數(shù)據(jù)包時(shí)進(jìn)行長度校驗(yàn)的方法
在GoLang?socket網(wǎng)絡(luò)編程中,為了確保數(shù)據(jù)交互的穩(wěn)定性和安全性,通常會(huì)通過傳輸數(shù)據(jù)的長度進(jìn)行校驗(yàn),發(fā)送端首先發(fā)送數(shù)據(jù)長度,然后發(fā)送數(shù)據(jù)本體,接收端則根據(jù)接收到的數(shù)據(jù)長度和數(shù)據(jù)本體進(jìn)行比較,以此來確認(rèn)數(shù)據(jù)是否傳輸成功2024-11-11Golang學(xué)習(xí)筆記(四):array、slice、map
這篇文章主要介紹了Golang學(xué)習(xí)筆記(四):array、slice、map,本文分別講解了這3個(gè)類型的聲明&賦值、元素訪問、其它操作,需要的朋友可以參考下2015-05-05