使用 Spring Boot 创建 REST API 的最简单方法

欢迎来到2026年。如果你觉得构建企业级 REST API 仍然是一项繁琐的任务,那么这篇文章正是为你准备的。作为一名在一线摸爬滚打多年的技术人,我们见证了 Spring Boot 从微服务的新宠演变为如今云原生时代的基石。在这篇文章中,我们将不仅仅停留在“如何跑通 Hello World”,而是会深入探讨如何结合 2026 年最新的 AI 辅助开发范式和现代化的工程实践,以最高效、最稳健的方式构建 REST API。

我们将基于 GeeksforGeeks 的经典教程进行深度扩展。你会发现,虽然核心的 Spring Boot 3 架构依然稳固,但我们的开发方式已经发生了翻天覆地的变化。让我们重新审视这一过程,并融入“氛围编程”和 AI Native 的新理念。

现代开发环境的觉醒:从 IDE 到 AI 结对伙伴

在我们开始编写第一行代码之前,我们需要搭建一个符合 2026 年标准的开发环境。这不仅仅是安装 JDK 和 IntelliJ 那么简单。

AI 辅助工作流的崛起

现在的我们,早已告别了单打独斗的编码时代。在我们最近的项目中,CursorWindsurf 这类 AI 原生 IDE 已经取代了传统的文本编辑器。为什么?因为它们提供了“氛围编程”的体验。

  • Vibe Coding(氛围编程): 这不是让你写代码,而是让 AI 理解你的意图。你只需在 IDE 中输入:“// 为我们创建一个 Product 实体,包含 JPA 注解和 Lombok 优化”,AI 就会自动补全整个类。
  • 环境准备: 当然,基础仍然重要。我们需要安装 JDK 21(LTS 版本)以及支持 Spring Boot 3.5+ 的 IDE。但更重要的是,确保你的 IDE 中集成了 GitHub Copilot 或类似的 LLM 插件,这将是我们后续调试和生成样板代码的得力助手。

重新审视 Spring Boot 项目的初始化

虽然 Spring Initializr 依然是标准起点,但在 2026 年,我们更倾向于通过 IDE 插件或 CLI 直接生成脚手架,以便快速进入开发流。

依赖管理的现代化思考

创建项目时,除了基础的 Spring Web, Spring Data JPA, 和 MySQL Driver,我们强烈建议你在 2026 年的项目中额外引入以下依赖,这不仅是“锦上添花”,而是“必须具备”:

  • SpringDoc OpenAPI (Starter): 自动生成 API 文档。不要浪费时间去手动维护 Swagger 注解,让 OpenAPI 3 规范为你服务。
  • Lombok: 减少 50% 的样板代码。虽然 Java 21 的 Record 很棒,但在 JPA 实体映射中,Lombok 依然不可或缺。

领域模型设计:超越简单的 Getter/Setter

在 GeeksforGeeks 的原始教程中,Product 类包含了大量手写的 Getter 和 Setter。但在现代 Spring Boot 开发中,这是一种技术债务。让我们用 2026 年的视角重构这个实体。

代码示例:现代化的 Product 实体

我们会使用 Lombok 来简化代码,并引入 Java 的新特性。请看以下代码,你会发现它变得多么简洁:

package com.example.entity;

import jakarta.persistence.*; // 注意:javax.persistence 已成为过去式,Spring Boot 3 使用 jakarta
import lombok.Data; // Lombok 的魔法:自动生成 Getter, Setter, toString, equals, hashCode
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;

/**
 * Product 实体类
 * 在 2026 年,我们更关注数据的不可变性和构建者模式。
 */
@Entity
@Table(name = "products")
@Data // 自动生成所有样板代码
@NoArgsConstructor
@AllArgsConstructor
@Builder // 允许我们优雅地构建对象:Product.builder().name("Phone").price(999).build()
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100)
    private String name;

    @Column(nullable = false)
    private Double price; // 使用 Double 而不是 double,以便处理可能的空值场景

    @Column(nullable = false)
    private Integer quantity;
}

关键演进点

  • 从 javax 到 jakarta: 这是你将旧项目迁移到 Spring Boot 3 时最常遇到的坑。务必使用 jakarta.persistence
  • 不可变性与构建者: 在复杂的业务逻辑中,使用 @Builder 可以让你的代码意图更加清晰,特别是在测试数据构建时。

Repository 层的极简主义与防御性编程

原始教程中的 INLINECODEa6826733 仅仅是继承了 INLINECODEcd588fe0。这对于简单的 CRUD 确实足够了,但在生产环境中,我们需要更多的防御性措施。

代码示例:增强型 Repository

package com.example.repository;

import com.example.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface ProductRepository extends JpaRepository {
    
    // Spring Data JPA 会自动实现这个方法,无需手写 SQL
    // 这种基于方法名派生查询的特性在 2026 年依然强大,且支持流式查询
    Optional findByName(String name);
}

在我们的经验中,尽量保持 Repository 的简洁。不要在这里写业务逻辑。如果你发现查询变得极其复杂,请考虑使用 @Query 注解原生 SQL,或者引入 Projections 来优化数据加载性能。

Service 层与响应式编程的擦肩而过

虽然 Spring WebFlux(响应式编程)在 2026 年非常流行,但对于大多数传统的 CRUD 应用,Spring MVC 依然是我们的首选,因为它更简单、调试更容易。

代码示例:业务逻辑层的最佳实践

让我们看看如何编写一个健壮的 Service 类,它不仅处理数据,还处理异常。

package com.example.service;

import com.example.entity.Product;
import com.example.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;

@Service
public class ProductService {

    private final ProductRepository repository;

    @Autowired // 在 2026 年,我们更推荐使用构造器注入,这里为了演示方便
    public ProductService(ProductRepository repository) {
        this.repository = repository;
    }

    public List findAll() {
        // 在生产环境中,这里应该加入分页逻辑,防止数据量过大导致 OOM
        return repository.findAll();
    }

    public Optional findById(Long id) {
        return repository.findById(id);
    }

    public Product save(Product product) {
        // 这里我们可以加入价格校验逻辑
        if (product.getPrice() < 0) {
            throw new IllegalArgumentException("价格不能为负数");
        }
        return repository.save(product);
    }

    public void deleteById(Long id) {
        if (!repository.existsById(id)) {
            throw new RuntimeException("产品不存在,无法删除"); // 建议自定义异常
        }
        repository.deleteById(id);
    }
}

注意:在真实的 2026 年项目中,你应该使用全局异常处理器(@ControllerAdvice)来捕获这些异常,并返回统一的 JSON 格式错误信息,而不是直接抛出原始异常。

Controller 层:RESTful 的极致与 OpenAPI

最后,让我们来看看 Controller。现在的趋势是将 API 视为产品。

package com.example.controller;

import com.example.entity.Product;
import com.example.service.ProductService;
import io.swagger.v3.oas.annotations.Operation; // OpenAPI 注解
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/products")
@Tag(name = "产品管理", description = "产品的增删改查 API")
public class ProductController {

    @Autowired
    private ProductService service;

    @GetMapping
    @Operation(summary = "获取所有产品")
    public List getAllProducts() {
        return service.findAll();
    }

    @PostMapping
    @Operation(summary = "创建新产品")
    public Product createProduct(@RequestBody Product product) {
        return service.save(product);
    }

    @GetMapping("/{id}")
    @Operation(summary = "根据 ID 获取产品")
    public ResponseEntity getProductById(@PathVariable Long id) {
        return service.findById(id)
                .map(product -> ResponseEntity.ok().body(product))
                .orElse(ResponseEntity.notFound().build());
    }
}

总结:未来已来

通过这篇文章,我们不仅重温了 Spring Boot 的基础,更重要的是,我们将视野扩展到了 2026 年。我们讨论了如何利用 AI 工具(如 Cursor)来减少心智负担,如何使用 Lombok 清理代码,以及如何通过 OpenAPI 规范化接口。

这不仅仅是“最简单”的方法,这是通往“最聪明”开发路径的方法。当你下次启动一个新的 Spring Boot 项目时,试着问一下你的 AI 结对伙伴:“有什么最新的最佳实践可以应用到这段代码中?”你可能会对答案感到惊喜。

最后,关于数据库配置和部署,在 2026 年,我们强烈建议你关注 Testcontainers 进行集成测试,以及使用 Docker Compose 或 Kubernetes 轻松部署你的应用。让我们一起拥抱技术带来的便利吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/37834.html
点赞
0.00 平均评分 (0% 分数) - 0