ClojureによるWeb開発ノウハウまとめ.
📝Clojure Web 開発概論
ClojureではRailsやDjangoのようなデファクトスタンダードなWebフレームワークをつかうよりも 小さなライブラリを組み合わせて開発することが多い.
そのため機能ごとにいろんなライブラリが存在する.
- 📝Clojure: APIサーバ開発: API Server, Webバックエンド.
- 📝Clojure APIクライアント開発: API Client.
- 📝ClojureScript Frontend Development: Webフロントエンドはこちら.
- 📝Clojureサービス開発: サービス開発.
ClojureはJavaのWeb技術の肩に乗っかっている部分も多く, Javaの基礎概念も理解しておきたい -> 📝Java Web Development.
Clojure: Web Frameworks
- Luminus
- 🔧Clojure: Duct
ref: 🔖Web Framework
Clojure: Ring
Clojureにおける Web サーバ抽象 のデファクトスタンダード.
- refs.
- docs.
- Why Use Ring? · ring-clojure/ring Wiki · GitHub
- なぜRingをつかうのか?
- WebアプリをClojureの関数とMapデータのみで構築するという設計概念を示す.
- Java servletの上で走るアプリにコンパイルする.
- 4つのコンポーネントからなる(ref).
- Handler
- Clojureの関数で表現される.
- Request Mapを受取り, Response Mapを返す.
- Request
- Response
- Middleware
- Handler
ref: 🔖Web Server Abstruction 📝Clojure: Pedestal
ring: middleware
ref. ring
- wrap-params(ring.middleware.params)
- ringはデフォルトではrequestに付随するパラメータに対してなにもしない. wrap-paramsを利用すると パラメータを処理してくれる.
- (通常getからの) urlについたquery-paramsを :query-paramsにbind.
- (通常postからの) bodyの中のform-paramsを :form-paramsにbind.
- :query-paramsと :form-paramsのデータを :paramsにマージ. そのため大抵は :paramsをチェックすればデータが入っている.
- wrap-keyword-params(ring.middleware.keyword-params)
- ring は request-mapのkeyをdefaultではstringとして扱う.これをkeywordに変換する.
- wrap-json-paramsの:json-paramsは ring parameter mapである :paramsにマージされる. しかしring paramsは mapのkeyがkeywordではなくstringとして扱うため wrap-keyword-params との併用が必要.
ring-json: middleware
ref. ring-json (ring.middleware.json)
- wrap-json-response
- response-mapのbodyのColojure MapやVectorをplain/textのJSONに変換.
- wrap-json-body
- request-mapのbodyのjson形式の文字列をclojure collectionに変換して :bodyにbinding.
- wrap-json-params
- request-mapの bodyの json形式の文字列を Mapに変換して(:body :json-paramsにbinding.
tips: run-jettyにhandlerのvarを渡してhot reloading
varは リーダマクロ #’ にて取得できる. すなわち,
(run-jetty #'handler {:port 3000})
詳しくは以下を参照.
- Column: REPL 駆動開発を取り入れて Ring でもう少し遊んでみる — Clojure の日本語ガイド
- 何故、RingハンドラーにVarを渡すと、ハンドラーを書き換えても書き換えたハンドラーが呼び出されるのか - ayato-p
varというのが参照型のため実際を差し替えられる.
References
- clojure-ring - 開発者ドキュメント
- Part2: Ring について知る — Clojure の日本語ガイド
- あやとぴさんのWeb 開発チュートリアル.
- ClojureのWeb開発でもっとも重要なRing Handlerについて理解する - TOYOKUMO
- Clojure Ring Middleware大全 - TOYOKUMO Tech Blog
- トヨクモの新卒やアルバイト学生のための教育用Ring解説記事.
サービス別
💡Heroku with Clojure
- https://devcenter.heroku.com/articles/deploying-clojure
- https://devcenter.heroku.com/articles/getting-started-with-clojure
- https://devcenter.heroku.com/articles/clojure-support
leiningenの作者がHerokuで働いてたらしくドキュメントがていねいとか.
https://twitter.com/as_chapa/status/1198104444711256064 https://twitter.com/iku000888/status/1099293410693808128
tip: Heroku上のappにreplで接続
heroku run lein replでHerokuサーバ上でreplを起動できる.
heroku run lein repl
howto: Heroku Deployでlein deps失敗の対処方法
Leiningen 1.7.1 がデフォルトで使用されますが、project.clj に :min-lein-version “2.0.0” がある場合は (強く推奨されます)、Leiningen 2.9.1 リリースが代わりに使用されます。
これにハマった. project.cljに :min-lein-version “2.0.0” を記載して解決✨
ref: https://devcenter.heroku.com/ja/articles/clojure-support
howto: Heroku上で Botを動かそうとするとエラー
web appではなく worker appにする必要がある.
そうしないと 60secでBootTimeoutとして扱われてProcess Killされる.
2022-02-11T09:30:12.486217+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch 2022-02-11T09:30:12.581863+00:00 heroku[web.1]: Stopping process with SIGKILL 2022-02-11T09:30:12.834345+00:00 heroku[web.1]: Process exited with status 137 2022-02-11T09:30:13.225734+00:00 heroku[web.1]: State changed from starting to crashed
Procfileを新規作成して以下を記載.
worker: lein run
heroku cliより
heroku ps:scale worker=1
ただし workerは30分活動がないとsleepしてしまう.
実際はheroku schedulerの活用も検討.
howto: tools.deps管理のプロジェクトをHerokuにデプロイ
未実施だけどブックマーク. leiningenの作者はライバルにいじわる?
ref: 試行錯誤な日々: clojure cliプロジェクトをherokuで動かす
Clojure Web Development Insights
💡ウェブアプリケーションとはデータ変換関数の集合にすぎない
Clojureからみた, いいかえれば関数型言語からみたウェブアプリケーションとは, リクエストマップを受け取ってレスポンスマップを返す関数の集合である.
この思想は, Clojureのデファクトスタンダードなサーバ抽象であるClojure: Ringに色濃く反映されて, したがってClojureでのWeb開発の世界観のひとつになっている.
🤔ClojureにRailsがないとシステムの深い理解を突き付けられる
ClojureにはRailsのようなデファクトスタンダードなフレームワークがなくて, 個々のフレームワークを自分で組み合わせてシステム開発をする必要がある. さらにそれぞれがドキュメントが充実しているわけではない.
そうすると, 原理原則から類推していくことによって理解をしようとするアプローチをとることが多い. 具体的には, システムとはなにか, 状態とはなにか, イベント駆動とはなにか… などなど.
ようは, Webサーバチョットデキルかということ.
そして中途半端な理解に直面するたびに, 自分が無知であることを気付かされる. 自分は何年コードを書いているんだ, こんな事も知らないのか… と.
確かに, Clojureを書けるようになると力がつくかもしれない. しかし, なにも知らない初心者はそもそもRailsやReactからの類推ができないというところで敷居がある.
かといって, そもそもClojureをプログラミング入門の一番はじめに選んでしまうひとはどのくらいいるのだろう? Clojureの年収が高いというStackOverflowの統計も, Clojure開発者の平均年齢が高く高齢化が進んだ結果ではとおもう.
🔗References
- オブジェクト指向とはまったく違うClojureの世界と実際のWeb開発 - 紙箱
- Clojure で Web 開発をはじめてみよう — Clojure の日本語ガイド
- http://ayato-p.github.io/clojure-beginner/intro_web_development/index.html
- ayato-pさんの作.
- たしかわたしがClojureにはじめて触れた2015ごろにはすでにあった気がする.
- ayato-pさんの作.
📚Web Development with Clojure - Dmitri Sotnikov
👨Dmitri Sotnikov(@yogthos)の著書.
https://pragprog.com/titles/dswdcloj3/web-development-with-clojure-third-edition/
この本のすごいと思うところは, Clojure周りのwebライブラリのupdateに追従してちゃんと重版を重ねているところ. Pragmatic Bookshelfで購入したので重版すると無料でupdateがみれるのはありがたい.