Golang项目中如何应用整洁架构及实现前的准备工作

Golang项目中如何应用整洁架构及实现前的准备工作 大家好, 我想创建一个能够播放带字幕的mp3和mp4文件的服务,使用Go作为后端,Android作为前端(可能还会用React开发一个网站)。

能否推荐一个关于在Go中实现简洁架构的优秀教程? 使用MySQL或MariaDB作为这个服务的数据库是否合适? 最后,我是否需要使用任何框架或ORM?或者直接使用Go及其必要的库就足够好了?

func main() {
    fmt.Println("hello world")
}
3 回复

使用MySQL或其他数据库来管理文件相关数据是不错的选择,但或许您应该尝试寻找能够处理MP3和MP4文件中跳转播放功能的文件传输库。类似这样的库:https://github.com/nareix/joy4(我个人尚未使用过)

更多关于Golang项目中如何应用整洁架构及实现前的准备工作的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好

我猜你已经读过这篇文章了?

Iman Tumorang 的《在 Golang 上尝试简洁架构》https://link.medium.com/deItnATjCR

以及对结构的一些更新

Iman Tumorang 的《在 Golang 上尝试简洁架构 — 2》https://link.medium.com/m9GyLG9jCR

在Go项目中应用整洁架构(Clean Architecture)能够有效分离关注点,提升代码的可维护性和可测试性。以下是对您问题的具体解答:

1. 整洁架构实现教程推荐

推荐以下资源来学习Go中的整洁架构:

核心实现示例:

// 项目结构示例
// cmd/
//   main.go
// internal/
//   domain/
//     entity/
//     repository/
//   usecase/
//   delivery/
//     http/
//   infrastructure/
//     mysql/

// 领域层实体
package entity

type Media struct {
    ID       string
    Title    string
    FilePath string
    Type     string // "audio" or "video"
}

type Subtitle struct {
    ID       string
    MediaID  string
    Language string
    Content  string
}

// 仓储接口
package repository

type MediaRepository interface {
    FindByID(id string) (*entity.Media, error)
    Save(media *entity.Media) error
}

// 用例层
package usecase

type MediaUseCase struct {
    repo repository.MediaRepository
}

func (uc *MediaUseCase) PlayMedia(id string) (*entity.Media, error) {
    return uc.repo.FindByID(id)
}

2. 数据库选择

MySQL/MariaDB完全适合您的需求:

// 基础设施层实现
package infrastructure

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

type MySQLMediaRepository struct {
    db *sql.DB
}

func NewMySQLMediaRepository(dsn string) (*MySQLMediaRepository, error) {
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        return nil, err
    }
    return &MySQLMediaRepository{db: db}, nil
}

func (r *MySQLMediaRepository) FindByID(id string) (*entity.Media, error) {
    var media entity.Media
    err := r.db.QueryRow(
        "SELECT id, title, file_path, type FROM media WHERE id = ?", 
        id,
    ).Scan(&media.ID, &media.Title, &media.FilePath, &media.Type)
    
    if err != nil {
        return nil, err
    }
    return &media, nil
}

3. 框架和ORM选择

建议采用以下方案:

使用标准库 + 必要依赖:

// HTTP处理层
package delivery

import (
    "encoding/json"
    "net/http"
    "yourproject/usecase"
)

type MediaHandler struct {
    mediaUseCase *usecase.MediaUseCase
}

func (h *MediaHandler) PlayMedia(w http.ResponseWriter, r *http.Request) {
    mediaID := r.URL.Query().Get("id")
    
    media, err := h.mediaUseCase.PlayMedia(mediaID)
    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(media)
}

// 依赖注入
func main() {
    // 初始化仓储
    repo, _ := infrastructure.NewMySQLMediaRepository("user:pass@/dbname")
    
    // 初始化用例
    mediaUseCase := &usecase.MediaUseCase{Repo: repo}
    
    // 初始化处理器
    handler := &delivery.MediaHandler{MediaUseCase: mediaUseCase}
    
    http.HandleFunc("/media/play", handler.PlayMedia)
    http.ListenAndServe(":8080", nil)
}

推荐的轻量级库:

  • 数据库:database/sql + github.com/go-sql-driver/mysql
  • HTTP路由:net/httpgithub.com/gorilla/mux
  • 配置管理:github.com/spf13/viper

媒体处理库:

// 使用ffmpeg进行媒体处理
import "os/exec"

func ExtractAudio(inputPath, outputPath string) error {
    cmd := exec.Command("ffmpeg", "-i", inputPath, "-vn", "-acodec", "libmp3lame", outputPath)
    return cmd.Run()
}

这种架构方案能够保持代码的简洁性,同时提供良好的可测试性和可维护性。每个层级都有明确的职责边界,便于团队协作和后续功能扩展。

回到顶部