Introduction: The Evolution of APIs in Java
\n\nThe world of Java development doesn't stand still. Just 10 years ago, the choice was obvious: REST and JSON. Today, when designing a microservice architecture or a mobile application, a developer faces a whole zoo of protocols. REST, GraphQL, gRPC — each promises a paradise, but in reality, every technology comes with trade-offs.
\n\nIn this article, we won't be paraphrasing documentation. We'll take a real-world task: we need to create an API for an educational platform (like our PythonLib, but in Java). We have courses, students, and learning progress. And we'll try to implement the same endpoint in three different ways.
\n\nLet's figure out which protocol will make your code faster and your life easier.
\n\nREST API in Java: The Classic That Never Dies
\n\nREST (Representational State Transfer) is an architectural style, not a protocol. In Java, the de facto standard for REST has become Spring Boot with its annotations. Simplicity, clarity, a huge community — that's why we love REST.
\n\nExample: Getting a list of courses
\n\nLet's say we need to return a list of all courses with basic information to the client:
\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\nThe client receives JSON:
\n\n[\n {"id": 1, "title": "Java for Beginners", "author": "Ivan Petrov"},\n {"id": 2, "title": "Spring Boot Masterclass", "author": "Anna Smirnova"}\n]\n\nPros of REST in Java:
\n- \n
- Minimal entry barrier — any Java developer knows Spring. \n
- Caching via HTTP headers (ETag, Cache-Control). \n
- Wide tool support (Postman, Swagger, OpenAPI). \n
Cons:
\n- \n
- The problem of over-fetching (unnecessary data) and under-fetching (not enough data, requiring multiple requests). \n
- Weak typing — everything depends on a contract that is easy to break. \n
REST is ideal for public APIs when clients are third parties and you need maximum compatibility. But if your client is a mobile application that wants to receive exactly what it needs, REST starts to become annoying.
\n\nGraphQL in Java: Give Me Only What I Ask For
\n\nGraphQL is a query language created by Facebook. In Java, it is most often implemented using the graphql-java library or integration with Spring — GraphQL Kickstart.
\n\nThe client decides which fields it needs. No over-fetching. One request — and you get courses along with the student's progress.
\n\nExample: GraphQL schema and resolver
\n\nDefining the schema:
\n\ntype Course {\n id: ID!\n title: String!\n author: String!\n progress(studentId: ID!): Int\n}\n\ntype Query {\n courses: [Course!]!\n}\n\nWriting the resolver in Java:
\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\nClient query:
\n\nquery {\n courses {\n title\n