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

Go搭建高效的Gin Web目錄結(jié)構(gòu)

 更新時(shí)間:2025年08月08日 09:49:28   作者:Vespeng  
本文主要介紹了Go搭建高效的Gin Web目錄結(jié)構(gòu),構(gòu)建一個(gè)既高效又便于管理的項(xiàng)目架構(gòu),助力開發(fā)者打造既快速響應(yīng)又易于維護(hù)的Web應(yīng)用程序,感興趣的可以了解一下

引言

在當(dāng)今迅速迭代的軟件開發(fā)領(lǐng)域,挑選合適的工具與框架對于項(xiàng)目能否順利推進(jìn)至關(guān)重要。Gin 框架,作為 Go 語言生態(tài)中備受青睞的 Web 開發(fā)框架,憑借其卓越的性能、簡潔的設(shè)計(jì)以及豐富的功能特性,在眾多選項(xiàng)中脫穎而出。本文旨在深入剖析如何在使用 Gin 框架的過程中,構(gòu)建一個(gè)既高效又便于管理的項(xiàng)目架構(gòu),助力開發(fā)者打造既快速響應(yīng)又易于維護(hù)的 Web 應(yīng)用程序。

一、Gin 概述

引入官網(wǎng)的描述:Gin 是一個(gè)使用 Go 語言開發(fā)的 Web 框架。 它提供類似 Martini 的 API,但性能更佳,速度提升高達(dá)40倍。 如果你是性能和高效的追求者, 你會(huì)愛上 Gin。

對比 Beego 框架,Gin 框架采用了極簡主義的方法,為追求簡單和高性能,沒有多余文件或目錄,他甚至什么也沒有,沒有集成任何中間件,一個(gè) main 文件即可啟動(dòng)一個(gè) web 服務(wù)。

正因?yàn)槿缟纤?,過分精簡對于開發(fā)一個(gè)項(xiàng)目來說,前期的項(xiàng)目搭建工作就顯得尤為重要。

二、項(xiàng)目結(jié)構(gòu)設(shè)計(jì)

有過 Java 開發(fā)經(jīng)驗(yàn)的伙伴應(yīng)該了解,SpringBoot 遵循著 MVC 的設(shè)計(jì)理念,這一套設(shè)計(jì)理念一直沿用至今,他的優(yōu)秀難以言喻,Gin 框架完全可以參照這個(gè)模式來做,如下是我個(gè)人設(shè)計(jì)的一套架構(gòu):

├── /cmd  
│   └── main.go  
├── /configs
│   └── config.yaml
├── /docs
├── /internal
│   ├── /api
│   │   ├── v1
│   │   │   ├── /routes.go
│   ├── /app
│   │   ├── bootstrap.go
│   │   ├── config.go
│   │   ├── db.go
│   │   └── ...
│   ├── /controller
│   │   ├── user_controller.go
│   │   └── ...
│   ├── /middleware
│   │   ├── error.go
│   │   └── ...
│   ├── /model
│   │   ├── user_entity.go
│   │   └── ...  
│   ├── /repository
│   │   ├── user_repository.go
│   │   └── ...  
│   ├── /service
│   │   ├── user_service.go
│   │   └── ...
│   └── /utils
├── /pkg
├── /scripts
├── /tests
├── .env
├── go.mod
├── go.sum

三、目錄職責(zé)

  • /cmd
    • 存放應(yīng)用的入口文件。
    • main.go:是整個(gè)應(yīng)用的入口,在這里啟動(dòng)應(yīng)用。
  • /configs
    • 存放應(yīng)用的配置文件和配置加載邏輯。
    • config.yaml:應(yīng)用的配置文件,通常包含數(shù)據(jù)庫連接信息、服務(wù)器設(shè)置等。
  • /docs
    • 存放應(yīng)用的文檔,如API文檔、用戶手冊等。
  • /internal
    • 存放應(yīng)用的內(nèi)部邏輯,這些代碼不能被外部包所引入,可根據(jù)實(shí)際需求進(jìn)而拆分目錄。
    • api:包含應(yīng)用中核心的業(yè)務(wù)路由等,即URL路徑與控制器方法的映射。
    • app:包含應(yīng)用的核心邏輯,如初始化、啟動(dòng)等。
    • controller:包含控制器邏輯,處理請求并返回響應(yīng)。
    • middleware:存放中間件代碼,用于在請求處理流程中的特定階段執(zhí)行代碼。
    • model:定義應(yīng)用的數(shù)據(jù)模型,通常與數(shù)據(jù)庫表結(jié)構(gòu)對應(yīng)。
    • repository:實(shí)現(xiàn)數(shù)據(jù)訪問邏輯,與數(shù)據(jù)庫進(jìn)行交互。
    • service:實(shí)現(xiàn)業(yè)務(wù)邏輯,調(diào)用repository中的方法來處理業(yè)務(wù)需求。
    • utils:包含通用的工具函數(shù),這些函數(shù)可以被多個(gè)包所共享。
  • /pkg
    • 存放第三方庫,如第三方中間件、工具庫等。
  • /scripts
    • 存放各種腳本,如項(xiàng)目部署腳本、測試腳本等。
  • /tests
    • 存放測試代碼,包括單元測試、集成測試等。
    • 這里的目錄結(jié)構(gòu)可以根據(jù)需要自行組織,以支持不同類型的測試。

以上目錄結(jié)構(gòu)有助于清晰地分離應(yīng)用的不同部分,使得代碼更加模塊化、易于理解和維護(hù)。同時(shí),我也參照眾多優(yōu)秀開源項(xiàng)目的目錄搭建思想,使其完美遵循了Go語言的最佳實(shí)踐。

四、實(shí)戰(zhàn)

目錄搭建好后,開始填充代碼

下邊簡單實(shí)現(xiàn)集成數(shù)據(jù)庫,配置路由,啟動(dòng)服務(wù)

1. 配置config

在 config.yaml 文件下配置端口和數(shù)據(jù)庫連接,這里選擇 xorm:

# 基礎(chǔ)配置
app:
  port: 8080
database:
  driver: mysql
  source: root:123456@tcp(127.0.0.1:3306)/xxx_table?charset=utf8mb4&parseTime=True&loc=Local

在 config.go 下解析配置

package config

import (
    "fmt"
    "github.com/spf13/viper"
)

type Config struct {
    App      AppConfig      `yaml:"app" mapstructure:"app"`
    Database DatabaseConfig `yaml:"database" mapstructure:"database"`
}

type AppConfig struct {
    Port int `mapstructure:"port"`
}

type DatabaseConfig struct {
    Driver string `yaml:"driver" mapstructure:"driver"`
    Source string `yaml:"source" mapstructure:"source"`
}

var Conf *Config

// LoadConfig 加載配置文件
func LoadConfig() error {

    // 設(shè)置配置文件路徑和名稱
    viper.AddConfigPath("./configs")
    viper.SetConfigName("config")
    viper.SetConfigType("yaml")

    // 讀取配置文件
    err = viper.ReadInConfig()
    if err != nil {
        return fmt.Errorf("讀取配置文件失敗: %v", err)
    }

    // 將配置文件內(nèi)容解析到 Conf 變量中
    Conf = &Config{}
    err = viper.Unmarshal(Conf)
    if err != nil {
        return fmt.Errorf("解析配置文件失敗: %v", err)
    }

    return nil
}

2. 配置init

數(shù)據(jù)庫及其他的初始化統(tǒng)一放置到 app 目錄下,在這里新建 loader.go 來初始化 mysql,但是為了之后方便管理,我們另單獨(dú)創(chuàng)建 db.go 文件:

如需要加載其他如 redis,那就新建 redis.go 文件

package app

import (
    _ "github.com/go-sql-driver/mysql"
    "github.com/go-xorm/xorm"
    log "github.com/sirupsen/logrus"
    "yourProject/config"
)

var Engine *xorm.Engine

// InitializeMySQL 數(shù)據(jù)庫初始化
func InitializeMySQL() error {
    var err error
    // 創(chuàng)建數(shù)據(jù)庫引擎
    Engine, err = xorm.NewEngine(config.Conf.Database.Driver, config.Conf.Database.Source)
    if err != nil {
        log.Error("數(shù)據(jù)庫初始化失敗: %v", err)
        return err
    }

    // 測試數(shù)據(jù)庫連接
    if err = Engine.Ping(); err != nil {
        log.Error("數(shù)據(jù)庫連接失敗: %v", err)
        return err
    }

    return nil
}

app.go 中調(diào)用 InitializeMySQL()

package app

import (
    "fmt"
)

// InitializeAll 初始化所有模塊
func InitializeAll() error {
    err := InitializeMySQL()
    if err != nil {
        return fmt.Errorf("MySQL初始化錯(cuò)誤: %v", err)
    }

    return nil
}

3. 配置model

在 model 下新建 user_entity.go,注意:這個(gè)需要和數(shù)據(jù)庫對應(yīng)

package model

type User struct {
    Id          int64  `xorm:"pk autoincr 'id'"`
    UserID      int64  `xorm:"not null 'user_id'"`
    Password    string `xorm:"varchar(50) not null 'password'"`
    UserName    string `xorm:"varchar(30) 'user_name'"`
    Email       string `xorm:"varchar(50) 'email'"`
    PhoneNumber int64  `xorm:"'phone_number'"`
    Sex         string `xorm:"char(1) 'sex'"`
    Remark      string `xorm:"varchar(500) 'remark'"`
}

// TableName 方法用于返回表名
func (u User) TableName() string {
    return "user"
}

4. 配置controller

在 controller 下新建 user_controller.go

package controller

import (
    "your_project/internal/service"
    "github.com/gin-gonic/gin"
    "net/http"
)

type UserController struct {
    UserService *service.UserService
}

func NewUserController(UserService *service.UserService) *UserController {
    return &UserController{UserService: UserService}
}

func (uc *UserController) GetUsers(c *gin.Context) {
    users, err := uc.UserService.GetUsers()
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch users"})
            return
        }
    c.JSON(http.StatusOK, gin.H{"users": users})
}

5. 配置service

在 service 下新建 user_service.go

package service

import (
    "your_project/internal/model"
    "your_project/internal/repository"
    "github.com/go-xorm/xorm"
)

type UserService struct {
    userRepo *repository.UserRepository
}

func NewUserService(engine *xorm.Engine) *UserService {
    return &UserService{userRepo: repository.NewUserRepository(engine)}
}

func (us *UserService) GetUsers() ([]*models.User, error) {
    return us.userRepo.GetUsers()
}

6. 配置repository

在 repository 下新建 user_repo.go

package repository

import (
    "your_project/internal/model"
    "github.com/go-xorm/xorm"
)

type UserRepository struct {
    engine *xorm.Engine
}

func NewUserRepository(engine *xorm.Engine) *UserRepository {
    return &UserRepository{engine: engine}
}

// GetUsers 獲取所有用戶
func (r *UserRepository) GetUsers() ([]*model.User, error) {
    var users []*model.User
    err := r.engine.Table(model.User{}.TableName()).Find(&users)
    return users, err
}

7. 配置api

routes.go 中設(shè)置路由,這里設(shè)置路由組,為方便日后迭代

package v1

import (
    "github.com/gin-gonic/gin"
    "github.com/go-xorm/xorm"
    "your_project/internal/controller"
    "your_project/internal/service"
)

func SetupRoutes(r *gin.Engine, engine *xorm.Engine) {
    // 定義用戶路由組
    user := r.Group("/user")
    {
        // 創(chuàng)建 UserService 實(shí)例
        UserService := service.NewUserService(engine)
        // 創(chuàng)建 UserController 實(shí)例
        UserController := controller.NewUserController(UserService)

        user.GET("/", UserController.GetUsers)
    }
}

8. 配置bootstrap

package app

import (
    "fmt"
    "github.com/gin-gonic/gin"
    log "github.com/sirupsen/logrus"
    "your_project/config"
    "your_project/internal/api/v1"
    "your_project/internal/app"
)

func Start() {
    // 加載配置文件
    err := config.LoadConfig()
    if err != nil {
        log.Error("配置文件加載錯(cuò)誤: %v", err)
        return
    }

    // 初始化所有模塊
    err = InitializeAll()
    if err != nil {
        log.Error("模塊初始化錯(cuò)誤: %v", err)
        return
    }

    r := gin.Default()
    v1.SetupRoutes(r, Engine)

    err = r.Run(fmt.Sprintf(":%d", config.Conf.App.Port))
    if err != nil {
        log.Error("服務(wù)啟動(dòng)錯(cuò)誤: %v", err)
        return
    }
}

9. 配置main

package app

import "your_project/internal/app"

func main() {
    app.Start()
}

截至這里,一個(gè)基本的查詢請求就已構(gòu)建完成

10. 啟動(dòng)項(xiàng)目

cmd 目錄下直接運(yùn)行 main 函數(shù),正常會(huì)輸出如下信息:

Listening and serving HTTP on :8080

接著訪問 http://localhost:8080/user 正常查詢結(jié)果回顯 json 如下:

{
    "users": [
        {
            "Id": 1,
            "UserID": "000001",
            "Password": "123456",
            ...
        }
    ]
}

到此這篇關(guān)于Go搭建高效的Gin Web目錄結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)Gin Web目錄結(jié)構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Go語言啟動(dòng)Redis的實(shí)例詳解

    使用Go語言啟動(dòng)Redis的實(shí)例詳解

    這篇文章主要為大家介紹了Go語言中一個(gè)可以用來啟動(dòng)?redis-server?的開源庫?github.com/stvp/tempredis,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • Golang如何調(diào)用Python代碼詳解

    Golang如何調(diào)用Python代碼詳解

    這篇文章主要給大家介紹了關(guān)于Golang如何調(diào)用Python代碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • golang之判斷元素是否在數(shù)組內(nèi)問題

    golang之判斷元素是否在數(shù)組內(nèi)問題

    這篇文章主要介紹了golang之判斷元素是否在數(shù)組內(nèi)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2020-12-12
  • goland Duration 和time的區(qū)別說明

    goland Duration 和time的區(qū)別說明

    這篇文章主要介紹了goland Duration 和time的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言微服務(wù)中實(shí)現(xiàn)鏈路追蹤

    Go語言微服務(wù)中實(shí)現(xiàn)鏈路追蹤

    在微服務(wù)架構(gòu)中,鏈路追蹤技術(shù)可以幫助我們跟蹤請求在各個(gè)服務(wù)之間的傳播路徑,本文就來介紹一下Go語言微服務(wù)中實(shí)現(xiàn)鏈路追蹤,感興趣的可以了解一下
    2024-12-12
  • Go語言中的匿名結(jié)構(gòu)體用法實(shí)例

    Go語言中的匿名結(jié)構(gòu)體用法實(shí)例

    這篇文章主要介紹了Go語言中的匿名結(jié)構(gòu)體用法,實(shí)例分析了匿名結(jié)構(gòu)體的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go語言中Gin框架使用JWT實(shí)現(xiàn)登錄認(rèn)證的方案

    Go語言中Gin框架使用JWT實(shí)現(xiàn)登錄認(rèn)證的方案

    在如今前后端分離開發(fā)的大環(huán)境中,我們需要解決一些登陸,后期身份認(rèn)證以及鑒權(quán)相關(guān)的事情,通常的方案就是采用請求頭攜帶token的方式進(jìn)行實(shí)現(xiàn),本文給大家介紹了Go語言中Gin框架使用JWT實(shí)現(xiàn)登錄認(rèn)證的方案,需要的朋友可以參考下
    2024-11-11
  • Go本地測試小技巧解耦任務(wù)拆解

    Go本地測試小技巧解耦任務(wù)拆解

    這篇文章主要為大家介紹了Go本地測試解耦任務(wù)拆解及溝通詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 使用Go module和GoLand初始化一個(gè)Go項(xiàng)目的方法

    使用Go module和GoLand初始化一個(gè)Go項(xiàng)目的方法

    這篇文章主要介紹了使用Go module和GoLand初始化一個(gè)Go項(xiàng)目,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 詳解如何解決golang定時(shí)器引發(fā)的id重復(fù)問題

    詳解如何解決golang定時(shí)器引發(fā)的id重復(fù)問題

    這篇文章主要為大家詳細(xì)介紹了如何解決golang定時(shí)器引發(fā)的id重復(fù)問題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04

最新評論