2024年12月29日日曜日

clojureのpedestal(ring)で動的なファイル配信


背景

pedestalとはプログラミング言語clojureのサーバーライブラリの1つです。
apiの説明ページを見ると静的なファイルの配信処理(static resource)の説明はあるものの動的なファイルの配信処理(dynamic resource)の説明は無く実現が分からなかったのですが、stack overflowで実現方法を見つけたので備忘録として方法を記事に残します。

使ったもの

pedestalを利用するサーバープロジェクト

この記事の内容で下記の変更を行いました。
Serve files for frontend as dynamic resource

実現方法 clojure.java.io/input-streamを利用

handlerでパスを解釈し、それに応じたファイルをinput-streamで返せば良いです。
(def path-dir "../files")

(defn handle-file [request]
(let [path (-> request :path-info)]
{:status 200
:body (io/input-stream (str path-dir path))}))

参考: How do you serve dynamically created files in clojure ring server?

動的の都合が良い場面: uberjarで固めたとき、権限を適用したいとき

開発時はdeps.ednのresourcesで指定したフォルダの中のファイルを入れ替えれば動的に変化するので問題ないのですが、uberjarでプロジェクトを固めるとresourcesの中身もjarに固められるのでjarファイル実行時にフォルダの内容を変えれません。
実行時に配信内容を変えるフォルダに対しては、今回紹介した方法が都合が良いです。

また、利用者の権限によってファイルを配信可否を変えたい場合も、ファイルを配信するhandlerで権限判別をすれば可能なので都合が良いです。

おわり

clojure.java.io/input-streamを利用して動的なファイルの配信をpedestalから行えました。
これを利用すればjarで固めたときも動的にファイルを配信するサーバーを作れます。

参考

Static Resources (Clojure Only) - metosin/reitit-pedestal
How do you serve dynamically created files in clojure ring server?
Serve files for frontend as dynamic resource

0 件のコメント :