/data/api/ApiService.kt
interface ApiService { @GET("user/profile") suspend fun getUserProfile(): Response<UserProfile> }
data/api/AuthInterceptor.kt
class AuthInterceptor(private val tokenProvider: ()-> String?):Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val token = tokenProvider() val request = chain.request().newBuilder().apply { token?.let { addHeader("Authorization", "Bearer $it") } }.build() return chain.proceed(request) } }
data/api/ApiClient.kt
object ApiClient { fun create(tokenProvider: () -> String?): ApiService { val client = OkHttpClient.Builder() .addInterceptor(AuthInterceptor(tokenProvider)) .build() return Retrofit.Builder() .baseUrl("https://your-api.com/") // 実際のURLに変更 .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() .create(ApiService::class.java) } }
presentation/viewmodel/MyViewModel.kt
class MyViewModel : ViewModel() { private val token = "" private val apiService = ApiClient.create {token} var userProfile by mutableStateOf<UserProfile?>(null) private set fun loadUserProfile() { viewModelScope.launch { try { val response = apiService.getUserProfile() if (response.isSuccessful) { userProfile = response.body() } else { // エラー処理 } } catch (e: Exception) { // 通信エラーなど } } } }
presentation/screen/ProfileScreen.kt
@Composable fun ProfileScreen(viewModel: MyViewModel = viewModel()) { val profile = viewModel.userProfile LaunchedEffect(Unit) { viewModel.loadUserProfile() } profile?.let { Text("ユーザー名: ${it.name}") } ?: Text("読み込み中...") }
domain/model/UserProfile.kt
data class UserProfile( val id: Int, val name: String, val email: String )