2025年1月12日日曜日

pedestalによるファイル受信処理とcurlによるファイルアップロードコマンド備忘録


背景

趣味で作っているログ取りサーバー(clojure pedestal利用)ファイルアップロードapiを追加しました。
取り組んだ内容を見返したくなった時の関連情報を記事に残します。

ファイル配信処理は以前の記事が参考になると思います。
clojureのpedestal(ring)で動的なファイル配信

使ったもの

  • curlが使えるshell
  • pedestalで作っているサーバー

ファイルアップロードコマンド

curlでファイルをアップロードするコマンドの例です。
-Fオプションを用いることでmultipart formとしてアップロードします。
PATH_FILE="your-local/image.png"
HOST=http://localhost:3000
curl -X POST ${HOST}/api/device_file -F "file=@$PATH_FILE"

参考: Using cURL to upload POST data with files

pedestalでファイルを受信して保存

multipalt-formのinterceptorをapiのパスに設定するとファイルを受信できます。
「..」は他の処理を記述しているという意味です。
(ns back.route
(:require ..
[io.pedestal.http.ring-middlewares :as middlewares]
..))

(def main
#{..
["/api/device_file"
:post [(middlewares/multipart-params) handlers/api-post-device-file]
:route-name :api-post-device-file]
..})

ファイルの情報はrequestのmultipart-paramsの"file"キー(curlで指定したファイルの送信先のキー)にあります。
tmpfileにはファイルの実体が、fielnameにはアップロード時のファイル名が格納されています。
ioのcopy関数を使えば渡されたファイルを保存できます。
格納先のフォルダ作成はmkdirsを使うと階層フォルダも一度で作れて便利です。
(ns some
(:require [clojure.java.io :as io]
..)

(defn api-post-device-file [req]
(let [info-file (-> req :multipart-params (get "file"))
input-file (:tempfile info-file)
filename (:filename info-file)
path-dir "some/dir/to/save"]
(.mkdirs (io/file path-dir))
(io/copy input-file (io/file path-dir filename))
{:status 200}))

参考
参考にしたファイルを扱うサーバーのプロジェクトです。
pedestal-file-upload/src/sample/file_upload/service.clj

pedestalの説明ページです。
multipart-params

おわり

pedestalでファイルを受信して保存できました。

参考

自分が行った変更内容です。
Support device_file on filestorage

0 件のコメント :