欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語(yǔ)言開(kāi)發(fā)前后端不分離項(xiàng)目詳解

 更新時(shí)間:2022年11月15日 09:39:01   作者:FengY_HYY  
這篇文章主要為大家介紹了Go語(yǔ)言開(kāi)發(fā)前后端不分離項(xiàng)目詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

現(xiàn)在,前后端分離的概念深入人心,前端、后端應(yīng)用從代碼倉(cāng)庫(kù)到發(fā)布到運(yùn)行,完全都是獨(dú)立的兩套系統(tǒng),互不影響,帶來(lái)了良好的獨(dú)立性。然而,我覺(jué)得在某些條件下,前后端不分離,也不失為一種很好的解決方案,在軟件開(kāi)發(fā)中,沒(méi)有什么萬(wàn)金油方案,都是要因地制宜。

一般一些中小系統(tǒng),尤其是管理后臺(tái),就比較適合前后端不分離的開(kāi)發(fā)方式,或者是前端同學(xué),意向?qū)W習(xí) go 語(yǔ)言,通過(guò)這種前后端不分離的方式快速開(kāi)發(fā)和學(xué)習(xí);或者是后端同學(xué),獨(dú)立開(kāi)發(fā)包含前端的項(xiàng)目。

較于前后端分離,用 Go 語(yǔ)言開(kāi)發(fā)前后端不分離的項(xiàng)目有如下優(yōu)點(diǎn):

  • 前后端代碼最后都打包到一個(gè)二進(jìn)制文件,無(wú)論是做容器,還是單獨(dú)運(yùn)行,都非常省事。
  • 后端可以利用 go 的模板技術(shù),在不深入學(xué)習(xí)前端知識(shí)的情況下,也能做出效果尚可的設(shè)計(jì)。
  • 前端用 vue、react、甚至直接寫 jQuery 都行,對(duì)技術(shù)無(wú)限制。
  • 靜態(tài)語(yǔ)言高性能,由于 go 直接編譯成機(jī)器碼,相較于 PHP、Java的 JSP這些也可以做前后端不分離技術(shù)的語(yǔ)言,性能會(huì)稍微好點(diǎn)。

接下來(lái),以一個(gè)實(shí)際項(xiàng)目為例,介紹前后端不分離項(xiàng)目的開(kāi)發(fā)過(guò)程:

Sail 后端使用 Gin 框架,前端使用 LayUI(基于 jQuery),用到了模板技術(shù)。

1. 項(xiàng)目結(jié)構(gòu)

.
.
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── deploy
│   └── Dockerfile
├── go.mod
├── go.sum
├── internal
│   └── service
└── ui
    ├── static
    ├── template
    └── ui.go

前端代碼都存在于 ui 文件夾,后端代碼都存在于 internal 文件夾,其它文件是一些容器打包命令之類。

2. 前端項(xiàng)目

在 ui 文件夾中,static 存著一些 js 庫(kù)、css 樣式、圖片之類,template 目錄下是 html 模板。這就是 Layui 所需的全部了。我對(duì)比過(guò) vue、react 和 layui,最后還是覺(jué)得 layui 更適合后端程序員開(kāi)發(fā)前端網(wǎng)頁(yè),比較返璞歸真,HTML+CSS+JQuery網(wǎng)上的資料也很多,可以專注于開(kāi)發(fā)邏輯,不至于陷入學(xué)習(xí)知識(shí)的漫長(zhǎng)過(guò)程中。

如果使用 vue、react 等當(dāng)然也可以,同樣是放在 ui 文件夾,無(wú)非是用一些打包工具比如 webpack、yarn 等打包成public或者dist,實(shí)際最后還是一些 js、html、css,然后把它們集成到 go 中。

3. 后端項(xiàng)目

后端項(xiàng)目與一個(gè) gin 的標(biāo)準(zhǔn)示例框架沒(méi)什么不同,前端來(lái)訪問(wèn)也是當(dāng)成一個(gè)正常的接口訪問(wèn),只是有一點(diǎn)不同的是,由于前后端不分離,前端訪問(wèn)接口無(wú)需帶域名(或者 ip),畢竟部署也是部署在一起的,直接訪問(wèn) url 就行。

4. 結(jié)合在一起

關(guān)鍵是在前端項(xiàng)目根目錄中增加一個(gè).go文件,內(nèi)部引用前端頁(yè)面:

package ui
import (
   "embed"
)
//go:embed template
var TemplateFs embed.FS
//go:embed static
var StaticFs embed.FS

利用 go1.16發(fā)布的 embed 技術(shù),我們?cè)谧兞?code>TemplateFS、StaticFS前面加上//go:embed注釋,后面跟著一個(gè)相對(duì)路徑(./可以省略,完整寫法是:./template),我們把ui/templateui/static下的所有文件都打包到TemplateFS、StaticFS,這個(gè)FS就是FileSystem的縮寫,底層是實(shí)現(xiàn)了一個(gè)內(nèi)存文件系統(tǒng)(只讀),從程序角度看,似乎跟直接讀文件沒(méi)什么不同。但實(shí)際上我們知道,這些文件已經(jīng)無(wú)需在進(jìn)程外準(zhǔn)備,而是直接打包到二進(jìn)制文件內(nèi)了。

在 go 程序編譯時(shí),編譯器監(jiān)測(cè)到文件內(nèi)的 go:embed 注釋,則會(huì)讀取這些文件,把它們標(biāo)記好,在最后生成可執(zhí)行文件時(shí),把文件內(nèi)容打到 embed.FS 中。所以這個(gè)技術(shù)不能支持太大的文件,不然內(nèi)存容量都可能不夠。

接下來(lái),在后端 go 程序的代碼,運(yùn)行 gin 時(shí)基本上是這樣寫法:

engine := gin.New()
engine.Run(":8080")

如何把對(duì)前端路由的監(jiān)聽(tīng)插到 engine 中呢?實(shí)際上在 gin 的引擎蓋下,真正對(duì)系統(tǒng) TCP 連接發(fā)起監(jiān)聽(tīng)的還是 go 本身的 http 包,gin 不過(guò)是做了層封裝。我們可以不運(yùn)行Run,而是把 gin 作為一個(gè)HTTPHandler,代碼如下:

// 后端路由
engine := gin.New()
// 前端路由
staticEngine := gin.New()
templateHTML, err := template.ParseFS(ui.TemplateFs, "template/**/**/*.html")
if err != nil {
   panic(err)
}
staticEngine.SetHTMLTemplate(templateHTML)
fads, err := fs.Sub(ui.StaticFs, "static")
if err != nil {
   panic(err)
}
staticEngine.StaticFS("/static", http.FS(fads))
// Route 
s.Route(c, engine)
s.RouteHTML(c, staticEngine)
// 通過(guò)一個(gè) Server 運(yùn)行,判斷應(yīng)該走前端路由還是后端路由
server := &http.Server{
   Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
      // 如果 URL 以 /static 或 /ui 開(kāi)頭,則走前端路由
      if strings.HasPrefix(request.URL.Path, "/static") ||
         strings.HasPrefix(request.URL.Path, "/ui") { // ??:/ui 是怎么來(lái)的?
         staticEngine.ServeHTTP(writer, request)
         return
      }
      // 否則,走后端路由
      engine.ServeHTTP(writer, request)
   }),
}
if err = server.ListenAndServe(":8080");err != nil{
   panic(err)
}

我們知道,go 提供的 http server,當(dāng)有請(qǐng)求來(lái)時(shí),默認(rèn)會(huì)回調(diào)到它注冊(cè)的 handler 上,而 gin 框架的核心也就是提供一個(gè) handler,所以我們?cè)O(shè)計(jì)了一個(gè)自己的 handler,判斷比如是 /static/xxxxx.css 這種請(qǐng)求,則走前端路由,否則走后端路由。

在上面代碼中,我們還缺少了一步關(guān)鍵操作,我們通過(guò)SetHTMLTemplate把 html 模板文件傳遞給 gin 的staticEngine,卻沒(méi)有為這些 html 文件設(shè)置訪問(wèn)入口,我們需要為每個(gè) html 配置訪問(wèn)入口:

// 以 index.html 為例:
func (s *Server) RouteHTML(c *Handlers, staticEngine *gin.Engine) {
   templateGroup := staticEngine.Group("/ui") // /ui 是這里聲明的
   templateGroup.GET("/index", c.indexHandler.Index) // 這是說(shuō),如果訪問(wèn)/ui/index,則回調(diào) Index 函數(shù)
}
func (h *IndexHandler) Index(c *gin.Context) {
   // 剛才 SetHTMLTemplate 已經(jīng)把所有的 html 文件傳給 gin 了,gin 已經(jīng)保存在 map 中,所以這里只需要指明 html 文件名即可。
   c.HTML(http.StatusOK, "index.html", gin.H{})
}

在 Index 函數(shù)里,我們通過(guò) gin 的 HTML 方法渲染了模板,并返回 html 頁(yè)面。那么,只要訪問(wèn)/ui/index即可獲取到這個(gè) html 頁(yè)了。通過(guò)模板技術(shù),我們可以把任意數(shù)據(jù)傳遞給這個(gè)頁(yè)面。

這就是 Go 開(kāi)發(fā)前后端不分離項(xiàng)目的全部流程,其中一些代碼細(xì)節(jié),可以去 Sail 這個(gè)項(xiàng)目查看,也可以基于這個(gè)項(xiàng)目,打造自己的前后端不分離項(xiàng)目。

如果想使用 vue、react 等前端框架技術(shù),也可以看看 parca,它使用了 HTTP 后端、GRPC 后端、React 前端、Yarn 打包等如今比較熱門的技術(shù),可以作為參考。

以上就是Go語(yǔ)言開(kāi)發(fā)前后端不分離項(xiàng)目詳解的詳細(xì)內(nèi)容,更多關(guān)于Go前后端不分離項(xiàng)目的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go基本數(shù)據(jù)類型的具體使用

    Go基本數(shù)據(jù)類型的具體使用

    本文主要介紹了Go的基本數(shù)據(jù)類型,包括布爾類型、整數(shù)類型、浮點(diǎn)數(shù)類型、復(fù)數(shù)類型、字符串類型,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 淺析Go語(yǔ)言容器之?dāng)?shù)組和切片的使用

    淺析Go語(yǔ)言容器之?dāng)?shù)組和切片的使用

    在?Java?的核心庫(kù)中,集合框架可謂鼎鼎大名:Array?、List、Set等等,隨便拎一個(gè)出來(lái)都值得開(kāi)發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計(jì)源碼。雖然Go語(yǔ)言沒(méi)有如此豐富的容器類型,但也有一些基本的容器供開(kāi)發(fā)者使用,接下來(lái)讓我們認(rèn)識(shí)一下這些容器類型吧
    2022-11-11
  • gorm golang 并發(fā)連接數(shù)據(jù)庫(kù)報(bào)錯(cuò)的解決方法

    gorm golang 并發(fā)連接數(shù)據(jù)庫(kù)報(bào)錯(cuò)的解決方法

    今天小編就為大家分享一篇gorm golang 并發(fā)連接數(shù)據(jù)庫(kù)報(bào)錯(cuò)的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Go語(yǔ)言中重構(gòu)的技巧分享

    Go語(yǔ)言中重構(gòu)的技巧分享

    這篇文章主要來(lái)和大家分享一下Go語(yǔ)言中重構(gòu)的技巧,即如何盡量避免使用 else、break 和 continue,從而讓代碼更透明、更易讀,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-10-10
  • Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    在軟件開(kāi)發(fā)的世界里,數(shù)據(jù)類型轉(zhuǎn)換是一項(xiàng)基礎(chǔ)而重要的技能,尤其在Go語(yǔ)言這樣類型嚴(yán)格的語(yǔ)言中,正確高效地進(jìn)行類型轉(zhuǎn)換對(duì)于性能優(yōu)化和代碼質(zhì)量至關(guān)重要,本文給大家介紹了Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換,需要的朋友可以參考下
    2024-02-02
  • Golang?WaitGroup?底層原理及源碼解析

    Golang?WaitGroup?底層原理及源碼解析

    WaitGroup?是?Golang?中最常見(jiàn)的并發(fā)控制技術(shù)之一,它的作用我們可以簡(jiǎn)單類比為其他語(yǔ)言中多線程并發(fā)控制中的?join(),這篇文章主要介紹了Golang?WaitGroup?底層原理及源碼詳解,需要的朋友可以參考下
    2023-04-04
  • GO語(yǔ)言中的Map使用方法詳解

    GO語(yǔ)言中的Map使用方法詳解

    這篇文章主要給大家介紹了關(guān)于GO語(yǔ)言中Map使用方法的相關(guān)資料,在go語(yǔ)言中map是散列表的引用,map的類型是map[k]v,也就是常說(shuō)的k-v鍵值對(duì),需要的朋友可以參考下
    2023-08-08
  • Golang?統(tǒng)計(jì)字符串中數(shù)字字母數(shù)量的實(shí)現(xiàn)方法

    Golang?統(tǒng)計(jì)字符串中數(shù)字字母數(shù)量的實(shí)現(xiàn)方法

    這篇文章主要介紹了Golang?統(tǒng)計(jì)字符串中數(shù)字字母數(shù)量,本文給出了兩種從字符串獲取數(shù)字與字母數(shù)量的方法,分別是ASCII 碼值和正則表達(dá)式,需要的朋友可以參考下
    2022-06-06
  • Golang標(biāo)準(zhǔn)庫(kù)container/list的用法圖文詳解

    Golang標(biāo)準(zhǔn)庫(kù)container/list的用法圖文詳解

    提到單向鏈表,大家應(yīng)該是比較熟悉的了,這篇文章主要為大家詳細(xì)介紹了Golang標(biāo)準(zhǔn)庫(kù)container/list的用法相關(guān)知識(shí),感興趣的小伙伴可以了解下
    2024-01-01
  • Golang生成Excel文檔的方法步驟

    Golang生成Excel文檔的方法步驟

    生成Excel是一個(gè)很常見(jiàn)的需求,本文將介紹如何使用Go的 Excelize庫(kù)去生成Excel文檔,以及一些具體場(chǎng)景下的代碼實(shí)現(xiàn),感興趣的可以參考一下
    2021-06-06

最新評(píng)論