[Scala] SOPlurk - Plurk API 2.0 Scala 函式庫

緣起

話說上星期放年假的時候,心血來潮想說來試試看用噗浪的 2.0 API 實作私噗收件人差集的功能,結果不知道為什麼一不小心就變成開始變成寫 Plurk API 2.0 的 Scala Binding,並且順道練習怎麼用 Scala 2.10 來設計函式庫了……XD

這次的成果就是 SOPlurk,雖然是在十二天之內隨便硬幹出來的函式庫,不過應該還算完整和堪用?至少 Plurk API 的文件裡提到的 API 都實作了,甚至實作了一些只藏在 Plurk APP Test Console 裡的 API。

安裝

如果是使用 SBT 的話,因為已經把 Jar 檔放到網路上了,所以只要在 build.sbt 裡加入以下的設定,就可以使用了。

scalaVersion := "2.10.0"

resolvers += "bone" at "http://brianhsu.moe/ivy"

libraryDependencies += "org.bone" %% "soplurk" % "0.1"

要注意的是,由於 SOPlurk 使用到了 Scala 2.10 以上才有的 scala.util.Try[T] 類別,所以一定要在 SBT 中指定使用 Scala 2.10 以上的版本來編譯專案。

使用起來的感覺

在設計 SOPlurk 的 API 的時候,給自己設定的其中一個目標,就是讓 API 使用起來簡單,但同時又可以讓 client code 夠強韌。

畢竟這是在網路上送資料和撈資料的 API,過程中什麼時候會發生什麼事誰都不知道,有可能是使用者的網路突然間斷線,也有可能是噗浪的伺服器自己掛掉了,也有可能使用者送的資料不合法,所以噗浪不收(例如防洪機制就會擋連續的同樣的噗)。

最後的結果,就是大量使用了 Scala 2.10 中的 Try[T] 這個東西,而一但了解了他的用法之後,程式碼就變得很簡單了。

舉例來說,下面是使用這個 SOPlurk 來取得我自己的噗浪的最新一則噗的回應的程式碼:

import org.bone.soplurk.api.PlurkAPI
import org.bone.soplurk.api.PlurkAPI.PlurkResponses

val appKey = "7xHSzV4xGLJS"
val appSecret = "r2SgShtAqMP0IWdYHQGYyoi8imWqiw48"
val plurkAPI = PlurkAPI.withoutCallback(appKey, appSecret)

for {
  profile <- plurkAPI.Profile.getPublicProfile("brianhsu") // 拿我噗浪上的個人檔案
  plurk   <- Try(profile.plurks.head)  // 從我的個人檔案裡找到最新的一則噗
  plurkResponse <- plurkAPI.Responses.get(plurk.plurkID) // 並且查裡面的回應
} {

  // users 會是 Map[Long, User],key 是使用者的 userID,value 是他的資訊
  // responses 則是這則噗的回應
  val PlurkResponses(users, responses, seen) = plurkResponse

  println("最新的回應:")

  // 把每一則回應印出
  responses.foreach { r =>
    val nickname = users(r.userID).nickname
    val qualifier = r.qualifier.name
    val content = r.contentRaw

    println(s"  $nickname $qualifier $content")
  }

}

就這樣,上面的程式碼會確認 for 的內容只有在每一個步驟都成功取得資訊的時候,才會執行。如果其中一個步驟有問題的話,就直接略過。

當然這是比較不好的作法,因為如果有 Exception 發生的話,使用者不會知道,只會覺得為什麼什麼輸出都沒有。不過因為多數 API 回傳的都是 Try[T] 這個類別,所以你可以選擇自己喜歡的方式去處理錯誤的情況

心得

在這次的實作過程中,覺得最令人驚豔的就是 Try[T] 所提供的彈性。雖然之前就知道可以用 Either[A,B] 的方式來做錯誤處理,但用 Try[T] 來做的時候,語法更簡潔,而且語意也更清楚。

一但了解了 Try[T] 的運作方式,和怎麼組合多個 Try[T] 的回傳值後,程式的 Exception 處理就變得相當有彈性,而且程式碼看起來真的乾淨很多,強烈建議有在玩 Scala 的朋友試試看,或許你會和我一樣愛上他。(笑)

回響