Golang中编写REST API的最佳架构是什么

Golang中编写REST API的最佳架构是什么 我知道编写Go代码没有绝对的标准方式……但有一件事我确实想知道;只是因为我偶然看到了这个视频:Golang / Go 速成课程 05 | 使用 Goroutines 和 Channels 构建 API 聚合服务 - YouTube

我注意到他为他的API和服务设计了一个结构体。这种方法叫什么?在REST API设计中,有哪些不同的方法可以使我的应用程序更健壮、更不易被攻击?

谢谢。

4 回复

fraud_market:

这种方法叫什么?

封装?

更多关于Golang中编写REST API的最佳架构是什么的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


REST API 是一种应用程序编程接口(API),它采用表述性状态转移(REST)架构风格。REST 架构风格利用 HTTP 协议来请求访问和使用数据。这使得与 RESTful Web 服务的交互成为可能。

REST 的概念由 Roy Fielding 于 2000 年提出,他是一位杰出的计算机科学家,对许多万维网标准的发展产生了影响。REST 过去是,现在仍然是整个网络的核心架构原则。

REST 建立在 HTTP 传输协议之上。它利用了 HTTP 的原生功能,如 GET、PUT、POST 和 DELETE。当请求发送到 RESTful API 时,响应(即所寻找信息“资源”的“表述”)会以 JSON、XML 或 HTML 格式返回。RESTful API 由一个网络地址或统一资源标识符(URI)定义,该标识符通常遵循命名约定。

与 SOAP 相比,REST 更易于使用且更灵活:

  • 与 Web 服务交互无需昂贵的工具。
  • 学习曲线更短。
  • 效率更高(SOAP 消息中使用的 XML 比 REST 的消息格式更长)。
  • 速度更快,所需处理更少。
  • Python Course in Pune

在Go中构建REST API时,常见的架构模式是分层架构(Layer Architecture)或清洁架构(Clean Architecture)。你提到的视频中使用的结构体组织方式通常被称为服务层模式(Service Layer Pattern)或领域驱动设计(DDD)的简化实现。

核心架构模式

  1. 分层架构:通常分为控制器层(Handler)、服务层(Service)和数据访问层(Repository)。
  2. 清洁架构:强调依赖倒置,核心业务逻辑独立于框架和外部依赖。

示例代码(分层架构)

// 1. 数据模型层(Model)
type User struct {
    ID       int    `json:"id"`
    Username string `json:"username"`
    Email    string `json:"email"`
}

// 2. 数据访问层(Repository)
type UserRepository interface {
    GetByID(id int) (*User, error)
    Create(user *User) error
}

type userRepo struct {
    db *sql.DB
}

func (r *userRepo) GetByID(id int) (*User, error) {
    // 数据库查询逻辑
    row := r.db.QueryRow("SELECT id, username, email FROM users WHERE id = $1", id)
    user := &User{}
    err := row.Scan(&user.ID, &user.Username, &user.Email)
    return user, err
}

// 3. 服务层(Service)
type UserService struct {
    repo UserRepository
}

func (s *UserService) GetUser(id int) (*User, error) {
    // 业务逻辑验证
    if id <= 0 {
        return nil, errors.New("invalid user ID")
    }
    return s.repo.GetByID(id)
}

// 4. 控制器层(Handler)
type UserHandler struct {
    service *UserService
}

func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
    idStr := r.URL.Query().Get("id")
    id, _ := strconv.Atoi(idStr)
    
    user, err := h.service.GetUser(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(user)
}

// 依赖注入
func main() {
    db, _ := sql.Open("postgres", "connection_string")
    repo := &userRepo{db: db}
    service := &UserService{repo: repo}
    handler := &UserHandler{service: service}
    
    http.HandleFunc("/user", handler.GetUser)
    http.ListenAndServe(":8080", nil)
}

安全增强措施

// 输入验证
func validateUserInput(user *User) error {
    if len(user.Username) < 3 {
        return errors.New("username too short")
    }
    if !strings.Contains(user.Email, "@") {
        return errors.New("invalid email")
    }
    return nil
}

// SQL注入防护(使用参数化查询)
func (r *userRepo) SafeQuery(id int) (*User, error) {
    // 正确方式:使用参数化查询
    row := r.db.QueryRow("SELECT * FROM users WHERE id = $1", id)
    
    // 错误方式:拼接SQL(易受攻击)
    // query := fmt.Sprintf("SELECT * FROM users WHERE id = %d", id)
    
    return &User{}, nil
}

// 速率限制中间件
func rateLimitMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        limiter := rate.NewLimiter(100, 30) // 100请求/30秒
        if !limiter.Allow() {
            http.Error(w, "too many requests", http.StatusTooManyRequests)
            return
        }
        next.ServeHTTP(w, r)
    })
}

推荐的包结构

project/
├── cmd/
│   └── api/
│       └── main.go
├── internal/
│   ├── handler/
│   │   └── user_handler.go
│   ├── service/
│   │   └── user_service.go
│   ├── repository/
│   │   └── user_repository.go
│   └── model/
│       └── user.go
├── pkg/
│   └── middleware/
│       └── auth.go
└── go.mod

这种架构通过关注点分离提高了代码的可测试性和可维护性。服务层封装业务逻辑,数据访问层处理持久化,控制器层管理HTTP交互。安全方面通过输入验证、参数化查询和中间件机制来增强防护。

回到顶部