simple-httpd.elはEmacs Lispで書かれたHTTPサーバー。今回はこれを使ってみる。
HTTPサーバの開始
HTTPサーバーを起動するにはhttpd-startを使う。 httpd-startはホストにhttpd-host、 ポートにhttpd-portを用いてmake-network-processを呼び出す。
(httpd-start)サーブレットの定義
ここで使っているサーブレットとはJavaサーブレットのことではなく、 HTTPリクエストを受け取りレスポンスを返すもののことをサーブレットと表現している。 他のWebフレームワークではリクエストハンドラと呼ばれるものに近い。 defservletマクロを使うとサーブレットを定義する。
(defservlet hello-world.txt text/plain (path)
(insert "Hello World!"))上の例では `/hello-world.txt` にリクエストを受けると BODYに `Hello World!` と書かれたレスポンスを返すサーブレット。 defservletは `httpd/hello-world.txt` という名称の関数を定義した 以下はその処理を行なっているdefservletマクロの定義。
(let ((proc-sym (make-symbol "proc"))
(fname (intern (concat "httpd/" (symbol-name name)))))
`(defun ,fname (,proc-sym ,@path-query-request &rest ,(cl-gensym))
(with-httpd-buffer ,proc-sym ,(httpd--stringify mime)
,@body))))`(concat "httpd/" (symbol-name name)` で関数名を作成してそれをinternしている。 その後 `defun` に展開して関数定義を作成している。 `/hello-world.txt` にリクエストを受けるとこの関数が呼び出されることになる。
リクエストを送信する
実際にリクエストを送信して挙動を確認する。
GET http://127.0.0.1:8080/hello-world.txt正しくレスポンスが返ってくることがわかる。
定義を変更すると即座に反映される
先ほどのdefservletで作成していた関数をevalしなおすと即座に挙動が変更される。
(defservlet hello-world.txt text/plain (path)
(insert "yay!!"))リクエストを送信して挙動を確認する。
GET http://127.0.0.1:8080/hello-world.txt変更されたことがわかる。 挙動を変更するためにプロセスを起動しなおす必要はない。
HTTPサーバの停止
(httpd-stop)まとめ
simple-httpd.elで簡単なAPIを書いた。