Retrofit คือ HTTP client แบบระบุชนิดสำหรับ Android และ Kotlin พัฒนาโดยบริษัท Square ไลบรารีนี้ช่วยให้เปลี่ยน REST API ให้เป็นอินเทอร์เฟซ Java หรือ Kotlin โดยใช้ annotation ตามข้อมูลจาก Square, 2025 มีการใช้ Retrofit ในหลายพันแอปพลิเคชันเป็นเครื่องมือมาตรฐานสำหรับการทำงานกับคำขอ HTTP
ประเด็นสำคัญ
Retrofit คือไลบรารีสำหรับการโต้ตอบแบบระบุชนิดกับ REST API บนแพลตฟอร์ม Android พัฒนาโดย Square โดยมีวิธีการแบบประกาศในการอธิบายคำขอ HTTP ผ่านอินเทอร์เฟซ Java หรือ Kotlin พร้อม annotation ซึ่งช่วยขจัดความจำเป็นในการแยกวิเคราะห์ JSON ด้วยตนเองและการจัดการการเชื่อมต่อ HTTP โดยสิ้นเชิง
ไลบรารีนี้เกิดขึ้นในปี 2013 เพื่อเป็นทางเลือกแทนโซลูชันที่ยุ่งยากอย่าง AsyncTask และ HttpURLConnection ภายในปี 2025 Retrofit ยังคงเป็นมาตรฐานโดยพฤตินัยสำหรับการสื่อสารเครือข่ายในแอป Android ด้วย ความเรียบง่ายและความปลอดภัยของชนิดข้อมูล จากการสำรวจ JetBrains Developer Ecosystem 2024 นักพัฒนา Android มากกว่า 65% ใช้ Retrofit ในโครงการเชิงพาณิชย์
ความแตกต่างหลักของ Retrofit จากทางเลือกอื่นคือแนวทางการประกาศ: นักพัฒนาอธิบายว่าต้องทำอะไร (เรียก endpoint ใด ส่งพารามิเตอร์ใด) แทนที่จะอธิบายวิธีทำ (วิธีเปิดการเชื่อมต่อ วิธีอ่าน InputStream วิธีแยกวิเคราะห์ JSON) ซึ่งช่วยลดโค้ด boilerplate ลง 60–70% เมื่อเทียบกับการใช้ HttpURLConnection ด้วยตนเอง
หลักการทำงาน Retrofit อาศัยพร็อกซีแบบไดนามิกของ Java เมื่อนักพัฒนาเรียกเมธอดของอินเทอร์เฟซที่มี annotation Retrofit จะสกัดกั้นการเรียกผ่านกลไก Proxy.newProxyInstance และแปลงเป็นคำขอ HTTP กระบวนการทั้งหมดเกิดขึ้นในรันไทม์โดยไม่ต้องสร้างโค้ดในเวลาคอมไพล์
เมื่อสร้างอินสแตนซ์ Retrofit.Builder จะมีการระบุ URL ฐานและโรงงาน converter Builder จะกำหนดค่า OkHttpClient — ตั้งค่ากำหนดเวลา ตัวสกัดกั้น พูลการเชื่อมต่อและแคช เมธอด create(Class) สร้างการใช้งานอินเทอร์เฟซ โดยคืนวัตถุพร็อกซีที่สามารถเรียกได้เหมือนคลาสปกติ
ห่วงโซ่การดำเนินการตามคำขอเป็นดังนี้: annotation ดึงเมธอด HTTP พารามิเตอร์จะถูกแทนที่ใน URL หรือเนื้อหาของคำขอ converter ทำให้เนื้อหาเป็นอนุกรม OkHttp ดำเนินการตามคำขอ converter ทำให้คำตอบกลับเป็นวัตถุ และผลลัพธ์จะถูกส่งคืนในชนิดที่ระบุ แต่ละขั้นตอนถูกแยกออกและสามารถแทนที่ด้วยการใช้งานแบบกำหนดเอง เช่น การแทนที่ OkHttpClient ด้วย MockWebServer สำหรับการทดสอบ หรือการเปลี่ยน converter เมื่อเปลี่ยน API
คุณสมบัติที่สำคัญ — Retrofit ไม่รองรับการส่งข้อมูลแบบสตรีมโดยตรง สำหรับการสตรีม จะใช้ OkHttp ResponseBody เป็นชนิดที่ส่งคืนของเมธอดอินเทอร์เฟซ Retrofit ยังไม่จัดการการยกเลิกคำขอโดยอัตโนมัติ — ในการยกเลิก ต้องเก็บการอ้างอิงไปยัง Call และเรียก cancel() ใน Kotlin ด้วยฟังก์ชัน suspend การยกเลิกคำขอจะเกิดขึ้นโดยอัตโนมัติเมื่อโครูทีนแม่ถูกยกเลิก
Call<T> คือวัตถุที่แทนหนึ่งคำขอ HTTP หลังจากการดำเนินการ (execute หรือ enqueue) Call ไม่สามารถนำกลับมาใช้ใหม่ได้ — สำหรับคำขอซ้ำ ต้องสร้าง Call ใหม่โดยการเรียกเมธอดอินเทอร์เฟซ ซึ่งป้องกันการส่งคำขอเดียวกันสองครั้งโดยไม่ตั้งใจ ซึ่งอาจทำให้เกิดการดำเนินการซ้ำบนเซิร์ฟเวอร์
ใน Kotlin แทนที่จะใช้ Call จะใช้ฟังก์ชัน suspend ซึ่ง จัดการวงจรชีวิตของคำขอโดยอัตโนมัติ Retrofit จะสลับการดำเนินการไปยัง Dispatchers.IO และส่งคืนผลลัพธ์ไปยังโครูทีน ซึ่งช่วยลดโค้ดลง 30–40% เมื่อเทียบกับเวอร์ชัน Call และ Callback
Annotation เป็น กลไกหลัก สำหรับกำหนดค่าคำขอ HTTP ใน Retrofit แต่ละ annotation สอดคล้องกับเมธอด HTTP มาตรฐานและรับพาธสัมพัทธ์ไปยัง endpoint Retrofit รองรับ GET, POST, PUT, DELETE, PATCH, HEAD และ OPTIONS
| Annotation | เมธอด HTTP | วัตถุประสงค์ |
|---|---|---|
| @GET | GET | รับข้อมูลจากเซิร์ฟเวอร์ |
| @POST | POST | สร้างทรัพยากรใหม่ |
| @PUT | PUT | อัปเดตทรัพยากรทั้งหมด |
| @DELETE | DELETE | ลบทรัพยากร |
| @PATCH | PATCH | อัปเดตทรัพยากรบางส่วน |
@Path แทนที่ค่าในส่วน URL: @Path("id") Int id แทนที่ {id} ในพาธ @Query เพิ่มพารามิเตอร์คำค้นหา: @Query("page") Int page กลายเป็น ?page=5 @Body ส่งวัตถุในเนื้อหาคำขอพร้อมการทำให้เป็นอนุกรมอัตโนมัติผ่าน converter ที่เลือก @Header และ @Headers จัดการส่วนหัว HTTP — แบบคงที่หรือไดนามิก
การรวม annotation เหล่านี้เข้าด้วยกัน สามารถอธิบาย endpoint REST ใดก็ได้ ตัวอย่างเช่น สำหรับ endpoint POST /api/users/{id}/posts?limit=10 จำเป็นต้องใช้ @POST, @Path สำหรับ id, @Query สำหรับ limit และ @Body สำหรับวัตถุที่ส่ง Retrofit จะประกอบคำขอ HTTP ที่ถูกต้องโดยอัตโนมัติ นอกจากนี้ยังรองรับ @Url (URL ไดนามิก), @Field (เนื้อหาที่เข้ารหัสแบบฟอร์ม), @Part และ @PartMap สำหรับคำขอแบบหลายส่วนพร้อมไฟล์
มาดู ตัวอย่างเชิงปฏิบัติ — อินเทอร์เฟซสำหรับ GitHub API กัน มีการสร้างอินเทอร์เฟซ Kotlin พร้อมเมธอดสำหรับรับรายการ repositories คลาสข้อมูล Repo อธิบายโครงสร้างของคำตอบ JSON
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>
}
หลังจากอธิบายอินเทอร์เฟซ จะมีการสร้าง อินสแตนซ์ Retrofit ผ่าน Builder URL ฐาน, converter และ OkHttpClient จะถูกกำหนดค่าครั้งเดียวและนำกลับมาใช้ใหม่ผ่านการฉีด dependencies
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)
สำหรับการจัดการ รหัสสถานะ HTTP ที่ยืดหยุ่น ให้ใช้ตัวห่อ Response<T> ซึ่งให้การเข้าถึงรหัสคำตอบ ส่วนหัว และเนื้อหา โดยไม่ต้องโยนข้อยกเว้นเมื่อเกิดข้อผิดพลาด 4xx และ 5xx ซึ่งช่วยให้จัดการ 404 และ 500 ได้โดยไม่ต้องใช้ try-catch
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 คือส่วนประกอบของ Retrofit ที่รับผิดชอบในการแปลงวัตถุเป็นเนื้อหา HTTP และกลับกัน Retrofit ไม่ฝังการทำให้เป็นอนุกรมในแกนกลาง — แต่ใช้แนวทางแบบโมดูลาร์ผ่าน Converter.Factory ซึ่งอนุญาตให้เชื่อมต่อไลบรารีการทำให้เป็นอนุกรมใดก็ได้
Converter ที่เป็นที่นิยมมากที่สุดคือ GsonConverterFactory ของ Google ที่ใช้ไลบรารี Gson ซึ่งใช้งานได้กับโครงการส่วนใหญ่ รองรับ TypeAdapter และ JsonDeserializer แบบกำหนดเอง อย่างไรก็ตาม Gson ใช้การสะท้อนกลับและไม่เคารพความปลอดภัย null ของ Kotlin ซึ่งอาจทำให้เกิด NPE ในฟิลด์ null ที่ไม่คาดคิด
ทางเลือกคือ MoshiConverterFactory ของ Square: เข้มงวดกับชนิดข้อมูลมากขึ้น รองรับ Kotlin ดีกว่า (ความปลอดภัย null ค่าเริ่มต้น) และไม่ต้องใช้การสะท้อนกลับ สำหรับโครงการ Kotlin บริสุทธิ์ Kotlinx Serialization Converter เหมาะสมที่สุด ซึ่งทำงานร่วมกับ annotation @Serializable ในเวลาคอมไพล์ ไม่ใช้การสะท้อนกลับ รองรับ sealed class ค่าเริ่มต้น และหลายแพลตฟอร์ม
การเลือก converter ส่งผลต่อ ประสิทธิภาพและความปลอดภัยของชนิดข้อมูล Gson โดยไม่มีการกำหนดค่าแบบกำหนดเอง สามารถแปลง null เป็นฟิลด์ non-null ของ Kotlin ทำให้เกิด NPE เมื่อเข้าถึง Moshi แก้ปัญหานี้ผ่าน annotation @Json(name) และ failOnUnknown Kotlinx Serialization ปลอดภัยที่สุด — สร้างโค้ดในเวลาคอมไพล์ กำจัดข้อผิดพลาดชนิดข้อมูลในรันไทม์โดยสิ้นเชิง
การขาดการจัดการข้อผิดพลาด HTTP ในฟังก์ชัน suspend เป็นปัญหาที่พบบ่อยที่สุด หากเซิร์ฟเวอร์ส่งคืน 4xx หรือ 5xx Retrofit จะโยน HttpException โดยไม่มี try-catch แอปจะหยุดทำงาน การใช้ Response<T> เป็นชนิดที่ส่งคืนจะแก้ปัญหานี้ โดยอนุญาตให้ตรวจสอบ isSuccessful ก่อนเข้าถึง body
การกำหนดค่าแคชที่ไม่ถูกต้อง ทำให้เกิดการรับส่งข้อมูลมากเกินไป Retrofit ไม่ได้แคชคำตอบด้วยตัวเอง — งานนี้ทำโดย OkHttpClient ผ่าน Cache หากไม่มีแคช แต่ละคำขอจะถูกดำเนินการอย่างสมบูรณ์ แม้ว่าข้อมูลจะไม่เปลี่ยนแปลง การเพิ่มแคชขนาด 10 MB ใน OkHttpClient จะลดการรับส่งข้อมูลลง 40–60% สำหรับคำขอซ้ำของข้อมูลเดียวกัน
การสร้าง Retrofit สำหรับทุกคำขอ เป็นข้อผิดพลาดทั่วไปของผู้เริ่มต้น Retrofit.Builder เป็นการดำเนินการที่ใช้ทรัพยากรมาก ซึ่งรวมถึงการสร้างคลาสพร็อกซีในรันไทม์ แนวปฏิบัติที่ถูกต้องคือการสร้างอินสแตนซ์ Retrofit เดียวและนำกลับมาใช้ใหม่ผ่านเฟรมเวิร์ก DI Hilt, Koin หรือ Dagger จัดเตรียมอินสแตนซ์ซิงเกิลตันของ Retrofit สำหรับทั้งแอป ประหยัดหน่วยความจำและเร่งคำขอ
การละเลย Interceptor สำหรับการอนุญาต เป็นปัญหาที่สี่ แทนที่จะเพิ่มส่วนหัว Authorization ด้วยตนเองในการเรียกแต่ละครั้ง ให้กำหนดค่า Interceptor ระดับโลกใน OkHttpClient Interceptor จะสกัดกั้นทุกคำขอ เพิ่มโทเค็น Bearer และ Authenticator จะจัดการคำตอบ 401 รีเฟรชโทเค็นและทำซ้ำคำขอโดยอัตโนมัติ ซึ่งรวมศูนย์ตรรกะการตรวจสอบสิทธิ์
คำถามที่พบบ่อย
Retrofit คือชั้นที่อยู่เหนือ OkHttp ซึ่งให้ API แบบประกาศผ่าน annotation OkHttp คือ HTTP client ระดับต่ำที่ทำงานโดยตรงกับ Request และ Response Retrofit ทำให้การระบุชนิด การทำให้เป็นอนุกรม และการจัดการคำตอบง่ายขึ้น โดยใช้ OkHttp เป็นการขนส่ง
สำหรับโครงการ Java — GsonConverterFactory สำหรับ Kotlin กับ Moshi — MoshiConverterFactory (ปลอดภัยกว่ากับชนิดข้อมูล) ตัวเลือกที่เหมาะสมที่สุดสำหรับ Kotlin บริสุทธิ์คือ Kotlinx Serialization Converter ทำงานโดยไม่ต้องใช้การสะท้อนกลับ รองรับ sealed class และค่าเริ่มต้น
ใช่ ตั้งแต่เวอร์ชัน 2.6.0 Retrofit รองรับ ฟังก์ชัน suspend ประกาศเมธอดเป็น suspend แล้ว Retrofit จะดำเนินการตามคำขอใน Dispatchers.IO และส่งคืนผลลัพธ์ไปยังโครูทีน ไม่จำเป็นต้องใช้ Call และ enqueue — โค้ดจะกลายเป็นลำดับ
การอนุญาตเพิ่มผ่าน Interceptor ของ OkHttp ใน intercept() ให้เพิ่มส่วนหัว Authorization สำหรับโทเค็นไดนามิก ให้ใช้ Authenticator ของ OkHttp — มันจะสกัดกั้นคำตอบ 401 และรีเฟรชโทเค็นโดยอัตโนมัติ ทำซ้ำคำขอด้วยส่วนหัวใหม่
ไม่ได้ — Retrofit ใช้ OkHttp เป็นเลเยอร์การขนส่งเสมอ OkHttpClient ถูกส่งผ่าน Builder.client() และจัดการกำหนดเวลา ตัวสกัดกั้น แคช และพูลการเชื่อมต่อ หากไม่มี OkHttp Retrofit จะไม่สามารถดำเนินการตามคำขอใด ๆ ได้
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม