Golang中Rest Web服务项目结构设计指南

Golang中Rest Web服务项目结构设计指南 目前我正在构建一个电子商务API,代码越来越长且复杂,难以将其全部放在单个main.go文件中。 对于如何管理或设计我的代码以使其更易于理解,有什么想法或资源吗?

我见过很多帖子和文章提到控制器、模型和模板文件夹,但我不明白该如何实现这些。

9 回复

实际上,我不是以英语为母语的人。这就是为什么我很难表达我的问题。

更多关于Golang中Rest Web服务项目结构设计指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


再次,我观察了他们如何将CRUD与Cobra包结合使用(https://github.com/spf13/cobra),将Get、Create、Delete、Update每个操作分别放在独立的文件中,以便通过CLI进行管理。总的来说,这取决于个人偏好和任务需求。

抱歉,你问的是一个很宽泛的问题,只能通过写笔记来回答,而你自己也说过,已经阅读了大量资料。请更具体地提问。我理解你的 main.go 文件可能很臃肿,那么你需要更深入地研究代码组织和面向对象编程的原则。分析你的代码,也许在某些地方使用接口会更方便,你也可以将程序拆分成包含常用函数的包。总的来说,正如我所说,你的问题非常模糊。

Kat Zien 关于如何构建 Go 项目的演讲 https://www.youtube.com/watch?v=oL6JBUk6tj0 有助于了解哪种结构适合您的项目。

我在使用 go-chi 作为构建 API 的“框架”方面有一些不错的经验,它非常轻量级,并且附带了一系列可能需要的工具。

@skillian 我的仓库链接:https://github.com/kunalprakash1309/kunalprakash1309/blob/master/e-commerce/main.go

正如你将注意到的,我正在构建一个电子商务API。 在 main.go 中,我只处理了用户模型的CRUD操作。但我还想包含商品、购物车、卖家模型来进行开发。将所有模型都包含进来会使得在单个文件 main.go 中工作变得困难。 这就是为什么我想知道我的项目布局应该是什么样的?

我完全理解,将所有内容存储在一个文件中并不好,正如我所说,尝试将其拆分为包。既然你是为API开发,可以使用控制器,例如,使用Get()、Post()、Delete()、Put()方法来描述控制器。这里有一篇优秀的文章,学习后你可以很好地理解控制器: https://astaxie.gitbooks.io/build-web-application-with-golang/content/en/13.3.html

如果你也使用Web界面,那么为模板和处理程序也创建一个单独的目录,同时为Web资源的静态内容创建一个文件夹。

你好,Kunal,

我认为 n0kk 的观点是,像“有什么想法或资源可以帮助我更好地管理和设计代码以提升理解吗?”这样的问题,在缺乏任何上下文的情况下很难回答。对于这种笼统的问题,我们只能给出一般性的建议,就像你在网上任何地方都能找到的关于将问题分解成更小部分的内容一样。如果你能提供一个更具体的问题(例如,“这是一个500行的函数代码,我不知道如何简化”),我们就可以针对这个具体问题给出更具体的建议。

如果你是在寻求一般性建议,这里仍然是一个获取建议的好地方,但我认为它更适合放在网站的 #technical-discussion 类别下。#getting-help 版块则往往更适合处理具体问题。

再次强调,这是一个普遍性的期望,这里无法找到具体的答案。如果你想实现一个微服务项目(我建议你这样做),可以使用gRPC,那么项目结构将是一种;或者使用更流行的GraphQL,那么结构又会不同。我还知道在电子商务领域流行的BeeGo框架,用于实现CRUD操作。

你的问题具有技术性,因为你需要构建应用程序的架构。

为此,最好拿出一张纸和一支笔,画出各个组件之间如何通信、需要处理和发送哪些请求。这样你就能自己设想出数据的存储位置和分配方式。

我还可以建议参考目录结构:https://github.com/golang-standards/project-layout,但这并非官方标准。

对于大型Go项目,推荐采用分层架构。以下是电商API的典型项目结构:

// cmd/api/main.go
package main

import (
    "log"
    "net/http"
    "your-project/internal/handler"
    "your-project/internal/repository"
    "your-project/internal/service"
)

func main() {
    // 依赖注入
    productRepo := repository.NewProductRepository()
    productService := service.NewProductService(productRepo)
    productHandler := handler.NewProductHandler(productService)
    
    // 路由配置
    http.HandleFunc("/api/products", productHandler.GetProducts)
    http.HandleFunc("/api/products/{id}", productHandler.GetProduct)
    
    log.Fatal(http.ListenAndServe(":8080", nil))
}
// internal/handler/product.go
package handler

import (
    "encoding/json"
    "net/http"
    "your-project/internal/service"
)

type ProductHandler struct {
    service *service.ProductService
}

func NewProductHandler(s *service.ProductService) *ProductHandler {
    return &ProductHandler{service: s}
}

func (h *ProductHandler) GetProducts(w http.ResponseWriter, r *http.Request) {
    products, err := h.service.GetAllProducts()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(products)
}
// internal/service/product.go
package service

import (
    "your-project/internal/model"
    "your-project/internal/repository"
)

type ProductService struct {
    repo *repository.ProductRepository
}

func NewProductService(r *repository.ProductRepository) *ProductService {
    return &ProductService{repo: r}
}

func (s *ProductService) GetAllProducts() ([]model.Product, error) {
    return s.repo.FindAll()
}
// internal/repository/product.go
package repository

import (
    "database/sql"
    "your-project/internal/model"
)

type ProductRepository struct {
    db *sql.DB
}

func NewProductRepository() *ProductRepository {
    // 初始化数据库连接
    return &ProductRepository{}
}

func (r *ProductRepository) FindAll() ([]model.Product, error) {
    // 数据库查询逻辑
    return []model.Product{}, nil
}
// internal/model/product.go
package model

type Product struct {
    ID    int     `json:"id"`
    Name  string  `json:"name"`
    Price float64 `json:"price"`
}

目录结构:

cmd/
└── api/
    └── main.go
internal/
├── handler/
│   ├── product.go
│   └── order.go
├── service/
│   ├── product.go
│   └── order.go
├── repository/
│   ├── product.go
│   └── order.go
└── model/
    ├── product.go
    └── order.go
pkg/
└── utils/
    └── validation.go
go.mod

这种分层架构将业务逻辑(service)、数据访问(repository)、HTTP处理(handler)和数据结构(model)分离。handler层处理HTTP请求响应,service层包含业务逻辑,repository层负责数据持久化,model层定义数据结构。

回到顶部