Backend/Java, Kotlin

gradle 설정 중 api와 implementation의 차이

mopil 2024. 6. 30. 21:12
반응형

build.gradle이나 build.gradle.kts의 dependencies를 정의하는 부분에 이런 식의 코드를 본 적 있을 것이다.

 

dependencies {
    implementation("mysql:mysql-connector-java")
    api("org.springframework.boot:spring-boot-starter-data-jpa")
}

 

이때 두 선언 모두 의존성 설정이 되는데, 어떤 차이가 있는지 알아보자.

 

 

# 멀티모듈 의존성

다음과 같은 멀티모듈 환경에서 api, core 모듈 모두 동일한 의존성이 필요하다고 해보자

 

 

api모듈의 dto에 bean validation을, core 모듈의 dto에도 bean validation을 걸고 싶은 상황이고, validation 의존성은 core 모듈에 implementation으로 선언되어있다고 가정해 보자.

 

    implementation("org.springframework.boot:spring-boot-starter-validation")

 

 

api 모듈은 core모듈을 의존하고 있으므로 당연히 api 모듈에서도 validation 함수들을 사용할 수 있을 것이라 예상되지만, 사실은 그렇지 않다.

 

이는 implementation으로 선언되었기 때문이다.

 

core에서 선언한 의존성을 api모듈에서도 추이적으로 사용하고 싶으면, api로 선언을 해야 한다.

 

    api("org.springframework.boot:spring-boot-starter-validation")

 

 

이러면 core를 의존하고 있는 api모듈에도 validation 의존성이 추이적으로 적용되어 사용할 수 있게 된다.

 

# 그럼 모두 api로 선언?

당연히... 이러면 core모듈의 validation 정보가 변경 (ex. 버전업) 되었을 때 api모듈도 재빌드 되어야 하므로 빌드 비용이 증가한다.

 

따라서 무조건 api 선언보다는, implementation으로 해당 모듈에 꼭 필요한 의존성만 격리하여 선언하고 중복되는 경우만 api로 선언하는 게 좋다.

 

 

당연하게 모듈이 한 개인 상황에서는 차이가 없다.

 

 

# 결론

멀티모듈 환경에서 의존성 중복을 제거하고 싶으면 api로 선언하자

반응형