เราใช้เทคโนโลยี เช่น ชุดติดตั้งเพิ่มและวอลเลย์มานานเกินไป และอุตสาหกรรมก็ได้ปรับเปลี่ยนสิ่งเหล่านี้อย่างมีประสิทธิภาพเช่นกัน อย่างไรก็ตาม ด้วยความนิยมที่เพิ่มขึ้นอย่างมากของ Kotlin ในหมู่นักพัฒนาซอฟต์แวร์ Android ทำให้มี API ใหม่สำหรับการโทรผ่านเครือข่ายใน Kotlin: Ktor-client

JetBrains กำลังพัฒนา Kotlin อย่างรวดเร็วทุกวัน เป็นหนึ่งในภาษาที่ได้รับความนิยมมากที่สุดในโลกซึ่งครองใจนักพัฒนา Android อย่างไรก็ตาม พวกเขาไม่ได้จำกัดอยู่แค่นั้น นอกจากนี้เรายังสามารถสร้างเซิร์ฟเวอร์แบ็กเอนด์ด้วย Kotlin ด้วย API ชื่อ Ktor และ Ktor-client เป็นเวอร์ชันไคลเอนต์ของสิ่งนี้

การตั้งค่า Ktor-client

ตามปกติ เราจำเป็นต้องติดตั้งการขึ้นต่อกันสำหรับ Ktor-client สำหรับบทช่วยสอนนี้ เราจะใช้การอ้างอิงต่อไปนี้:

def ktor_version = "1.6.8"
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-android:$ktor_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
implementation "io.ktor:ktor-client-logging:$ktor_version"
implementation "ch.qos.logback:logback-classic:1.2.9"

Ktor-clientส่งเสริมการใช้งานโมดูลการใช้งาน เพื่อให้เราใช้เฉพาะโมดูลที่จำเป็นเท่านั้น ไม่ใช่ทุกอย่างที่มีอยู่ใน Ktor

การสร้างอินเทอร์เฟซ

แม้ว่าจะใช้ Ktor-client แต่ก็ไม่จำเป็นต้องสร้างอินเทอร์เฟซ แต่การใช้รูปแบบการออกแบบนี้ถือเป็นแนวปฏิบัติที่ดี

interface ApiService {
  suspend fun getPost(id: String): Response<PostDto>
  suspend fun createPost(post: Post): Response<PostDto>
}

และตอนนี้เราสามารถใช้อินเทอร์เฟซนี้ในคลาสที่เป็นรูปธรรมได้แล้ว นี่คือที่ที่เราจะทำการโทรผ่านเครือข่ายจริง

class ApiServiceImpl(
  private val client: HttpClient
) : ApiService {
  override suspend fun getPost(id: String): Response<PostDto> {
    return try {
      val response = client.get<PostDto> {
        url("$BASE_URL/posts/$id/?key=value")
      }
      return Response.Success(response)
    } catch (e: RedirectResponseException) { // 3xx 
      Response.Error(e.response.status.description)
    } catch (e: ClientRequestException) { // 4xx
      Response.Error(e.response.status.description)
    } catch (e: ServerResponseException) { // 5xx
      Response.Error(e.response.status.description)
    }
  }
  [...]
}

Ktor-clientเป็นไลบรารีที่ใช้ Kotlin ซึ่งใช้คุณสมบัติทั้งหมดที่มีให้ ในการโทร GET HTTP เราใช้ฟังก์ชัน suspend fun get() บนวัตถุ client ฟังก์ชันจะแยกวิเคราะห์ข้อมูลที่เข้ามาเป็นพารามิเตอร์ทั่วไป ฟังก์ชันแลมบ์ดาของตัวสร้างมีเมธอด url() ที่จะรับ String URL พร้อมด้วยพารามิเตอร์เส้นทางและพารามิเตอร์การค้นหา ซึ่งเป็น URL แบบดิบ

การสร้างวัตถุไคลเอนต์

โดยปกติ ฉันขอแนะนำให้คุณทำเช่นนี้ด้วย Dependency Injection แต่สำหรับตอนนี้ ฉันจะสร้าง companion object ภายในอินเทอร์เฟซ ApiService

interface ApiService {
  [...]
  companion object {
    val client = HttpClient(Android) {
      install(Logging) {
        level = LogLevel.ALL
      }            
      install(JsonFeature) {                
        serializer = KotlinxSerializer()
      }
    }
  }
}

ห่อมันขึ้นมา

ตอนนี้คุณสามารถสรุปทุกอย่างและเริ่มการโทรผ่านเครือข่ายได้แล้ว สมมติว่าคุณต้องการรับโพสต์ทุกครั้งที่ผู้ใช้คลิกที่ปุ่ม:

btnGetPost.setOnClickListener { _ ->
  lifecycleScope.launch {
    ApiService.client.use { 
      val service = ApiServiceImpl(it)
  
      when (val response = service.getPost("2")) {
        is Response.Success -> { /* do something */ }
        is Response.Error -> toast(response.message)
      }
    }
  }
}

ทำการร้องขอ POST

ซึ่งง่ายพอๆ กับการส่งคำขอ get

override suspend fun createPost(post: Post): Response<PostDto> {
  try {
    val response = client.post<PostDto> {
      url("$BASE_URL/posts")
      contentType(ContentType.Application.Json)
      setBody(post)
    }
   } catch ([...]) {
     [ same as in the get function ]
   }
}

เราใช้วิธี post แทน get เราระบุ Content-Type และส่งเนื้อหาคำขอ

หมายเหตุเบ็ดเตล็ด

  1. ตรวจสอบให้แน่ใจว่า data classs ทั้งหมดที่ใช้ควรทำเครื่องหมายด้วยคำอธิบายประกอบ @kotlinx.serialization.Serializable
  2. คลาส Response ที่ใช้ในโค้ดข้างต้นมีดังนี้:
sealed class Response<T> {    
  data class Success<T>(val data: T) : Response<T>()    
  data class Error<T>(val message: String) : Response<T>()
}

3. อย่าลืมเพิ่มสิทธิ์ INTERNET ในไฟล์ AndroidManifest ของคุณ

บทสรุป

Ktor-client กำหนดค่าได้ง่ายมากและใช้งานง่ายมาก ไม่มีคำอธิบายประกอบสำหรับวิธี HTTP หรือบางส่วนของ URL เป็นการเรียกคำขอเครือข่ายธรรมดาธรรมดาเพื่อส่งคืนออบเจ็กต์คลาสข้อมูลที่เราต้องใช้งาน