개발하면서 약 일주일간의 삽질을 통해 해결했던 경험을 쓰려고 한다.
결론부터 이야기하자면 protobuf repeated와 코틀린 프로퍼티 또는 자바 객체간 변환을 mapstruct로는 완벽히 커버할 수 없으며 추가 라이브러리(https://github.com/entur/mapstruct-spi-protobuf)를 설정해야 한다.
최초 문제:
protobuf와 kotlin 객체변환을 위해 mapstruct를 활용하고자 하였다. (보일러플레이트 코드를 지양하기 위해서) 그래서 다음과 같은 proto, kt를 작성하였다.
base.proto
message BaseResponse {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
string baseId = 4;
string baseName = 5;
string baseNumber = 6;
repeated string baseList = 7;
repeated CarList cars = 8;
}
message CarList{
string name = 1;
string madeYear = 2;
}
baseDto.kt
class BaseDTO(
val id: Any?,
val baseId: String,
val baseName: String,
var baseNumber: String,
var baseList : List<String>,
var carList: List<Car>,
) {
class Car(
var name: String,
var madeYear: String,
)
}
baseMapper.kt
@Mapper
interface BaseMapper {
fun toBaseGrpcStream(baseDTO: BaseDTO) : BaseResponse
}
각각의 프로퍼티 값이 proto 변수값과 매핑되는 것을 원했다
하지만 genereate시에 해당 리스트값에 대한 mapping은 진행되지 않는 것을 확인 하였다.
원인 :
repeated string을 compile시에 ProtocolStringList로 변환된다.하지만 kotlin에서는 protocolStringList를 List<String>으로 인식하지 못하여 제대로 매핑이 되지 않았다.
→ 1.3.0 beta 버전 이후에 조치 되었다고 하는데 위의 프로젝트에서 1.5.2.Final 버전을 쓰고 있는데도 Mapping 되지 않는 것을 보면 아직 작업이 완벽히 되지 않은 것 같다. (https://github.com/mapstruct/mapstruct/issues/1338)
또한 repeated baseList or carList를 complie시 네이밍이 baseListlist or carListlist(xxxlist)로 변환되어 kotlin의 List<Image> ko의 변수명과 맞지 않아 제대로 매핑이 되지 않았다.
결론적으로 mapstruct를 활용하여 protobuf의 완벽한 mapping은 아직이다
해결법 :
1) Mapstruct mapper 설정을 통해 list 하나 하나 매핑해야 한다.
2) https://github.com/entur/mapstruct-spi-protobuf 오픈 소스를 활용하여 해결
- Mapper 설정에 CollectionMappingStrategy.ADDER_PREFERRED 추가
→ 옵션 내용 : 기존 Target 객체의 컬렉션 객체를 유지한 채로 새로운 데이터 추가 및 업데이트 진행 - implementation("no.entur.mapstruct.spi:protobuf-spi-impl:1.41") 추가
나는 1번과 2번 중 2번 설정을 진행 한 후 compile시 다음과 같이 정상적으로 매핑되는 것을 확인할 수 있었다.
끝.
'개발 지식 > Kotlin' 카테고리의 다른 글
[Kotest] 클래스 프로퍼티 Value NULL 여부 한번에 검증하기 (2) | 2023.11.25 |
---|---|
[Coroutine] 코루틴 빌더 간단 정리 (0) | 2023.01.12 |
[Coroutine] Composing Suspending Functions (0) | 2022.09.02 |
[Coroutine] Coroutine Cancellation And Timeout (0) | 2022.08.29 |
[Coroutine] Coroutine Basic (0) | 2022.08.23 |
댓글