Java Notes
HubWhat Is Java?History of JavaFeatures of JavaJava EditionsJDK, JRE, and JVMYour First Java ProgramJava Program StructureJava Compilation ProcessIdentifiers in JavaKeywords in JavaVariables in JavaData Types in JavaType Casting in JavaOperators in JavaInput and Output in JavaComments in JavaIf-Else Statements in JavaSwitch-Case in JavaFor Loop in JavaWhile Loop in JavaDo-While Loop in JavaNested Loops in Javabreak and continue in JavaArray IntroductionOne Dimensional ArrayMulti Dimensional ArrayJagged Array in JavaArray OperationsArray Programs — FundamentalsArray Interview QuestionsString Class in JavaImmutable Strings in JavaString MethodsStringBuilder in JavaStringBuffer in JavaString Programs — FundamentalsString Interview QuestionsOOPs IntroductionClass and Object in JavaConstructor in Javathis Keyword in Javastatic Keyword in JavaEncapsulation in JavaInheritance in Javasuper Keyword in JavaPolymorphism in JavaMethod Overloading in JavaMethod Overriding in JavaAbstraction in JavaAbstract Class in JavaInterface in JavaObject Class in JavaWrapper Class in JavaInner Class in JavaAnonymous Class in JavaObject Cloning in JavaJava Collections Framework OverviewGenerics in JavaArrayList in JavaLinkedList in JavaVector in JavaStack in JavaHashSet in JavaLinkedHashSet in JavaTreeSet in JavaPriorityQueue in JavaArrayDeque in JavaDeque Interface in JavaHashMap in JavaLinkedHashMap in JavaTreeMap in JavaHashtable in JavaIterator in JavaComparable vs Comparator in JavaJava Collections Practice ProgramsException Handling IntroductionException Hierarchy in JavaTry-Catch Block in JavaFinally Block in Javathrow and throws Keywords in JavaCustom Exceptions in JavaException Handling Best PracticesFile Class in JavaByte Streams in JavaCharacter Streams in JavaBuffered Streams in JavaSerialization in JavaDeserialization in JavaJava NIO PackageLambda Expression in Java 8Functional Interface in Java 8Method Reference in Java 8Default and Static Methods in InterfacesStream API in Java 8Optional Class in Java 8Date and Time API in Java 8Thread IntroductionThread Life Cycle in JavaThread Class in JavaRunnable Interface in JavaCreating Threads in JavaThread Priority in JavaDaemon Threads in JavaSynchronization in JavaInter-Thread Communication in JavaExecutor Framework in JavaMultithreading Programs in JavaJDBC IntroductionJDBC ArchitectureMySQL Connection with JDBCStatement Interface in JDBCPreparedStatement in JDBCResultSet in JDBCCallableStatement in JDBCTransaction Management in JDBCBatch Processing in JDBCJDBC ProjectsServlet IntroductionGenericServletHttpServletServlet Life CycleRequest and Response ObjectsCookies in ServletsSession TrackingJSP IntroductionJSP Tags and JSTLExpression Language (EL)MVC ArchitectureSpring Framework IntroductionSpring Core ContainerSpring BeansDependency InjectionSpring Boot IntroductionREST API with Spring BootValidation in Spring BootCRUD ApplicationSpring Data JPAException Handling in Spring BootSpring SecurityJWT Authentication — Java ProgrammingConfig ServerEureka Server - Service DiscoveryAPI GatewayDocker DeploymentTime ComplexityRecursion in JavaLinked List in JavaStack in Java — DSA in JavaQueue in JavaHashing in JavaSorting Algorithms in JavaSearching Algorithms in JavaTree Data Structure in JavaHeap (DSA)Graph Data Structure in JavaDynamic Programming in JavaSingleton Design PatternFactory Design PatternBuilder Design PatternAdapter Design PatternObserver Design PatternMVC Pattern — Java ProgrammingBasic Java ProgramsArray Programs — PracticeString Programs — PracticeOOP ProgramsCollection ProgramsMultithreading ProgramsJDBC ProgramsPlacement Coding QuestionsStudent Management System — Java ProgrammingEmployee Management SystemLibrary Management System — Java ProgrammingBanking System — Java ProgrammingChat ApplicationE-Commerce BackendSpring Boot Fullstack ProjectCore Java Interview QuestionsOOPs Interview QuestionsCollections Interview QuestionsMultithreading Interview QuestionsJDBC Interview QuestionsSpring Framework Interview QuestionsCoding Interview QuestionsJava Cheat SheetQuick Revision Notes — Java ProgrammingImportant Java ProgramsImportant Formulas & ConceptsJava Master Course - Learning Roadmap
Building RESTful APIs with Spring Boot - REST principles, controller annotations, request/response handling, pagination, HATEOAS, and API versioning.
REST Principles
REST (Representational State Transfer) is an architectural style for designing networked applications:
| Principle | Description |
|---|---|
| Stateless | Each request contains all info needed |
| Client-Server | Separation of concerns |
| Uniform Interface | Standard HTTP methods (GET, POST, PUT, DELETE) |
| Resource-Based | URLs represent resources, not actions |
| Layered System | Client doesn't know if connected directly to server |
REST URL Design
| GET /api/users | Get all users |
| GET /api/users/1 | Get user with id 1 |
| POST /api/users | Create new user |
| PUT /api/users/1 | Update user 1 |
| DELETE /api/users/1 | Delete user 1 |
| GET /api/users/1/orders | Get orders of user 1 |
| GET /api/users?page=1&size=10 | Paginated users |
Request and Response Handling
Path Variables
java example
@GetMapping("/users/{userId}/orders/{orderId}")
public Order getOrder(
@PathVariable Long userId,
@PathVariable Long orderId) {
return orderService.findByUserAndId(userId, orderId);
}Request Parameters
java example
@GetMapping("/products")
public Page<Product> getProducts(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortBy,
@RequestParam(defaultValue = "asc") String direction,
@RequestParam(required = false) String category) {
Sort sort = direction.equalsIgnoreCase("desc")
? Sort.by(sortBy).descending()
: Sort.by(sortBy).ascending();
Pageable pageable = PageRequest.of(page, size, sort);
if (category != null) {
return productService.findByCategory(category, pageable);
}
return productService.findAll(pageable);
}Request Body
java example
@PostMapping("/users")
public ResponseEntity<UserResponse> createUser(@RequestBody @Valid UserRequest request) {
User user = userService.create(request);
UserResponse response = mapToResponse(user);
URI location = ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(user.getId())
.toUri();
return ResponseEntity.created(location).body(response);
}Request Headers
java example
@GetMapping("/profile")
public UserProfile getProfile(
@RequestHeader("Authorization") String authHeader,
@RequestHeader(value = "Accept-Language", defaultValue = "en") String language) {
String token = authHeader.replace("Bearer ", "");
return userService.getProfile(token, language);
}ResponseEntity for Full Control
java example
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping("/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
return productService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody @Valid ProductRequest request) {
Product product = productService.create(request);
return ResponseEntity
.status(HttpStatus.CREATED)
.header("X-Product-Id", product.getId().toString())
.body(product);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
productService.delete(id);
return ResponseEntity.noContent().build();
}
}DTO Pattern (Data Transfer Objects)
java example
// Request DTO
@Data
public class CreateUserRequest {
@NotBlank(message = "Name is required")
private String name;
@Email(message = "Invalid email")
@NotBlank
private String email;
@Min(18) @Max(120)
private int age;
@NotBlank
@Size(min = 8, message = "Password must be at least 8 characters")
private String password;
}
// Response DTO (no password!)
@Data
@Builder
public class UserResponse {
private Long id;
private String name;
private String email;
private int age;
private LocalDateTime createdAt;
}
// Mapper
@Component
public class UserMapper {
public User toEntity(CreateUserRequest request) {
User user = new User();
user.setName(request.getName());
user.setEmail(request.getEmail());
user.setAge(request.getAge());
return user;
}
public UserResponse toResponse(User user) {
return UserResponse.builder()
.id(user.getId())
.name(user.getName())
.email(user.getEmail())
.age(user.getAge())
.createdAt(user.getCreatedAt())
.build();
}
}Pagination
java example
@GetMapping
public ResponseEntity<Map<String, Object>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Page<User> userPage = userService.findAll(PageRequest.of(page, size));
Map<String, Object> response = new HashMap<>();
response.put("users", userPage.getContent());
response.put("currentPage", userPage.getNumber());
response.put("totalItems", userPage.getTotalElements());
response.put("totalPages", userPage.getTotalPages());
response.put("hasNext", userPage.hasNext());
response.put("hasPrevious", userPage.hasPrevious());
return ResponseEntity.ok(response);
}API Versioning Strategies
java example
// 1. URL Versioning (Most Common)
@RestController
@RequestMapping("/api/v1/users")
public class UserControllerV1 { }
@RestController
@RequestMapping("/api/v2/users")
public class UserControllerV2 { }
// 2. Header Versioning
@GetMapping(value = "/users", headers = "X-API-VERSION=1")
public List<UserV1> getUsersV1() { }
@GetMapping(value = "/users", headers = "X-API-VERSION=2")
public List<UserV2> getUsersV2() { }
// 3. Content Negotiation
@GetMapping(value = "/users", produces = "application/vnd.company.v1+json")
public List<UserV1> getUsersV1() { }CORS Configuration
java example
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000", "https://myapp.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}Interview Key Points
@RestController=@Controller+@ResponseBodyon every method- Use
ResponseEntityfor full control over status codes and headers - DTOs separate internal model from API contract
@PathVariablefor URL segments;@RequestParamfor query params- Always use
@Validwith request DTOs for input validation - Use pagination for large datasets (never return all records)
- Version APIs via URL path (
/api/v1/,/api/v2/) - CORS must be configured for frontend-backend separation
Summary
In this chapter, we learned about REST API with Spring Boot in detail. Here are the key points:
- Basic introduction to the concept and why it is needed
- Syntax and structure with complete examples
- Internal working and best practices
- Real-world applications and use cases
- Common mistakes and how to avoid them
- How this topic is asked in interviews
To practice these concepts, write and run the code in your IDE and verify the output. Modify each example and experiment so that you deeply understand the concept.
Continue the lesson path
Study next in this module
01Spring FrameworkSpring Boot IntroductionComplete introduction to Spring Boot - auto-configuration, starter dependencies, embedded servers, creating your first Spring Boot application, and project structure.02Spring FrameworkValidation in Spring BootComplete guide to input validation in Spring Boot - Jakarta Bean Validation, custom validators, group validation, and validation error handling.03Spring FrameworkCRUD ApplicationBuild a complete CRUD application with Spring Boot - project setup, layered architecture, full CRUD operations, testing, and deployment.04Spring FrameworkSpring Data JPAComplete guide to Spring Data JPA - entity mapping, repository interfaces, query methods, JPQL, native queries, relationships, and database operations.