Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

week7: 서버통신 심화 및 권한 요청, 저장소 활용 #17

Open
wants to merge 9 commits into
base: develope-xml
Choose a base branch
from
Open
11 changes: 11 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.0'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android'
id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
}

Properties properties = new Properties()
Expand Down Expand Up @@ -77,4 +80,12 @@ dependencies {
// Glide 라이브러리 추가
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

// Hilt
implementation 'com.google.dagger:hilt-android:2.48'
kapt 'com.google.dagger:hilt-compiler:2.48'
Comment on lines +84 to +86
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제 꿀팁공유 열심히 따라해보셨군요~~ 민재님을 위해 썼었답니다 ㅋㅋㅋㅋㅋ

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

없었으면 이번 과제 못했습니다.. 압도적 감사

}

kapt {
correctErrorTypes = true
}
7 changes: 4 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@


<application
android:name=".NowSopt"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -18,18 +19,18 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".signIn.SignInActivity"
android:name=".ui.signIn.SignInActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".signUp.SignUpActivity"
android:name=".ui.signUp.SignUpActivity"
android:exported="false"/>
<activity
android:name=".main.MainActivity"
android:name=".ui.main.MainActivity"
android:exported="false"/>
</application>

Expand Down
21 changes: 21 additions & 0 deletions app/src/main/java/com/sopt/now/NowSopt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.sopt.now

import android.app.Application
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class NowSopt : Application() {
override fun onCreate() {
super.onCreate()
appContext = applicationContext

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}

companion object {
lateinit var appContext: Context
private set
}
}
77 changes: 77 additions & 0 deletions app/src/main/java/com/sopt/now/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.sopt.now.data.di

import android.util.Log
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.sopt.now.data.service.AuthService
import com.sopt.now.data.service.FriendService
import com.sopt.now.data.service.UserService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.serialization.json.Json
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
private const val CONTENT_TYPE = "application/json"
private val json: Json =
Json {
ignoreUnknownKeys = true
}

private fun getLogOkHttpClient(): Interceptor {
val loggingInterceptor =
HttpLoggingInterceptor { message ->
Log.d("Retrofit2", "CONNECTION INFO -> $message")
}
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}

private val okHttpClient =
OkHttpClient.Builder()
.addInterceptor(getLogOkHttpClient())
.build()

@Singleton
@Provides
fun provideRetrofit(): Retrofit.Builder {
return Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory(CONTENT_TYPE.toMediaType()))
}

@Singleton
@Provides
fun provideAuthService(
retrofitBuilder: Retrofit.Builder,
@AuthBaseUrl url: String,
): AuthService {
return retrofitBuilder.baseUrl(url).build().create(AuthService::class.java)
}

@Singleton
@Provides
fun provideUserService(
retrofitBuilder: Retrofit.Builder,
@AuthBaseUrl url: String,
): UserService {
return retrofitBuilder.baseUrl(url).build().create(UserService::class.java)
}

@Singleton
@Provides
fun provideFriendService(
retrofitBuilder: Retrofit.Builder,
@FriendBaseUrl url: String,
): FriendService {
return retrofitBuilder.baseUrl(url).build().create(FriendService::class.java)
}
}
28 changes: 28 additions & 0 deletions app/src/main/java/com/sopt/now/data/di/UrlModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.sopt.now.data.di

import com.sopt.now.BuildConfig
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Qualifier

@Module
@InstallIn(SingletonComponent::class)
object UrlModule {
@AuthBaseUrl
@Provides
fun provideAuthBaseUrl(): String = BuildConfig.AUTH_BASE_URL

@FriendBaseUrl
@Provides
fun provideFriendBaseUrl(): String = BuildConfig.FRIEND_BASE_URL
}

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class AuthBaseUrl

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class FriendBaseUrl
25 changes: 25 additions & 0 deletions app/src/main/java/com/sopt/now/data/repository/AuthRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.sopt.now.data.repository

import com.sopt.now.data.request.RequestSignInDto
import com.sopt.now.data.request.RequestSignUpDto
import com.sopt.now.data.response.ResponseSignInDto
import com.sopt.now.data.response.ResponseSignUpDto
import com.sopt.now.data.service.AuthService
import retrofit2.Response
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AuthRepository
@Inject
constructor(
private val authService: AuthService,
) {
suspend fun signUp(request: RequestSignUpDto): Response<ResponseSignUpDto> {
return authService.signUp(request)
}
Comment on lines +18 to +20

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[2]
레포지토리 패턴은 데이터 소스를 추상화하는데 의미가 있습니다.
즉 뷰단에서는 이 값들이 우리 서버에서 왔는지, 로컬 디비에서 왔는지 혹은 파이어베이스에서 왔는지 관심이 없다는 뜻이죠.
그런 레포지토리가 레트로핏의 Response 형태로 값을 반환하게 된다면 네트워크 통신의 결과물이라는 의미를 내포하게 됩니다.
그러므로 Response로 래핑된 형태가 아닌 ResponseSignUpDto의 형태로 반환해보는 것은 어떨까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와,, Response 와 ResponseSignUpDto 가 그런 차이가 있었는지는 생각도 못했습니다. 그럼 ResponseSignUpDto 는 서버나 로컬디비, 파이어베이스 어디서 받아와도 가능한 형태겠군요. 레포지토리 패턴에 대해 다시 한번 생각해보겠습니다. 너무 도움 많이 됐습니다! 감사합니다!


suspend fun signIn(request: RequestSignInDto): Response<ResponseSignInDto> {
return authService.signIn(request)
}
Comment on lines +18 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 따라하셨는데요? ㅋㅋㅋㅋㅋㅋ

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과찬이십니다 허허 이제 이해하는 일만 남았네요

}
18 changes: 18 additions & 0 deletions app/src/main/java/com/sopt/now/data/repository/FriendRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.sopt.now.data.repository

import com.sopt.now.data.response.ResponseFriendsInfoDto
import com.sopt.now.data.service.FriendService
import retrofit2.Response
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class FriendRepository
@Inject
constructor(
private val friendService: FriendService,
) {
suspend fun getFriendsInfo(i: Int): Response<ResponseFriendsInfoDto> {
return friendService.getFriendsInfo(2)
}
}
SYAAINN marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 18 additions & 0 deletions app/src/main/java/com/sopt/now/data/repository/UserRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.sopt.now.data.repository

import com.sopt.now.data.response.ResponseUserInfoDto
import com.sopt.now.data.service.UserService
import retrofit2.Response
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class UserRepository
@Inject
constructor(
private val userService: UserService,
) {
suspend fun getUserInfo(memberId: Int): Response<ResponseUserInfoDto> {
return userService.getUserInfo(memberId)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sopt.now.signIn
package com.sopt.now.data.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sopt.now.signUp
package com.sopt.now.data.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.sopt.now.main.homeFragment
package com.sopt.now.data.response

import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseFriendsInfoDto(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sopt.now.signIn
package com.sopt.now.data.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sopt.now.signUp
package com.sopt.now.data.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sopt.now.main
package com.sopt.now.data.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/java/com/sopt/now/data/service/AuthService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.sopt.now.data.service

import com.sopt.now.data.request.RequestSignInDto
import com.sopt.now.data.request.RequestSignUpDto
import com.sopt.now.data.response.ResponseSignInDto
import com.sopt.now.data.response.ResponseSignUpDto
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POST

interface AuthService {
@POST("member/join")
suspend fun signUp(
@Body request: RequestSignUpDto,
): Response<ResponseSignUpDto>

@POST("member/login")
suspend fun signIn(
@Body request: RequestSignInDto,
): Response<ResponseSignInDto>
}
13 changes: 13 additions & 0 deletions app/src/main/java/com/sopt/now/data/service/FriendService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sopt.now.data.service

import com.sopt.now.data.response.ResponseFriendsInfoDto
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

interface FriendService {
@GET("/api/users")
suspend fun getFriendsInfo(
@Query("page") page: Int,
): Response<ResponseFriendsInfoDto>
}
13 changes: 13 additions & 0 deletions app/src/main/java/com/sopt/now/data/service/UserService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sopt.now.data.service

import com.sopt.now.data.response.ResponseUserInfoDto
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header

interface UserService {
@GET("member/info")
suspend fun getUserInfo(
@Header("memberId") memberId: Int,
): Response<ResponseUserInfoDto>
}
Loading