[gradle] implementation? api?

coding_ticket·2024년 12월 20일
0
post-thumbnail

멀티모듈을 적용하며, 중복되는 코드와 의존성을 분리하는 과정에서 알게된 내용을 정리했습니다.

배치서버의 배포를 분리해야겠다!라고 생각하여, 멀티모듈을 적용했고, 만들어진 모듈구성은 아래와 같습니다.

후하하하~~ 완벽은 없지만 그래도 작고소중한 나의 모듈들

기존에 Service레이어에서 Redis의 RestTemplate를 바로 import하여 사용하였는데, 모듈을 나누고 나니 RestTemplate를 선언하지 못하는 문제가 발생했습니다..!
내가 redis모듈을 불러오지 않았나?라는 생각에 build.gradle을 확인하니

오잉? 잘 선언한거같은뎅

해당 문제는 gradle의 implementation과 api 설정에 대해 정확히 이해하지 못해 발생한 문제였습니다!

Gradle??

Gradle은 빌드를 자동으로 관리해주는 도구입니다. 개발을 할때 라이브러리, 프레임워크 등 의존성을 끌어와 사용해야하는 경우가 많은데, 이러한 과정을 자동으로 관리해줍니다.

gradle에서는 의존성의 범위를 4가지로 정의하고있습니다.

  • runtimeOnly: 런타임 경로에만 설정
  • compileOnly: 컴파일 경로에만 설정
  • implementation: 컴파일+런타임 경로설정
  • api: 컴파일+런타임 경로설정

그러면 implementation과 api의 경로는 같은데, 차이는 무엇일까?

implementation VS api

둘의 차이는 의존성의 전이에 있습니다.

만약 Web이 Core를 의존할때 Core가 의존하고있는 Redis를 알수있다면 이를 전이 의존성이라고 합니다.

즉, 둘의 차이는 다음과같습니다.

  • implementation: 전이 의존성 불가
  • api: 전이 의존성 허용

위의 사진은 전이 의존성이 허용된 상태인데, 그렇다면 전이 의존성이 불가하다면 어떻게 될까요?

ARedisRepository를 Web에서 생성할시 컴파일 에러가 나오게 됩니다. 즉, implementation을 사용하면 의존성을 끊긴다고 생각하면 된다!

그럼 나는 왜 안되지??

그렇다면 나의 모듈은 왜 안되는것일까?? 문제는 fitdo-redis 모듈에 있었다..

fitdo-redis의 redis의존성이 implemetation으로 선언되었기 때문에 redis라이브러리의 RedisTemplate을 fitdo-core모듈에서 가져올수 없었던것이다. 따라서 implementation을 api로 변경하여 해결했다!!

그렇다면 모두다 api로 하는게 좋지 않나??

처음에는 나도 그렇게 생각했는데, 멀티모듈을 만들면서 생각이 바뀌었다.

멀티모듈은 기본적으로 중복코드를 없애기위해 의존성에 대한 분리를 하는것인데, api를 남발하게되면 실수든 아니든 불필요하게 의존성을 참조하게 되어 분리의 의미가 없어질것이라 생각했다.(컴파일 속도도 불필요하게 많아져 시간도 더 걸릴듯??)

그렇다면 언제 implementation과 api를 사용해야할까??

정의를 정확히 내리지 못해 다른 블로그에서 답을 알수있었습니다..!

api

  • 부모 클래스 또는 인터페이에 사용되는 타입
  • 제너릭 타입을 포함하여 public 메소드 파라미터로 사용하는 타입
  • 퍼블릭 필드에 사용되는 타입
  • 퍼블릭 애노테이션 타입

implementation
메소드의 바디에서만 사용되는 타입
프라이빗 멤버로 사용되는 타입
내부 클래스에서 발견되는 타입

결론

gradle설정은 항상 복붙하기 바빴는데, 정확히 알고 사용하자..ㅎㅎ 위의 fitdo-redis의 api는 추후 implementation으로 수정하는 작업을 거칠 예정이다.


참고자료
MangKyu's Diary

0개의 댓글