Statische Middleware, die das Golang Gin-Framework verbessert: Gin-Static

Gin ist derzeit das beliebteste und beliebteste Web-Framework unter Benutzern im Golang-Ökosystem, aber Staticdie Middleware im Ökosystem war schon immer schwierig zu verwenden.

Also habe ich es geändert und diese verbesserte Version als Open Source bereitgestellt.

schreibe vorne

seelenträchtig/Gin-statisch

Ich habe die verbesserte Version von Gin-static in soulteary/gin-static als Open-Source-Version bereitgestellt und sie auch im Go-Softwarepaketmarkt veröffentlicht: pkg.go.dev/github.com/soulteary/gin-static . Sie können es sich holen, wenn Sie möchten brauchen.

Wenn es um eine verbesserte Optimierung geht, müssen wir die Verarbeitung statischer Dateien durch Go-Gin und das ursprüngliche Gin-Static erwähnen.

Informationen zur statischen Dateiverarbeitung in Go-Gin und der Gin-Community

In der offiziellen Dokumentation von Gin wird sehr deutlich erläutert , wie Gin zum Umgang mit „ Anfragen im Zusammenhang mit statischen Dateien “ verwendet werden kann:

func main() {
    
    
	router := gin.Default()
	router.Static("/assets", "./assets")
	router.StaticFS("/more_static", http.Dir("my_file_system"))
	router.StaticFile("/favicon.ico", "./resources/favicon.ico")

	// Listen and serve on 0.0.0.0:8080
	router.Run(":8080")
}

In diesem Beispiel betrachtete der Beamte jedoch nur die Situation, in der statische Ressourcen im sekundären Verzeichnis gespeichert sind und das statische Ressourcenverzeichnis nur statische Ressourcen enthält.

/Wenn unsere statischen Ressourcen das Stammverzeichnis oder das Verzeichnis verwenden müssen , in dem sich das statische Verzeichnis befindet /assets/*, gibt es eine „dynamische Logik“, die vom Golang-Backend-Programm verarbeitet werden muss, oder wir möchten Platzhalter verwenden, um bestimmte statische Dateien zu verarbeiten Routing, diese Methode wird nicht funktionieren. . Diese Situation kommt in vielen Front-End-lastigen Anwendungen sehr häufig vor, insbesondere wenn wir Golang zur Optimierung von Node- oder reinen Front-End-Implementierungsprojekten verwenden möchten.

Dieses Problem wurde im Community-Feedback erwähnt: „ #21, statische Dateien können nicht im Verzeichnis /root verwendet werden “, „ #360, Konflikt zwischen Platzhaltern und statischen Dateien “.

Daher erschien vor acht Jahren in der Gin-Contrib-Community eine Middleware, die sich auf die Verarbeitung statischer Programme konzentriert: gin-contrib/static , die uns bei der Lösung dieses Problems half. Die verwendete Methode ist ebenfalls sehr einfach:

package main

import (
  "github.com/gin-contrib/static"
  "github.com/gin-gonic/gin"
)

func main() {
    
    
  r := gin.Default()
  // ...
  r.Use(static.Serve("/", static.LocalFile("/tmp", false)))
  // ...
}

Als jedoch die Grundfunktionen abgeschlossen waren, fiel das Plug-in in einen Ruhezustand und die Versionsnummer blieb bis jetzt bei 0.0.1.

Die Zeit ist vergangen, Golangs Version wurde auf 1.21 aktualisiert, einige in dieser Middleware referenzierte Software ist veraltet oder wurde sogar aufgegeben, und einige gute funktionale Implementierungen wurden in der Community ausgesetzt (z. B. „ #19, Go native Dateieinbettung“ Achieve “), aber weil der Autor beschäftigt ist oder nicht die gleichen Schwachstellen hat, wurde die PR nicht zusammengeführt.

Es macht keinen Sinn, den alten Code nach ein paar Jahren zu kritisieren, daher werden wir den Code nicht herausziehen und Zeile für Zeile überprüfen. Ich persönlich denke, dass die relativ zuverlässige Aktion darin besteht, ihm bei der Lösung des Problems zu helfen.

Zuvor habe ich in den beiden Artikeln „ Golangs Ressourceneinbettungsschema in einfachen Worten: Teil 1 “ und „ Golangs Ressourceneinbettungsschema in einfachen Worten: go-bindata “ die am besten bewerteten offiziellen und Community-Ressourceneinbettungsschemata von Golang erwähnt Sehr wertvoll für die Erstellung von Einzeldateianwendungen mit zuverlässiger Leistung und einfacher Verteilung.

Daher habe ich in Kombination mit den vorhandenen PR-Einreichungen in der Community ( Leistung: Einbettungsordner implementieren und eine bessere Organisation implementieren ) eine neue PR (Nr. 46) eingereicht , einige Verbesserungen am vorherigen Programm und PR-Implementierungscode vorgenommen und die Testabdeckung sichergestellt Der Anteil dieser Middleware beträgt 100 %, was die Verwendung sicherer macht.

Laden Sie die für Gin-Static optimierte Version herunter

Verwenden Sie wie bei anderer Community-Software den folgenden Befehl, um den Download von gin-static abzuschließen:

go get github.com/soulteary/gin-static

Wenn Sie damit noch nicht vertraut sind, fügen Sie einfach den folgenden Referenzinhalt zu Ihrem Programm hinzu:

import "github.com/soulteary/gin-static"

// 或
import (
	static "github.com/soulteary/gin-static"
)

github.com/gin-gonic/gin-staticWenn Sie bereits Community -Softwarepakete verwenden und die Referenzen und das Verhalten vorhandener Programme nicht ändern möchten, können wir eine andere Methode verwenden.

In Ihrer go.modDatei sollten wir etwa Folgendes sehen:

module your-project

go 1.21.2

require (
	github.com/gin-gonic/gin v1.9.1
	github.com/gin-gonic/gin-static v0.0.1
)

Wir müssen nur requireeine Abhängigkeitsersetzungsregel hinzufügen, bevor:

module your-project

go 1.21.2

replace (
	github.com/gin-gonic/gin-static v0.0.1 => github.com/soulteary/gin-static v0.0.5
)

require (
	github.com/gin-gonic/gin v1.9.1
	github.com/gin-gonic/gin-static v0.0.1
)

Nachdem wir den Inhalt hinzugefügt haben, führen wir ihn aus go mod tidy, um die Aktualisierung der Abhängigkeiten abzuschließen. Unabhängig davon, wie Sie es verwenden, können wir nach der Ausführung des Befehls die native eingebettete Go-Datei verwenden.

Verwenden Sie die für Gin-Statik optimierte Version

Im Beispielverzeichnis des Projekts habe ich zwei Anwendungsbeispielprogramme eingereicht, darunter „Grundlegende Verwendung (einfach)“ und ein Beispiel, das „Dateien einbetten“ (Einbetten) unterstützt:

├── embed
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   └── public
│       └── page
└── simple
    ├── go.mod
    ├── go.sum
    ├── main.go
    └── public
        └── index.html

Grundlegende Verwendung

Die grundlegende Verwendung des Programms entspricht der Benutzeroberfläche der vorherigen Community-Version. Wenn wir lokale statische Dateien direkt im Programm verwenden möchten:

package main

import (
	"log"

	"github.com/gin-gonic/gin"
	static "github.com/soulteary/gin-static"
)

func main() {
    
    
	r := gin.Default()

    // 静态文件在默认根路径
	r.Use(static.Serve("/", static.LocalFile("./public", false)))

    // 其他路径 /other-place
    // r.Use(static.Serve("/other-place", static.LocalFile("./public", false)))

	r.GET("/ping", func(c *gin.Context) {
    
    
		c.String(200, "test")
	})

	// Listen and Server in 0.0.0.0:8080
	if err := r.Run(":8080"); err != nil {
    
    
		log.Fatal(err)
	}
}

Bei der tatsächlichen Verwendung können wir auch eine zusätzliche Logik für das Stammverzeichnis ausführen und diese verwenden, r.[Method]um das standardmäßige statische Dateirouting zu überschreiben:

// 将静态资源注册到根目录,使用本地的 Public 作为“数据源”
r.Use(static.Serve("/", static.LocalFile("public", false)))
// 允许添加其他的路由规则处理根目录
r.GET("/", func(c *gin.Context) {
    
    
  c.Redirect(http.StatusMovedPermanently, "/somewhere")
})

Dateieinbettung

Zuvor habe ich in den beiden Artikeln „ Golangs Ressourceneinbettungsschema in einfachen Worten: Teil 1 “ und „ Golangs Ressourceneinbettungsschema in einfachen Worten: go-bindata “ die am besten bewerteten offiziellen und Community-Ressourceneinbettungsschemata von Golang erwähnt Sehr wertvoll für die Erstellung von Einzeldateianwendungen mit zuverlässiger Leistung und einfacher Verteilung.

Das Arbeiten mit eingebetteten Dateien gin-staticist sehr einfach und unterstützt eine Vielzahl von Verwendungsmöglichkeiten:

package main

import (
	"embed"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

//go:embed public
var EmbedFS embed.FS

func main() {
    
    
	r := gin.Default()

	// Method 1: use as Gin Router
	// trim embedfs path `public/page`, and use it as url path `/`
	r.GET("/", static.ServeEmbed("public/page", EmbedFS))

	// OR, Method 2: use as middleware
	// trim embedfs path `public/page`, the embedfs path start with `/`
	r.Use(static.ServeEmbed("public/page", EmbedFS))

	// OR, Method 2.1: use as middleware
	// trim embedfs path `public/page`, the embedfs path start with `/public/page`
	r.Use(static.ServeEmbed("", EmbedFS))

	// OR, Method 3: use as manual
	// trim embedfs path `public/page`, the embedfs path start with `/public/page`
	// staticFiles, err := static.EmbedFolder(EmbedFS, "public/page")
	// if err != nil {
    
    
	// 	log.Fatalln("initialization of embed folder failed:", err)
	// } else {
    
    
	// 	r.Use(static.Serve("/", staticFiles))
	// }

	r.GET("/ping", func(c *gin.Context) {
    
    
		c.String(200, "test")
	})

	r.NoRoute(func(c *gin.Context) {
    
    
		fmt.Printf("%s doesn't exists, redirect on /\n", c.Request.URL.Path)
		c.Redirect(http.StatusMovedPermanently, "/")
	})

	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

Im obigen Code //go:embed publiclesen wir zunächst das lokale publicVerzeichnis in das Golang-Programm ein und konvertieren es in ein Objekt, auf das das Programm zugreifen kann. Dann können Sie jedes der oben genannten Programme entsprechend Ihrer spezifischen Situation verwenden.

Wenn wir go builddas Programm erstellen, erhalten wir eine einzelne ausführbare Datei, die alle abhängigen statischen Dateien enthält.

Persönliche Nutzungspräferenz

In meinem persönlichen Gebrauch neige ich dazu, die beiden oben genannten Verwendungen miteinander zu verschmelzen. Wenn wir entwickeln, verwenden wir das lokale Dateisystem (ersteres) und wenn wir erstellen, verwenden wir das eingebettete Go-Dateisystem (letzteres). Von) .

Dadurch wird sichergestellt, dass die statische Datei beim Abspielen WYSIWYG-Änderungen unterstützt und sofort wirksam wird. Hier ist mein persönliches Lieblingsanwendungsbeispiel:

if debugMode {
    
    
	r.Use(static.Serve("/", static.LocalFile("public", false)))
} else {
    
    
	r.NoRoute(
		// 例如,对存在的具体目录进行一些特殊逻辑处理
		func(c *gin.Context) {
    
    
			if c.Request.URL.Path == "/somewhere/" {
    
    
				c.Data(http.StatusOK, "text/html; charset=utf-8", []byte("custom as you like"))
				c.Abort()
			}
		},
		static.ServeEmbed("public", EmbedFS),
	)
	// 或者,不需要额外处理和拦截存在的静态文件
	// r.NoRoute(static.ServeEmbed("public", EmbedFS))
}

Im obigen Code mounten wir /während der Entwicklung als „Fallback“ standardmäßig lokale statische Dateien im Stammverzeichnis. Diese Dateien dürfen auf verschiedenen anderen Wegen überschrieben werden. Wenn wir bauen oder einrichten debugMode=false, mounten wir die statischen Dateien in der Route mit niedriger Priorität NoRouteals „Fallback“. Wenn wir einige echte statische Dateien anpassen oder überschreiben müssen, müssen wir sie der Route hinzufügen. Führen Sie vorher eine zusätzliche Verarbeitung durch.

zu guter Letzt

Okay, diese Middleware ist so einfach, wir haben über 80 % des zugehörigen Inhalts gesprochen. Wir haben die Gelegenheit, über weitere interessante Geschichten zur Optimierung von Einbettungsdateien zu sprechen.

–EOF


Dieser Artikel verwendet die Lizenzvereinbarung „Attribution 4.0 International (CC BY 4.0)“. Sie können ihn gerne nachdrucken, erneut ändern und verwenden, jedoch muss die Quelle angegeben werden. Namensnennung 4.0 International (CC BY 4.0)

Autor dieses Artikels: Su Yang

Erstellungszeit: 3. Januar 2024
Statistische Wortzahl: 6357 Wörter
Lesezeit: 13 Minuten zum Lesen
Link zu diesem Artikel: https://soulteary.com/2024/01/03/golang-gin-static-middleware-improves.html

Supongo que te gusta

Origin blog.csdn.net/soulteary/article/details/135372391
Recomendado
Clasificación