How to handle HTTP status code in Moya

Error 404 Page Not Found …

ก่อนอื่นต้องบอกว่า Library อย่าง Moya เป็นที่นิยมในการทำ Request API ในแอพ iOS แต่ส่วนใหญ่ก็มักจะเขียน code ตาม sample project ที่ Moya แนะนำไว้แบบเบสิคๆ … บางคนก็จะคิดตามว่า กูทำให้มันใช้งานได้ก็ดีแค่ไหนแล้วว หื้ออ … 🤣

ซึ่งมันก็ไม่ได้ผิดอะไรนะ ทำงานได้ถูกต้องด้วย ได้รับ response ตามที่ต้องการ
ถ้า success ก็เอา JSON ที่ได้ไปทำเป็น Model
ถ้า failure ก็ handle status code มันตรงนั้นไม่เห็นต้องทำอะไรเลย จ๊บบบบ …

ตัวอย่าง provider

แต่เดี๋ยวก่อนนะ … เห็นอะไรใน code นี้รึป่าว ? 🤔

เราต้องทำการ check เพื่อจัดการกับ status code ที่ไม่อยู่ในช่วงแล้วทำอะไรสักอย่างหนึ่ง เช่น ถ้า 401 (Unauthorized) ก็มักจะให้ user login ใหม่

หนึ่ง request ต้อง handle status code ถึงสองที่ ซึ่งส่วนใหญ่ก็จะ handle เหมือนกันอยู่แล้ว เช่นโชว์ alert view บอก User อย่างดีหน่อยก็ทำที่กด Retry อะไรก็ว่ากันไป

สิ่งแรกที่คิดขึ้นมาในหัวก็คือ copy แม่งงง … อะไม่เป็นไรแค่สองที่เอง โธ่เอ้ยย

แต่ในโปรเจคนึงมันมี request API เดียวซะที่ไหนล่ะ … มีเป็นสิบๆ แต่ละที่ก็ต้อง handle อีกสองที่ รวมๆแล้วก็เป็นร้อยอะ ของฝากนักกอล์ฟเลยทีนี้ copy เก่งงงง

ซึ่งมันไม่ดี โปรแกรมเมอร์เค้ารู้ เค้าไม่ทำกันหรอก ไม่ใช่ไม่ copy นะ ไม่ handle แม่งเลย ทิ้งมันไว้ตรง TODO นั้นแหละ ฮ่าๆๆ 😂

// TODO: handle the error == best. comment. ever.

มาถึงตรงนี้แล้วผมเชื่อว่าหลายๆคนคงอยากรู้กันว่า มันจะมีวิธีไหนอีกบ้าง ที่จะ handle status code เมื่อ HTTP request error ทำที่เดียวจบ “แบบวร้ายๆ” อีกแล้ว


มาครับมา เรามาทำในสิ่งที่โลกจะต้องจดจำกันดีกว่า … หื้อออ

อย่างแรก Moya นั้นมี ValidationTypeให้เราใช้ ตามนี้

ซึ่งถ้าเราไม่ได้ implement มันจะมีค่าเป็น none ทำให้ เวลาเราได้รับ response มันจะไม่ valid status code ให้ ไม่ว่าจะเป็นค่าอะไรมันก็เข้าไปใน success หมด

ดังนั้นให้เราไปเพิ่ม code นี้ใน service ของเราซะ ถ้าในกรณีที่แต่ละ case ต้องการ valid ไม่เหมือนกันก็ให้เพิ่ม case เข้าไป

* ถ้าเป็น Moya version เก่าหน่อยจะเป็น Bool

คราวนี้ถ้า response กลับมามันจะทำการ valid ให้ก่อนถ้าอยู่ในช่วงก็จะเข้าไป success ถ้าไม่ก็ไปที่ failure ตอนนี้ในหนึ่ง request เราก็จะ handle status code แค่ที่เดียวแล้ว ดีขึ้นมาหน่อย แต่ก็ยังมีต้องทำทุกๆ request อยู่ดี

มาถึงตรงนี้แล้วตามทันกันมั้ย … ถ้าไม่ทันให้ลองทำตามนะครับ

ส่วนอันนี้เป็นบทความเกี่ยวกับ automatic validation ของ Moya เพิ่มความเข้าใจ

อย่างที่สอง Moya นั้นใช้ Library เทพ อย่าง Alamofire ถึงกับต้องใช้คำว่า

Elegant HTTP Networking in Swift

งื้อออ … จะอวยทำไม แต่มันก็เป็นอย่างนั้นจริงๆ เดี๋ยวนี้ไม่มีใครเขียนเองแล้ว

นั้นหมายถึง MoyaProviderType มันจัดการกับ session ได้ ผ่านทาง

/// The manager for the session.
open let manager: Manager

Manager มันก็คือ

public typealias Manager = Alamofire.SessionManager

แล้ว SessionManager มันสามารถจัดการ retrier ได้ เอาละเว้ยๆ

/// The request retrier called each time a request encounters an error to determine whether to retry the request.
open var retrier: RequestRetrier? {
get { return delegate.retrier }
set { delegate.retrier = newValue }
}

เอ้าๆใจเย็นๆ อย่าเพิ่งตกใจ พักกินน้ำกินท่า ล้างหน้าแปรงฟันกันก่อน หายใจเข้าลึกๆ ตั้งสติ ฮ่าๆๆ โอ้ย เข้ามาซะลึกเลย … แต่ตอนใช้แค่สั้นๆ 🤣


หมะ … ไม่เสียสละ ชัยชนะไม่เกิด หื้อออ ✌️

ให้เราสร้าง class Handler ขึ้นมาโดย conform protocol : RequestRetrier

จริงๆแล้ว protocol นี้มีไว้ทำ retry request แต่ว่าเราจะยืมมันมา handle status code ซึ่งผมมองว่า มันจะทำให้เราจัดการกับ status code แบบนี้ที่เดียวได้
แล้วเดี๋ยวจะมาเขียนการทำ retry request ให้อ่านอีกทีนะ

จากนั้นกลับไป set retrier ให้กับ provider

เพียงเท่านี้ เราก็จะมีตัว handle status code ที่เดียวแล้ว

ส่วนอันนี้เป็นรายละเอียดของเรื่อง RequestRetrier ของ Alamofire ครับ


ผมทำ simple api ไว้ให้ เผื่อต้องการ test สามารถ clone ไป start ที่ localhost ได้เลย

และ demo project iOS


จบละ เด้อ … 🤪