Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 6 additions & 22 deletions data/src/main/java/com/example/data/api/CategoryApi.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// data/api/CategoryApi.kt
// data/api/CategoryApi.kt - @Header 파라미터 방식
package com.example.data.api

import com.example.data.dto.CategoryCreateRequest
Expand All @@ -8,40 +8,24 @@ import retrofit2.http.*

/**
* 카테고리 관련 API 엔드포인트 정의
* 카테고리 CRUD 작업을 처리하는 Retrofit 인터페이스
*/
interface CategoryApi {

/**
* 모든 카테고리 목록 조회
*
* @return 카테고리 목록을 담은 Response
* API: GET /api/categories
*/
@GET("api/categories")
suspend fun getCategories(): Response<List<CategoryDto>>

/**
* 새로운 카테고리 생성
*
* @param request 생성할 카테고리 정보 (이름, ID)
* @return 생성된 카테고리 정보를 담은 Response
* API: POST /api/categories
* 새로운 카테고리 생성 - 헤더를 파라미터로 전달
*/
@POST("api/categories")
suspend fun createCategory(
@Header("Content-Type") contentType: String = "application/json",
@Header("Accept") accept: String = "application/json",
@Body request: CategoryCreateRequest
): Response<CategoryDto>

/**
* 특정 카테고리 삭제
*
* @param categoryId 삭제할 카테고리의 ID
* @return 삭제 결과를 담은 Response (성공 시 빈 응답)
* API: DELETE /api/categories/{id}
*/
@DELETE("api/categories/{id}")
suspend fun deleteCategory(
@Path("id") categoryId: Long // Int에서 Long으로 변경
@Path("id") categoryId: Long
): Response<Unit>
}
}
63 changes: 58 additions & 5 deletions data/src/main/java/com/example/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Named
import javax.inject.Singleton

/**
Expand Down Expand Up @@ -59,16 +60,42 @@ object NetworkModule {
* - 로깅 인터셉터 추가
* - 타임아웃 설정 (연결, 읽기, 쓰기 각각 30초)
*/
// NetworkModule.kt - 인터셉터 순서 변경 및 강화
@Provides
@Singleton
fun provideOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor
): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(loggingInterceptor) // HTTP 로깅
.connectTimeout(30, TimeUnit.SECONDS) // 연결 타임아웃
.readTimeout(30, TimeUnit.SECONDS) // 읽기 타임아웃
.writeTimeout(30, TimeUnit.SECONDS) // 쓰기 타임아웃
// 로깅 인터셉터를 먼저 추가
.addInterceptor(loggingInterceptor)
// 헤더 인터셉터를 나중에 추가 (더 높은 우선순위)
.addInterceptor { chain ->
val original = chain.request()

// 강제로 로그 출력
android.util.Log.d("HeaderInterceptor", "🔧 헤더 인터셉터 실행됨!")
android.util.Log.d("HeaderInterceptor", "원본 URL: ${original.url}")
android.util.Log.d("HeaderInterceptor", "원본 헤더: ${original.headers}")

val newRequest = original.newBuilder()
.removeHeader("Content-Type") // 기존 헤더 제거
.removeHeader("Accept")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("User-Agent", "Barrion-Android")
.build()

android.util.Log.d("HeaderInterceptor", "수정된 헤더: ${newRequest.headers}")

val response = chain.proceed(newRequest)
android.util.Log.d("HeaderInterceptor", "응답 코드: ${response.code}")

response
}
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
}

Expand Down Expand Up @@ -107,7 +134,33 @@ object NetworkModule {
*/
@Provides
@Singleton
fun provideCategoryApi(retrofit: Retrofit): CategoryApi {
fun provideCategoryApi(@Named("CategoryRetrofit") retrofit: Retrofit): CategoryApi {
return retrofit.create(CategoryApi::class.java)
}
// NetworkModule.kt에 추가
@Provides
@Singleton
@Named("CategoryRetrofit")
fun provideCategoryRetrofit(json: Json): Retrofit {
val client = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build()

android.util.Log.d("CategoryRetrofit", "헤더 추가됨: ${request.headers}")
chain.proceed(request)
}
.build()

return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
}
}
4 changes: 2 additions & 2 deletions data/src/main/java/com/example/data/dto/CategoryDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import kotlinx.serialization.Serializable
@Serializable
data class CategoryDto(
@SerialName("categoryId")
val categoryId: Long, // Int에서 Long으로 변경
val categoryId: Long,
@SerialName("categoryName")
val categoryName: String
)

@Serializable
data class CategoryCreateRequest(
@SerialName("categoryId")
val categoryId: Long, // Int에서 Long으로 변경
val categoryId: Long, // 필수 필드로 변경
@SerialName("categoryName")
val categoryName: String
)
Expand Down
18 changes: 14 additions & 4 deletions data/src/main/java/com/example/data/mapper/CategoryMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ import com.example.domain.model.Category
* - order: API에 order 필드가 없으므로 categoryId를 Int로 변환하여 사용
* - 나머지 필드들은 기본값 사용
*/
/**
* 카테고리 관련 데이터 변환을 담당하는 매퍼 함수들
*/

fun CategoryDto.toDomain(): Category {
return Category(
id = categoryId, // Long 그대로 사용
id = categoryId,
name = categoryName,
order = categoryId.toInt(), // Long을 Int로 변환 (order 필드용)
// API에 없는 필드들은 기본값 설정
order = categoryId.toInt(),
isDefault = false,
menuCount = 0,
createdAt = System.currentTimeMillis()
Expand All @@ -44,9 +47,16 @@ fun CategoryDto.toDomain(): Category {
* - id → categoryId: Domain의 id를 서버의 categoryId로 매핑
* - name → categoryName: Domain의 name을 서버의 categoryName으로 매핑
*/


/**
* Domain 모델을 서버 생성 요청 DTO로 변환
* ⚠️ categoryId는 서버에서 자동 생성하므로 포함하지 않음
*/
// 2. CategoryMapper.kt 수정
fun Category.toCreateRequest(): CategoryCreateRequest {
return CategoryCreateRequest(
categoryId = id, // Long 그대로 사용
categoryId = id, // ID 포함해서 전송
categoryName = name
)
}
Expand Down
Loading