이번 글에서는 Kotlin과 Jetpack Compose 기반의 Android 프로젝트에서 폴더별 역할을 설명해보고자 합니다 !
" springboot 백엔드 + Kotlin 프론트엔드 조합 "
첫 코틀린 프로젝트를 진행하게 되면서 다음과 같은 폴더 구조를 지닌 프로젝트를 만들어보게 되었습니다.

components (컴포넌트)
재사용 가능한 UI 요소(Composable)들을 모아둔 곳
ex) BoardComponent.kt 파일 : ‘??’ 화면에서 반복적으로 쓰이는 UI를 정의한 파일
역할
- 여러 화면(Screen)에서 공통적으로 사용하는 UI 요소를 정의
- Button, Card, ListItem 같은 작은 단위의 컴포넌트를 따로 만들어서 관리
예시
@Composable
fun BoardCard(boardName: String) {
Card(
modifier = Modifier.fillMaxWidth().padding(8.dp),
shape = RoundedCornerShape(10.dp),
elevation = 4.dp
) {
Text(text = boardName, modifier = Modifier.padding(16.dp))
}
}
data (데이터 관리)
서버(API)와 데이터를 주고받는 역할
api (API 통신 관련)
- ApiService.kt → REST API 호출을 위한 인터페이스
- RetrofitInstance.kt → Retrofit 객체를 생성하는 파일
예시 (ApiService.kt)
interface ApiService {
@GET("boards")
suspend fun getBoards(): List<BoardData>
}
→ getBoards() 함수가 서버에서 게시판 목록을 가져오는 역할
dto (Data Transfer Object)
- ContentDto.kt → 서버에서 받아온 데이터를 앱에서 사용할 수 있도록 변환하는 객체
- DTO는 서버에서 데이터를 가져올 때 주로 JSON을 매핑하기 위해 사용
예시 (ContentDto.kt)
data class ContentDto(
val id: Int,
val title: String,
val description: String
)
→ id, title, description 데이터를 포함하는 구조체
repository (저장소 패턴)
- Repository 패턴을 사용해서 API와 ViewModel 간의 데이터를 관리
보통 Repository 클래스에서는 다음과 같은 역할을 함 !
- API 요청
- DB 저장
- ViewModel에 전달
domain (비즈니스 로직)
데이터를 가공하거나, ViewModel과 연동하는 곳
model (데이터 모델)
- BoardData.kt → 게시판 데이터를 담는 모델
- CardData.kt → 카드 데이터를 담는 모델
보통 DTO보다 앱 내부에서 사용하는 데이터 모델을 별도로 둬서 관리
예시 (BoardData.kt)
data class BoardData(
val id: Int,
val name: String,
val description: String
)
viewmodel (화면과 데이터를 연결하는 역할)
- BoardViewModel.kt → 게시판 화면의 데이터를 관리하는 ViewModel
ViewModel에서는 API에서 데이터를 가져오고, UI에 반영하는 역할
예시 (BoardViewModel.kt)
class BoardViewModel : ViewModel() {
private val _boards = MutableLiveData<List<BoardData>>()
val boards: LiveData<List<BoardData>> = _boards
fun fetchBoards() {
viewModelScope.launch {
val result = repository.getBoards()
_boards.postValue(result)
}
}
}
→ fetchBoards() 함수가 API에서 데이터를 가져와서 화면에 보여주는 역할
navigation (화면 이동)
- NavGraph.kt → 앱에서 화면(Screen) 간의 이동 경로를 정의하는 파일
Jetpack Compose에서는 NavController를 사용해서 화면 간 이동을 관리
예시 (NavGraph.kt)
@Composable
fun NavGraph(navController: NavHostController) {
NavHost(navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("board") { BoardScreen(navController) }
}
}
→ NavGraph.kt에서 HomeScreen → BoardScreen 이동 정의
screen (화면 UI)
실제로 사용자가 보는 UI 화면
board (게시판 화면)
- BoardScreen.kt → 게시판 목록을 보여주는 화면
card (카드 화면)
- CardScreen.kt → 카드 정보를 보여주는 화면
home (홈 화면)
- HomeScreen.kt → 앱의 메인 화면
여기서 각 Screen.kt 파일들은 ViewModel에서 가져온 데이터를 UI로 보여주는 역할
ui/theme (앱 테마 및 디자인)
- Color.kt → 앱에서 사용할 색상 정의
- Theme.kt → Jetpack Compose의 테마 스타일 정의
- Type.kt → 텍스트 스타일 (폰트 크기 등) 정의
MainActivity.kt (앱의 진입점)
앱이 시작될 때 가장 먼저 실행되는 파일
setContent {} 안에 NavGraph()를 넣어서 화면을 보여줌
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAppTheme {
val navController = rememberNavController()
NavGraph(navController)
}
}
}
}
res (리소스)
- drawable/ → 아이콘, 배경 이미지 등
- mipmap/ → 앱 아이콘
- values/ → colors.xml, strings.xml 등 앱에서 사용할 리소스
Gradle Scripts
앱의 빌드 설정을 관리하는 파일
- build.gradle.kts (Module :app) → 앱에 필요한 라이브러리 및 의존성 관리
- settings.gradle.kts → 프로젝트의 기본 설정
- gradle-wrapper.properties → 사용 중인 Gradle 버전 관리
결론
- components/ → 재사용 가능한 UI
- data/ → API, 데이터 관리
- domain/ → 모델과 ViewModel
- navigation/ → 화면 이동
- screen/ → 각 화면 UI
- ui/theme/ → 앱 테마
- MainActivity.kt → 앱의 시작점
- res/ → 이미지, 아이콘, 리소스
- Gradle Scripts/ → 빌드 설정