Java API:REST、GraphQL、gRPC——2025年该如何选择?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:Java API的演进

\n\n

Java开发的世界并非一成不变。就在10年前,选择还很明确:REST和JSON。而如今,在设计微服务架构或移动应用时,开发者会面对各种各样的协议。REST、GraphQL、gRPC——每一个都承诺带来天堂般的体验,但实际上,每项技术背后都伴随着权衡取舍。

\n\n

在本文中,我们不会复述文档。我们将采用一个实际的任务:我们需要为一个教育平台创建一个API(就像我们的PythonLib,但使用Java)。我们有课程、学生和学习进度。我们将尝试用三种不同的方式来实现同一个端点。

\n\n

让我们开始分析,看看哪种协议能让你的代码更快,生活更简单。

\n\n

Java上的REST API:永不消亡的经典

\n\n

REST(表述性状态转移)是一种架构风格,而非协议。在Java中,REST的事实标准是Spring Boot及其注解。简单、易懂、庞大的社区——这就是我们喜爱REST的原因。

\n\n

示例:获取课程列表

\n\n

假设我们需要向客户端返回所有课程及其基本信息的列表:

\n\n
@RestController\n@RequestMapping("/api/courses")\npublic class CourseController {\n\n    @GetMapping\n    public ResponseEntity<List<CourseDTO>> getAllCourses() {\n        List<Course> courses = courseService.findAll();\n        List<CourseDTO> dtos = courses.stream()\n                .map(c -> new CourseDTO(c.getId(), c.getTitle(), c.getAuthor()))\n                .toList();\n        return ResponseEntity.ok(dtos);\n    }\n}
\n\n

客户端收到JSON:

\n\n
[\n  {"id": 1, "title": "Java入门", "author": "伊万·彼得罗夫"},\n  {"id": 2, "title": "Spring Boot大师班", "author": "安娜·斯米尔诺娃"}\n]
\n\n

Java上REST的优点:

\n
    \n
  • 入门门槛极低——任何Java开发者都了解Spring。
  • \n
  • 通过HTTP头(ETag、Cache-Control)进行缓存。
  • \n
  • 广泛的工具支持(Postman、Swagger、OpenAPI)。
  • \n
\n\n

缺点:

\n
    \n
  • 过度获取(多余数据)和获取不足(数据不够,需要多次请求)的问题。
  • \n
  • 弱类型——一切由易于违反的契约决定。
  • \n
\n\n

当客户端是第三方,并且您需要最大兼容性时,REST是公共API的理想选择。但如果您的客户端是一个移动应用,希望只获取所需的数据,REST就会开始让人烦恼。

\n\n

Java上的GraphQL:只给我我请求的数据

\n\n

GraphQL是一种查询语言,由Facebook创建。在Java中,最常通过graphql-java库或与Spring的集成GraphQL Kickstart来实现。

\n\n

客户端自己决定需要哪些字段。没有过度获取。一次请求,你就能获得课程以及学生的学习进度。

\n\n

示例:GraphQL schema和resolver

\n\n

定义schema:

\n\n
type Course {\n    id: ID!\n    title: String!\n    author: String!\n    progress(studentId: ID!): Int\n}\n\ntype Query {\n    courses: [Course!]!\n}
\n\n

用Java编写resolver:

\n\n
@Component\npublic class CourseResolver implements GraphQLQueryResolver {\n\n    @Autowired\n    private CourseService courseService;\n\n    public List<Course> courses() {\n        return courseService.findAll();\n    }\n}\n\n@Component\npublic class CourseFieldResolver implements GraphQLResolver<Course> {\n\n    @Autowired\n    private ProgressService progressService;\n\n    public Integer progress(Course course, Long studentId) {\n        return progressService.getProgress(course.getId(), studentId);\n    }\n}
\n\n

来自客户端的查询:

\n\n
query {\n  courses {\n    title\n                

博客

书籍推荐