Retrofit: nó là gì, các tính năng của HTTP Client Android

Tác giả: IT Sectr Đã đăng: 2026-03-07 Thời gian đọc: 8 phút

Retrofit là một HTTP client được định kiểu cho Android và Kotlin, được phát triển bởi công ty Square. Thư viện này cho phép biến REST API thành một giao diện Java hoặc Kotlin thông qua các annotation. Theo Square, 2025, Retrofit được sử dụng trong hàng nghìn ứng dụng như một công cụ tiêu chuẩn để làm việc với các yêu cầu HTTP.

Những điểm chính

  • Retrofit là HTTP client được định kiểu từ Square cho Android và Kotlin với API khai báo
  • Annotation @GET, @POST, @Path, @Query mô tả các yêu cầu HTTP mà không cần mã boilerplate
  • Converter Gson, Moshi và Kotlinx Serialization chuyển đổi JSON thành các đối tượng Kotlin
  • OkHttp là lớp truyền tải bắt buộc thực thi tất cả các yêu cầu HTTP bên trong Retrofit
  • Hàm Suspend tích hợp Retrofit với coroutine Kotlin cho các lệnh gọi bất đồng bộ

Retrofit là gì?

Retrofit là một thư viện để tương tác có định kiểu với REST API trên nền tảng Android, được phát triển bởi Square. Nó cung cấp một cách khai báo để mô tả các yêu cầu HTTP thông qua giao diện Java hoặc Kotlin với annotation, loại bỏ hoàn toàn nhu cầu phân tích JSON thủ công và quản lý kết nối HTTP.

Thư viện xuất hiện vào năm 2013 như một giải pháp thay thế cho các giải pháp cồng kềnh như AsyncTask và HttpURLConnection. Đến năm 2025, Retrofit vẫn là tiêu chuẩn thực tế cho giao tiếp mạng trong các ứng dụng Android nhờ sự đơn giản và an toàn kiểu dữ liệu. Theo khảo sát JetBrains Developer Ecosystem 2024, hơn 65% nhà phát triển Android sử dụng Retrofit trong các dự án thương mại.

Sự khác biệt chính của Retrofit so với các giải pháp thay thế là cách tiếp cận khai báo: nhà phát triển mô tả việc cần làm (gọi endpoint nào, truyền tham số nào) thay vì cách thực hiện (cách mở kết nối, cách đọc InputStream, cách phân tích JSON). Điều này giảm mã boilerplate từ 60–70% so với việc sử dụng thủ công HttpURLConnection.

Cách Retrofit hoạt động

Nguyên lý hoạt động của Retrofit dựa trên proxy động Java. Khi nhà phát triển gọi một phương thức của giao diện có annotation, Retrofit chặn lệnh gọi thông qua cơ chế Proxy.newProxyInstance và chuyển đổi nó thành một yêu cầu HTTP. Toàn bộ quá trình diễn ra tại thời gian chạy mà không cần tạo mã tại thời gian biên dịch.

Khi tạo một phiên bản Retrofit.Builder, URL cơ sở và nhà máy converter được chỉ định. Builder cấu hình OkHttpClient — đặt thời gian chờ, bộ chặn, nhóm kết nối và bộ nhớ đệm. Phương thức create(Class) tạo ra cách triển khai của giao diện, trả về một đối tượng proxy có thể được gọi như một lớp thông thường.

Chuỗi thực thi yêu cầu như sau: annotation trích xuất phương thức HTTP, các tham số được thay thế vào URL hoặc nội dung yêu cầu, converter tuần tự hóa nội dung, OkHttp thực thi yêu cầu, converter giải tuần tự hóa phản hồi và kết quả được trả về ở kiểu đã chỉ định. Mỗi giai đoạn được cô lập và có thể được thay thế bằng cách triển khai tùy chỉnh, ví dụ thay thế OkHttpClient bằng MockWebServer để kiểm thử hoặc thay đổi converter khi thay đổi API.

Một tính năng quan trọng — Retrofit không hỗ trợ truyền dữ liệu trực tiếp theo luồng. Để truyền luồng, OkHttp ResponseBody được sử dụng làm kiểu trả về của phương thức giao diện. Retrofit cũng không tự động quản lý việc hủy yêu cầu — để hủy, cần giữ tham chiếu đến Call và gọi cancel(). Trong Kotlin với hàm suspend, việc hủy yêu cầu diễn ra tự động khi coroutine cha bị hủy.

Vòng đời của đối tượng Call

Call<T> là một đối tượng đại diện cho một yêu cầu HTTP. Sau khi thực thi (execute hoặc enqueue), Call không thể được sử dụng lại — để thực hiện yêu cầu lặp lại, cần tạo một Call mới bằng cách gọi phương thức giao diện. Điều này ngăn chặn việc vô tình gửi cùng một yêu cầu hai lần, có thể dẫn đến các thao tác trùng lặp trên máy chủ.

Trong Kotlin, thay vì Call, các hàm suspend được sử dụng, chúng tự động quản lý vòng đời của yêu cầu. Retrofit chuyển việc thực thi sang Dispatchers.IO và trả kết quả cho coroutine. Điều này giảm mã 30–40% so với phiên bản sử dụng Call và Callback.

Annotation Retrofit cho các phương thức HTTP

Annotation là cơ chế chính để cấu hình các yêu cầu HTTP trong Retrofit. Mỗi annotation tương ứng với một phương thức HTTP tiêu chuẩn và chấp nhận đường dẫn tương đối đến endpoint. Retrofit hỗ trợ GET, POST, PUT, DELETE, PATCH, HEAD và OPTIONS.

AnnotationPhương thức HTTPMục đích
@GETGETLấy dữ liệu từ máy chủ
@POSTPOSTTạo tài nguyên mới
@PUTPUTCập nhật toàn bộ tài nguyên
@DELETEDELETEXóa tài nguyên
@PATCHPATCHCập nhật một phần tài nguyên

Annotation tham số yêu cầu

@Path thay thế một giá trị vào đoạn URL: @Path("id") Int id thay thế {id} trong đường dẫn. @Query thêm tham số truy vấn: @Query("page") Int page biến thành ?page=5. @Body truyền một đối tượng trong nội dung yêu cầu với tuần tự hóa tự động qua converter đã chọn. @Header@Headers quản lý tiêu đề HTTP — tĩnh hoặc động.

Bằng cách kết hợp các annotation này, có thể mô tả bất kỳ endpoint REST nào. Ví dụ, cho endpoint POST /api/users/{id}/posts?limit=10 cần @POST, @Path cho id, @Query cho limit và @Body cho đối tượng được truyền. Retrofit sẽ tự động tập hợp một yêu cầu HTTP chính xác. Ngoài ra còn hỗ trợ @Url (URL động), @Field (nội dung mã hóa biểu mẫu), @Part và @PartMap cho các yêu cầu đa phần với tệp tin.

Ví dụ mã Retrofit trong Kotlin

Hãy xem một ví dụ thực tế — một giao diện cho API GitHub. Một giao diện Kotlin được tạo với phương thức lấy danh sách kho lưu trữ. Lớp dữ liệu Repo mô tả cấu trúc phản hồi JSON.

kotlin
data class Repo(
    val name: String,
    val description: String?,
    val stargazersCount: Int,
    val forksCount: Int
)

interface GitHubApi {
    @GET("users/{user}/repos")
    suspend fun getRepos(
        @Path("user") user: String,
        @Query("sort") sort: String = "updated"
    ): List<Repo>
}

Sau khi mô tả giao diện, một phiên bản Retrofit được tạo thông qua Builder. URL cơ sở, converter và OkHttpClient được cấu hình một lần và tái sử dụng thông qua tiêm phụ thuộc.

kotlin
val retrofit = Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .client(OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .build())
    .build()

val api = retrofit.create(GitHubApi::class.java)

Xử lý phản hồi với wrapper Response

Để xử lý linh hoạt mã trạng thái HTTP, hãy sử dụng wrapper Response<T>. Nó cung cấp quyền truy cập vào mã phản hồi, tiêu đề và nội dung mà không ném ngoại lệ khi gặp lỗi 4xx và 5xx. Điều này cho phép xử lý 404 và 500 mà không cần try-catch.

kotlin
interface GitHubApi {
    @GET("users/{user}/repos")
    suspend fun getRepos(
        @Path("user") user: String
    ): Response<List<Repo>>
}

val response = api.getRepos("octocat")
if (response.isSuccessful) {
    println(response.body()?.size)
} else {
    Log.e("API", "Error: ${response.code()}")
}

Converter và tuần tự hóa trong Retrofit

Converter là các thành phần của Retrofit chịu trách nhiệm chuyển đổi đối tượng thành nội dung HTTP và ngược lại. Retrofit không nhúng tuần tự hóa vào lõi của nó — thay vào đó, nó sử dụng cách tiếp cận mô-đun thông qua Converter.Factory, cho phép cắm bất kỳ thư viện tuần tự hóa nào.

Converter phổ biến nhất là GsonConverterFactory của Google dựa trên thư viện Gson. Nó hoạt động với hầu hết các dự án, hỗ trợ TypeAdapter và JsonDeserializer tùy chỉnh. Tuy nhiên, Gson sử dụng phản chiếu và không tôn trọng tính an toàn null của Kotlin, có thể dẫn đến NPE khi gặp trường null bất ngờ.

Một giải pháp thay thế là MoshiConverterFactory của Square: nghiêm ngặt hơn với kiểu dữ liệu, hỗ trợ Kotlin tốt hơn (an toàn null, giá trị mặc định) và không cần phản chiếu. Đối với các dự án Kotlin thuần túy, Kotlinx Serialization Converter là tối ưu, hoạt động với annotation @Serializable tại thời gian biên dịch. Nó không sử dụng phản chiếu, hỗ trợ sealed class, giá trị mặc định và đa nền tảng.

Việc lựa chọn converter ảnh hưởng đến hiệu suất và an toàn kiểu dữ liệu. Gson mà không có cấu hình tùy chỉnh có thể giải tuần tự hóa null thành trường non-null của Kotlin, gây ra NPE khi truy cập. Moshi giải quyết vấn đề này thông qua annotation @Json(name) và failOnUnknown. Kotlinx Serialization là an toàn nhất — nó tạo mã tại thời gian biên dịch, loại bỏ hoàn toàn lỗi kiểu tại thời gian chạy.

Lỗi thường gặp khi làm việc với Retrofit

Thiếu xử lý lỗi HTTP trong hàm suspend là vấn đề phổ biến nhất. Nếu máy chủ trả về 4xx hoặc 5xx, Retrofit ném HttpException. Không có try-catch, ứng dụng sẽ bị treo. Sử dụng Response<T> làm kiểu trả về giải quyết vấn đề này, cho phép kiểm tra isSuccessful trước khi truy cập nội dung.

Cấu hình bộ nhớ đệm không đúng dẫn đến lưu lượng truy cập quá mức. Retrofit không tự lưu trữ phản hồi — nhiệm vụ này do OkHttpClient thực hiện thông qua Cache. Không có bộ nhớ đệm, mỗi yêu cầu được thực thi đầy đủ, ngay cả khi dữ liệu không thay đổi. Thêm bộ nhớ đệm 10 MB trong OkHttpClient giảm lưu lượng 40–60% khi yêu cầu lặp lại cùng một thông tin.

Tạo Retrofit cho mỗi yêu cầu là lỗi thường gặp của người mới bắt đầu. Retrofit.Builder là một thao tác tốn tài nguyên bao gồm việc tạo lớp proxy tại thời gian chạy. Thực hành đúng là tạo một phiên bản Retrofit duy nhất và tái sử dụng nó thông qua các framework DI. Hilt, Koin hoặc Dagger cung cấp một phiên bản singleton của Retrofit cho toàn bộ ứng dụng, tiết kiệm bộ nhớ và tăng tốc yêu cầu.

Bỏ qua Interceptor để ủy quyền là vấn đề thứ tư. Thay vì thêm thủ công tiêu đề Authorization vào mỗi lệnh gọi, hãy cấu hình một Interceptor toàn cục trong OkHttpClient. Interceptor chặn mọi yêu cầu, thêm mã thông báo Bearer, và Authenticator xử lý phản hồi 401, làm mới mã thông báo và tự động lặp lại yêu cầu. Điều này tập trung hóa logic xác thực.

Các câu hỏi thường gặp

Retrofit khác OkHttp như thế nào?

Retrofit là một lớp bọc trên OkHttp, cung cấp API khai báo thông qua annotation. OkHttp là HTTP client cấp thấp làm việc trực tiếp với Request và Response. Retrofit đơn giản hóa việc định kiểu, tuần tự hóa và xử lý phản hồi, sử dụng OkHttp làm phương tiện truyền tải.

Nên chọn converter nào cho Retrofit?

Cho dự án Java — GsonConverterFactory. Cho Kotlin với Moshi — MoshiConverterFactory (an toàn hơn về kiểu). Lựa chọn tối ưu cho Kotlin thuần túy là Kotlinx Serialization Converter. Nó hoạt động không cần phản chiếu, hỗ trợ sealed class và giá trị mặc định.

Retrofit có hỗ trợ coroutine không?

Có, từ phiên bản 2.6.0 Retrofit hỗ trợ hàm suspend. Khai báo phương thức là suspend, và Retrofit sẽ thực thi yêu cầu trên Dispatchers.IO, trả kết quả về coroutine. Không cần sử dụng Call và enqueue — mã trở nên tuần tự.

Làm thế nào để thiết lập ủy quyền trong Retrofit?

Ủy quyền được thêm thông qua Interceptor của OkHttp. Trong intercept(), thêm tiêu đề Authorization. Đối với mã thông báo động, sử dụng Authenticator của OkHttp — nó chặn phản hồi 401 và tự động làm mới mã thông báo, lặp lại yêu cầu với tiêu đề mới.

Có thể sử dụng Retrofit mà không có OkHttp không?

Không — Retrofit luôn sử dụng OkHttp làm lớp truyền tải. OkHttpClient được truyền qua Builder.client() và quản lý thời gian chờ, bộ chặn, bộ nhớ đệm và nhóm kết nối. Không có OkHttp, Retrofit không thể thực thi bất kỳ yêu cầu nào.

Tổng kết

  • Retrofit là HTTP client được định kiểu từ Square cho Android và Kotlin với API khai báo dựa trên annotation
  • Annotation @GET, @POST, @Path, @Query và @Body mô tả các yêu cầu REST mà không cần mã boilerplate
  • Proxy động Java chuyển đổi lệnh gọi phương thức giao diện thành yêu cầu HTTP tại thời gian chạy
  • Converter Gson, Moshi và Kotlinx Serialization cung cấp tuần tự hóa JSON thành đối tượng
  • OkHttp là lớp truyền tải bắt buộc với bộ chặn, bộ nhớ đệm và nhóm kết nối
  • Hàm Suspend tích hợp các lệnh gọi HTTP bất đồng bộ với coroutine Kotlin
  • Wrapper Response xử lý lỗi HTTP 4xx và 5xx mà không có ngoại lệ chưa được xử lý

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm