(rontolisp) docs
← リファレンス

Ring アダプター (ring.adapter.rontolisp)

ring.adapter.rontolisp/run-server は、Ring のハンドラ(リクエストマップを受け取ってレスポンスマップを返す関数)を、ターゲット自身の HTTP 受信トランスポートで提供します。組み込みなので、clojure.string と同じように require します。Clack バックエンドの :server :rontolisp(Clack)が対応する すべてのトランスポートで、同じソースが動きます。両アダプターは同じトランスポートのコードを 呼び出します。

ターゲットビルドトランスポート
インタプリタrontolisp app.cljプログラムがバインドするソケット(:port、:host)
JVM-o App.class、-o app.jar同じソケットサーバー
Servlet war-o app.warポートはコンテナが持ち、run-server はハンドラを登録して戻る
WASM コンポーネント-o app.wasm --component、wasmtime serve で実行ソケットはホストが持ち、run-server はすぐ戻る
WASM リアクター-o app.wasm --no-wasiホストが handle-request エクスポートを呼ぶ(Clack ガイドのリアクタビルド)

素の Preview 1 モジュール(-o app.wasm)は接続を受け付けません。コンパイルはでき、 実行時に run-server が --component が必要だというエラーを通知します。

NameExampleResult
ring.adapter.rontolisp/run-server(run-server handler {:port 3000})ブロックする。:join? false ならサーバーを返す
$ cat app.clj
(ns app (:require [ring.adapter.rontolisp :refer [run-server]]))

(defn handler [{:keys [request-method uri]}]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body (str (name request-method) " " uri "\n")})

(run-server handler {:port 3000 :host "127.0.0.1"})
$ rontolisp app.clj &
$ curl http://127.0.0.1:3000/hello
get /hello

リクエストマップ

キー値
:request-method小文字キーワードのメソッド: :get、:post など
:uri送られたままの(パーセントデコードしない)パス。クエリは含まない
:query-string? より後のテキスト。なければ nil
:headers小文字のヘッダー名から値へのマップ。繰り返されたヘッダーは ", " で連結
:server-name、:server-portHost ヘッダーから。なければ待ち受けアドレス
:remote-addr接続元アドレス。コンポーネントと、ホストが送らないリアクターでは nil
:scheme:http または :https
:protocol"HTTP/1.1"
:content-type、:content-lengthヘッダーから。なければ nil
:bodyリクエストボディのオクテットの java.io.InputStream。ボディのないリクエストでは空

:body はどのバックエンドでも .read、slurp(:encoding の文字セット。既定は UTF-8)、 clojure.java.io/reader、line-seq、clojure.java.io/copy、java.io.InputStreamReader で読めます。バイナリのアップロードはオクテットどおりに読めます。ストリームはバッファ済みなので、 読み取りがネットワークを待つことはありません。クラスは Ring の Jetty アダプターと同じ org.eclipse.jetty.ee9.nested.HttpInput で、Jetty と同じく閉じても読めるままです。slurp の後の読み取りはボディの終端を返します。レスポンスの :body として返すか、 rontolisp.http-client のリクエストの :body として送ると、そのオクテットに なります。

レスポンスマップ

キー値
:status整数。なければ 200
:headersヘッダー名(文字列かキーワード)から、文字列、または 1 要素ずつ別のヘッダー行で送る文字列の seq へのマップ
:body文字列、各要素を str で送る seq、リーダーか入力ストリーム(終端まで読んで閉じる)、java.io.File(そのバイト列をそのまま送る)、または nil

ハンドラがマップ以外を返した場合と、それ以外の種類のボディを返した場合はエラーを通知し、 トランスポートは 500 を返します。プログラムが読めるファイルを指さない java.io.File も 同じです。WebAssembly の配信トランスポート(wasmtime serve、リアクター)にはファイル システムがないので、ファイルを配信できるのはインタープリター、JVM、war です。プログラムが 持ち運ぶリソースの上のバイトストリームはどこでも配信できます。 レスポンスを組み立てる関数(file-response と resource-response を含む)とパラメーターの ミドルウェアは、組み込みの Ring ユーティリティにあります。

Cloudflare Workers

Worker は handle-request エクスポートを呼ぶので、リアクタービルドはソースを変えずに Worker としてデプロイできます。--emit-js-glue が JavaScript 側をモジュールの隣に書き出します。

$ rontolisp app.clj -o src/worker.wasm --no-wasi --optimize=size --emit-js-glue
$ cat src/index.js
import module from "./worker.wasm";
import { worker } from "./worker.js";

export default worker(module);
$ npx wrangler dev      # http://localhost:8787
$ npx wrangler deploy

ここでは :port と :host は読まれません。wrangler.jsonc と、他のターゲットと同じ Ring の例を ビルドする build.sh を含む完全なプロジェクトは examples/cloudflare-workers/ring-hello-one-source/ にあります。