📱 Android

[Android] Multipart / Presigned url

콩드로이드 2024. 11. 14. 22:14

파일업로드 방식 2가지에 대해 알아보겠습니다


 MultiPart

- 여러 데이터 조각을 하나의 HTTP 요청으로 전송하는 방식

- 안드로이드에서는 Retrofit, OkHttp 등의 라이브러리를 통해 쉽게 구현가능한데, 파일 업로드와 텍스트 데이터 전송에 주로 사용됩니다

 

MultiPart의 방식

- 클라이언트 → 서버 : 클라이언트는 파일을 여러 부분으로 나누어 서버에 전송

- 서버 → 저장소 : 서버는 클라이언트로 파일의 각 부분을 수신한 후, 이를 하나의 파일로 조합하여 저장소에 저장

 

@MultiPart annotation을 사용하면 돼요 

interface ApiService {
    @Multipart
    @POST("upload")
    fun uploadFile(
        @Part file: MultipartBody.Part,
        @Part("description") description: RequestBody
    ): Call<ResponseBody>
}

 

선언된 api를 실행하려면 아래와 같이 실행하면 됩니다 

//이미지 파일 
val file = File("path/to/your/file.jpg")
val requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file)

//동영상 파일
val videoFile = File("path/to/your/video.mp4")
val requestBody = RequestBody.create(MediaType.parse("video/mp4"), videoFile)

// MultipartBody.Part 생성
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
val videoBody = MultipartBody.Part.createFormData("video", videoFile.name, requestBody)

// API 호출
val call = apiService.uploadFile(body, videoBody)

 

여기서 createFormData의 원형에 대해 살펴보자면

fun createFormData(
    name: String,
    filename: String?,
    body: RequestBody
): MultipartBody.Part
  1. name:
    • 서버에서 이 데이터를 식별하는 데 사용
  2. filename:
    • 업로드할 파일명
  3. body:
    • 업로드할 파일의 내용, 파일의 MIME 타입 포함

MutliPart의 장단점은 아래와 같습니다 

장점

- 서버가 파일의 유효성, 보안 검사 수행 -> 에러 발생 시 서버에서 처리 가능

단점

- 모든 파일 업로드가 서버를 거침 -> 부하 증가 

- 클라이언트 -> 서버 , 서버 -> 저장소의 과정을 거치므로 시간이 지연될 수 있음 

 


 Presigned Url

- 특정 시간 동안 유효한 URL로, 이를 통해 인증 없이도 파일을 업로드

- AWS S3와 같은 클라우드 스토리지 서비스에서 자주 사용

- 서버에서 url 받아오는 과정이 필요

 

Presigned Url의 방식

- 서버에 presigned url 요청 

- 클라이언트 -> 저장소 :  presigned URL을 사용하여 직접 저장소에 파일 업로드

 

아래의 예시는 서버에서 url을 받아왔다는 걸 가정합니다

fun uploadFileToPresignedUrl(presignedUrl: String, filePath: String): Response? {
    val file = File(filePath)
    val requestBody = RequestBody.create(MediaType.parse("image/jpeg"), file)

    val request = Request.Builder()
        .url(presignedUrl)
        .put(requestBody)
        .build()

    val client = OkHttpClient()
    return client.newCall(request).execute()
}


fun main() {
    val presignedUrl = "YOUR_PRESIGNED_URL" // 서버에서 받은 presigned URL
    val filePath = "path/to/your/file.jpg"

    val response = uploadFileToPresignedUrl(presignedUrl, filePath)
    if (response != null && response.isSuccessful) {
        println("File uploaded successfully!")
    } else {
        println("File upload failed: ${response?.message()}")
    }
}

 

Presigned url 방식의 장단점은 아래와 같습니다 

장점

- 서버 부하 감소 (클라이언트가 직접 저장소에 접근)

- 빠른 업로드 속도

단점

- Presigned URL이 인증값을 포함한 url이라 유출 주의

- 서버가 업로드 과정을 직접 관리하지 않기 때문에, 파일의 유효성 및 보안 검사를 클라이언트에서 수행