AI Chat앱을 구현하던 중이었습니다.
https://openai.com/ 에서 제공하는 api를 사용했구요.
Retrofit으로 통신하고, Room으로 대화 내역을 저장하고자 했습니다.
통신하고자 하는 데이터를 보면요,
requestBody에 role과 content를 보내고
responseBody에서도 role과 content를 받아요.
전 그래서 생각했죠..
아, 통신할 때 role과 content를 하나의 데이터 모델로 만들어서 사용하면 되겠구나.
그리고 Room으로 디바이스에 데이터를 저장할 때는
{
항목을 구분할 id,
항목의 title,
role + content의 리스트
}
가 저장되면 좋겠다고 생각했었습니다.
여기서도 role과 content가 필요하네?
하나의 데이터 클래스로 만들어서 같이 써도 되지 않을까?
결론부터 말씀드리면 분리해야 합니다..
우선 데이터를 Room에 저장하기 위해서는 어노테이션을 사용하여 데이터 클래스를 정의해야 합니다.
@Entity(tableName = "history_table")
data class HistoryData(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "title")
val title: String,
)
role+content의 리스트는 별도의 Entity로 생성해줘야 합니다.
@Entity(tableName = "message_table")
data class MessageData(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
@ColumnInfo(name = "message_role")
val role: String,
@ColumnInfo(name = "message_content")
val content: String,
val historyId: Int
)
위와 같이 historyId를 외래키로 가지고 있는 것이 관계형 데이터베이스에서 작업과 관리 측면에서 용이한 방법이기 때문입니다..
위와 같이 설계가 되면서, MessageData안에 id와 historyId라는 값이 추가되었습니다.
이 데이터 클래스를 그대로 통신할 때 전송한다면 (당연히) 에러가 발생합니다.
불필요한 값을 보냈다고 400에러가 날라옵니다.
@Expose나 @Transient로 직렬화/역직렬화 때 제외시켜주는 어노테이션을 사용할 수는 있지만,,
id값과 같은 @PrimaryKey와는 중복으로 사용이 불가능합니다.
추가로 저장 데이터와 통신 데이터는 완전히 일치할 수 없고,
관리하는 것에도 분리하는 게 용이하기 때문에
데이터 구조가 같다고 해서 같은 데이터 클래스를 사용하는 건 좋지 않은 방법입니다.
저는.. 같이 사용.. 할 수 있을 줄.. 알았죠...
끝도 없이 이어지는.. 에러를 보기 전까지요....
🫠
관련 작업 깃허브 링크
https://github.com/xxria17/PromptEngineering/tree/main/app
'Android' 카테고리의 다른 글
[Android] 이미지 파일(binary string) 받아서 Compose로 띄우기 (0) | 2024.04.15 |
---|---|
[Android] Retrofit MultipartBody로 POST보내기 (0) | 2024.04.12 |
[Android] Firestore Coroutine으로 받아오기 (0) | 2023.07.17 |
[Android/Kotlin] 인앱 업데이트 In-App Update (AppUpdateManager) (1) | 2022.09.19 |