GYOMUハックでAPI叩くときにCommonLisp使うと便利だった話


これはGYOMUハック/業務ハック Advent Calendar 2018の7日目の記事です。

昨日はDataSpiderの記事でした。
私はその一つ前(?)のiDIVOというのを触っていたので、ちょっとだけいいところと大変だったところの気持ちがわかるような気がします。

今日の結論

CommonLisp使うと便利でした。

その中でも今回はClozureCLを使っています。

背景

その1

  • A) GYOMUハックっていろんなシステムと連携するよね
  • B) REST APIだよね
  • A) あれって何を送ったら何が返ってくるかイメージしにくいよね
  • B) REPLがある言語でやるといいんじゃない?

(Postman使え?ごもっとも)

その2

  • A) Authorization面倒だよね
  • B) メモリをダンプできる言語でやるといいんじゃない?

CommonLispでZendeskにアクセスする

トークンの作成

(ql:quickload :cl-base64)

(defvar *zendesk-token* nil)
(defun set-zendesk-token (email token)
  (setf *zendesk-token*
        (format NIL "Basic ~A"
                (cl-base64:string-to-base64-string
                 (format NIL "~A/token:~A" emai token)))))

;; トークンを設定する
;; メールアドレスとAPIトークンを渡すとZendeskにアクセスする際に使うトークンが得られます
(set-zendesk-token "[email protected]" "xxxxxxxxxxxxxxxxxxxxxxx")
;; => "Basic dGVzdEB4eHh4eHguY29tL3Rva2VuOnh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4"

これでトークンができました。

メモリのダンプ(コアファイルの作成)

メールアドレスとかAPIトークンとかを毎回入力するのも面倒なのでメモリをダンプしておきます。
CommonLispではメモリをダンプして次回読み込むことで、前回と同じ環境を作ることができます。

OAuth2とかだとAccessTokenやRefreshTokenをメモリに持っておくだけで、次回以降も使い回しができるので便利です。

(ccl:save-application "/path/to/core/zendesk.core"
                      :purify t
                      :prepend-kernel t)

これを実行するとREPLが終了します。

メモリの読み込み

処理系を起動する際にダンプしたコアファイルを指定することでメモリに乗った状態で立ち上がります。

dx86cl64 --image-name /path/to/core/zendesk.core

で、SLIMEとかを使いたい場合はここからswankサーバを起動させておきます。

(ql:quickload :swank)
(swank:create-server)

Emacsとかからはslime-connectなどを使って接続します。

swankサーバに接続したら変数を見てみます。

CL-USER> *zendesk-token*
"Basic dGVzdEB4eHh4eHguY29tL3Rva2VuOnh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4"

無事に値が残っていました。
あとは毎回このコアファイルを使えばZendeskにアクセスできます。

余談ですが、関数set-zendesk-tokenも残っているので、APIトークンを新しく発行し直した時はもう一度セットすることができます。

Zendeskへの接続

(dex:get "https://xxxxxxx.zendesk.com/api/v2/users.json"
         :headers `(("Authorization" . ,*zendesk-token*)))

REPLに結果がだーーーっと出てきます。

余談ですが、SLIMEだと*に直前の出力がバインドされているので、いったん目で構造を確認したのちに*を評価し直して整形する、というやり方が使えます。
(2018.12.09 誤りの訂正。*はCommonLispの仕様でした。
http://www.lispworks.com/documentation/lw51/CLHS/Body/v__stst_.htm
@nfunato さん情報ありがとうございます)

余談ですが、*に直前の出力がバインドされているので、いったん目で構造を確認したのちに*を評価し直して整形する、というやり方が使えます。
REPL最高ですね。

応用

いろいろな外部サービスへの接続の変数を設定したコアファイルを用意しておくと、いざという時の調査とかにサッと取りかかることができます。