Lombok은 Java 개발 시 반복적으로 작성해야 하는 보일러플레이트 코드(Boilerplate Code)를 어노테이션 하나로 자동 생성해주는 매우 유용한 라이브러리입니다.
문제점: Java의 클래스(특히 DTO나 Entity)를 작성할 때, Getter, Setter, toString(), equals(), hashCode(), 생성자 등을 매번 작성하는 것은 매우 번거롭고 가독성을 해칩니다.
Lombok의 해결책: 컴파일 시점에 어노테이션을 분석하여, 필요한 메서드들의 바이트코드를 자동으로 생성해줍니다. 개발자는 실제 코드에서는 어노테이션만 선언하면 되므로, 코드가 매우 깔끔하고 간결해집니다.
| 어노테이션 | 설명 |
|---|---|
@Getter / @Setter | 모든 필드에 대한 Getter/Setter 메서드를 자동으로 생성합니다. |
@ToString | toString() 메서드를 자동으로 오버라이드합니다. (디버깅 시 유용) |
@NoArgsConstructor | 파라미터가 없는 기본 생성자를 생성합니다. |
@AllArgsConstructor | 모든 필드를 파라미터로 받는 생성자를 생성합니다. |
@RequiredArgsConstructor | final 또는 @NonNull이 붙은 필드만 포함하는 생성자를 생성합니다. (생성자 주입 시 유용) |
@EqualsAndHashCode | equals()와 hashCode() 메서드를 자동으로 오버라이드합니다. |
@Data | @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 모두 합친 강력한 어노테이션입니다. |
@Builder | 빌더 패턴(Builder Pattern)을 사용하여 객체를 생성할 수 있게 해줍니다. (가독성 및 안정성 향상) |
@Slf4j | private static final Logger log = LoggerFactory.getLogger(ThisClass.class); 와 같은 로거(Logger) 선언 코드를 자동으로 생성해줍니다. |
```java
// Lombok 사용 전
public class UserDto {
private String name;
private int age;
// ... 수많은 Getter, Setter, 생성자, toString 등 ...
}
// Lombok 사용 후
@Data // 또는 @Getter @Setter @ToString 등 필요한 것만
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
private String name;
private int age;
}
```
문제점: 계층형 아키텍처에서 Entity, Request DTO, Response DTO 간의 필드 값을 복사하는 변환 코드를 작성하는 것은 매우 반복적이고 실수가 발생하기 쉬운 작업입니다.
// 수동 매핑
UserResponseDto dto = new UserResponseDto();
dto.setId(user.getId());
dto.setUsername(user.getUsername());
// ... 필드가 10개라면 10줄의 코드가 필요 ...
MapStruct는 이러한 객체 간의 매핑(Mapping) 코드를 컴파일 시점에 자동으로 생성해주는 코드 생성기(Code Generator)입니다.
인터페이스 기반: 개발자는 매핑 규칙을 정의할 인터페이스를 작성하고 @Mapper 어노테이션을 붙입니다.
컴파일 시점 코드 생성: 빌드 시점에 MapStruct가 이 인터페이스의 구현체를 자동으로 생성해줍니다. (리플렉션을 사용하지 않아 성능 저하가 없음)
규칙 기반 매핑: 필드 이름이 같으면 자동으로 매핑해주고, 이름이 다르거나 특별한 로직이 필요한 경우 @Mapping 어노테이션을 통해 커스텀 규칙을 지정할 수 있습니다.
@Mapper(componentModel = "spring") // Spring Bean으로 등록
public interface UserMapper {
// User 엔티티를 UserResponseDto로 변환하는 메서드 선언
@Mapping(source = "user.id", target = "userId") // 필드 이름이 다를 경우 매핑 규칙 지정
UserResponseDto toResponseDto(User user);
// List<User>를 List<UserResponseDto>로 변환하는 메서드도 자동으로 구현
List<UserResponseDto> toResponseDtoList(List<User> users);
}
// 서비스에서 사용
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper; // 생성자 주입
public UserResponseDto getUser(Long id) {
User user = userRepository.findById(id).orElseThrow();
// 한 줄로 매핑 완료!
return userMapper.toResponseDto(user);
}
}
Swagger는 OpenAPI Specification(OAS) 표준을 기반으로, REST API의 명세를 자동으로 생성하고, 시각적인 UI로 문서화하며, 해당 UI에서 직접 API를 테스트해볼 수 있는 강력한 도구입니다.
문제점: API를 개발한 후, API 명세서를 별도의 문서(Wiki, Excel 등)로 관리하면, 코드 변경 사항이 문서에 제때 반영되지 않아 결국 코드와 문서가 불일치하게 되는 문제가 발생합니다.
Swagger의 해결책: 코드가 곧 문서(Code as Documentation)가 되도록 합니다. 코드에 추가한 어노테이션을 기반으로 항상 최신 상태의 API 문서를 자동으로 생성해줍니다.
springdoc-openapispringdoc-openapi 라이브러리를 의존성에 추가하면, Spring Boot 애플리케이션의 컨트롤러 코드를 분석하여 자동으로 OpenAPI 3.0 명세를 생성해줍니다./v3/api-docs 경로에서 JSON 명세를, /swagger-ui.html 경로에서 시각적인 UI를 확인할 수 있습니다.@Operation: API의 기능에 대한 요약(summary) 및 설명(description)을 추가합니다.
@Parameter: 파라미터에 대한 설명을 추가합니다.
@ApiResponse: 발생 가능한 응답 상태 코드별로 설명을 추가합니다.
@Schema: DTO나 모델 객체의 필드에 대한 설명을 추가합니다.
@RestController
@RequestMapping("/api/users")
public class UserController {
@Operation(summary = "사용자 정보 조회", description = "ID로 특정 사용자의 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공")
@ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음")
@GetMapping("/{id}")
public UserResponseDto getUserById(
@Parameter(description = "사용자 ID") @PathVariable Long id
) {
// ...
}
}
@Data, @Builder 등의 어노테이션으로 반복적인 보일러플레이트 코드를 제거하여 코드의 가독성과 생산성을 높입니다.@Mapper 어노테이션을 통해 Entity와 DTO 간의 변환 코드를 컴파일 시점에 자동으로 생성하여, 반복적인 매핑 작업을 줄여주고 실수를 방지합니다.