Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Duct for beginners.
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Nakamura, Ryotaro
February 16, 2018
Technology
0
4.2k
Duct for beginners.
How to use Integrant and Duct.
Nakamura, Ryotaro
February 16, 2018
Tweet
Share
More Decks by Nakamura, Ryotaro
See All by Nakamura, Ryotaro
Learn Go in 15 minutes
nryotaro
0
42
An introduction of statistical learning
nryotaro
0
43
Seven architectural patterns
nryotaro
1
110
Improving Performance with Parallel Programming
nryotaro
0
55
Other Decks in Technology
See All in Technology
M&A 後の統合をどう進めるか ─ ナレッジワーク × Poetics が実践した組織とシステムの融合
kworkdev
PRO
1
450
レガシー共有バッチ基盤への挑戦 - SREドリブンなリアーキテクチャリングの取り組み
tatsukoni
0
210
配列に見る bash と zsh の違い
kazzpapa3
1
140
FinTech SREのAWSサービス活用/Leveraging AWS Services in FinTech SRE
maaaato
0
130
We Built for Predictability; The Workloads Didn’t Care
stahnma
0
140
20260208_第66回 コンピュータビジョン勉強会
keiichiito1978
0
130
こんなところでも(地味に)活躍するImage Modeさんを知ってるかい?- Image Mode for OpenShift -
tsukaman
0
140
GitLab Duo Agent Platform × AGENTS.md で実現するSpec-Driven Development / GitLab Duo Agent Platform × AGENTS.md
n11sh1
0
140
GitHub Issue Templates + Coding Agentで簡単みんなでIaC/Easy IaC for Everyone with GitHub Issue Templates + Coding Agent
aeonpeople
1
220
ZOZOにおけるAI活用の現在 ~開発組織全体での取り組みと試行錯誤~
zozotech
PRO
5
5.5k
登壇駆動学習のすすめ — CfPのネタの見つけ方と書くときに意識していること
bicstone
3
100
Claude_CodeでSEOを最適化する_AI_Ops_Community_Vol.2__マーケティングx_AIはここまで進化した.pdf
riku_423
2
570
Featured
See All Featured
Discover your Explorer Soul
emna__ayadi
2
1.1k
[SF Ruby Conf 2025] Rails X
palkan
1
750
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Skip the Path - Find Your Career Trail
mkilby
0
55
It's Worth the Effort
3n
188
29k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
76
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
66
37k
The SEO identity crisis: Don't let AI make you average
varn
0
240
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.6k
Building Applications with DynamoDB
mza
96
6.9k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Unsuck your backbone
ammeep
671
58k
Transcript
はじめてのDuct 中村 遼太郎
話すこと 2 IntegrantでこまってDuctを使うようになった話 • Integrant ◦ 概要 ◦ 困ったこと •
Duct ◦ 概要 ◦ Boundaries ◦ Moduleの作り方
Integrant 3
Ringの初期化例 4 (def endpoint “http://localhost/health”) (defn handler [request] (get-health endpoint))
(defn -main [] (jetty/run-jetty handler {:port 3000})) 他のサービスの状態を調べるハンドラ endpointに対するヘルスチェックの結果を返す
よくないところ 5 (def endpoint “http://localhost/health”) (defn handler [request] (get-health endpoint))
(defn -main [] (jetty/run-jetty handler {:port 3000})) グローバル変数による依存解決 変数のスコープが必要以上に大きい mainからendpointが見える
パラメタでスコープを小さくする 6 パラメタによる依存解決 設定とリクエストまじり,パラメタが複雑になる (defn wrap-handler [handler ep] (fn [request]
(handler (assoc request :endpoint ep)))) (defn handler [request] (get-health (:endpoint request))) (wrap-handler handler “http://localhost/health”)
Integrant 7 クロージャによる依存解決 クロージャでローカル変数を個別に渡す (defmethod ig/init-key :ebis/handler [_ endpoint] (fn
[request] (get-health endpoint))) (defmethod ig/init-key :ebis/jetty [_ {:keys [handler] :as options}] (jetty/run-jetty handler options))
関心ごと分離 8 コンフィグマップ(構造) Integrantはシステムの実装と構造を分ける {:ebis/handler “http://localhost/health” :ebis/jetty {:handler #ig/ref :ebis/handler
:port 3000}}
Integrantがやること 9 キーワードをオブジェクトに置き換える Integrantはシステムの実装と構造を分ける {:ebis/handler “http://localhost/health” :ebis/jetty {:handler #ig/ref :ebis/handler
:port 3000}} init-key
Integrantからみたシステム 10 コードの木 Integrantはコードの幹にある integrantは コードを呼び出す コードが ライブラリを呼ぶ https://skillsmatter.com/skillscasts/8717-arachne-building-a-framework-in-clojure
Integrantからみたシステム 11 システムの実装と構造の分離 Integrantは幹の部分から実装とコードを分けていく James Reeves, Enter Integrant: a micro-framework
for data-driven-architecture 実装
Integrantで困ったこと 12 途中までIntegrantを使う ライブラリの呼び出し部分への適用が最後になる ライブラリと コードが密結合 コンフィグマップ にする順序
ほしいもの 13 途中までIntegrantを使う ➔ ライブラリの呼び出しを楽を疎にするもの ➔ コンフィグマップの適用を楽にするもの 楽に適用できる システムの境界 を疎にできる
ほしいもの 14 途中までIntegrantを使う ➔ ライブラリの呼び出しを楽を疎にするもの ➔ コンフィグマップの適用を楽にするもの 楽に適用できる システムの境界 を疎にできる
Duct Boundaries Duct modules
Duct 15 weavejester If Integrant is the “grammar”, Duct is
attempting to build a “vocabulary”
Integrantの初期化手順 16 コンフィグをもとにシステムを初期化する read init コンフィグを読む コンフィグをオブジェクトに変換する
Ductの初期化手順 17 コンフィグを拡張する中間ステップがある read init コンフィグを読む prep コンフィグを書き換える コンフィグをオブジェクトに変換する
モジュール 18 prepステップでコンフィグを展開する純粋関数 read init prep module.web module.cljs module.sql module.logging
module.ataraxy Ductが提供するもの
コンフィグの展開 19 config.ednで使うモジュールを宣言する コンフィグのロード $ cat resources/ebis/config.edn { :duct.module/logging {}
... } ... $ lein repl user => (dev) :loaded Read Prep init
コンフィグの展開 20 prepでコンフィグを展開する モジュールによるloggerの展開 Read Prep init (dev) => (prep)
:prepped dev => (pprint config) { :duct.logger/timbre {:level :debug, {:appenders {: ...} :duct.logger.timbre/spit {:fname “logs/..”} :duct.module/logging {} ... }
コンフィグの展開 21 展開されたコンフィグでシステムが初期化される サーバの起動 Read Prep init dev => (go)
:duct.server.http.jetty/starting-server {:port 3000} :initiated
プロジェクトの構造 22 lein newでテンプレートからプロジェクトを作れる プロジェクトの構造 lein new duct ebis +api
+ataraxy {{project}} ├── src │ └── {{project}} │ ├── boundary │ │ └── {{boundary}}.clj │ ├── handler │ │ └── {{handler}}.clj │ └── main.clj
Boundaries 23 protocolを介してシステムの外と通信する プロトコルの利用例 (defprotocol Health (get-health [this])) (defrecord HttpHealth
[method url handler] Health (get-health [{:keys [method url handler]}] (handler (method url)))) (defmethod ig/init-key ::http [_ {:keys [url]}] (->HttpHealth http/get “http://..” #(..)))
Ductで困ること 24 必要なモジュールがない https://github.com/duct-framework module.web module.cljs module.sql module.logging module.ataraxy Duct
frameworkが提供するモジュール
事例 25 Google pubsubのモジュールを作る 購読開始処理 (def s-name (SubscriptionName/create “p-id” “s-id”))
(def receiver (reify MessageReceiver (receiveMessage [this message consume] (println (. message getData))))) (def subscriber (Subscriber/newBuilder s-name receiver)) (. (. subscriber build) startAsync)
モジュール化の方針 26 SubscriptionName/createをモジュールに移す 処理の分割 (def s-name → モジュール (SubscriptionName/create “p-id”
“s-id”)) (def receiver → ig/init (reify MessageReceiver (receiveMessage [this message consume] (println (. message getData))))) (def subscriber (Subscriber/newBuilder s-name receiver)) (. (. subscriber build) startAsync)→ protocol
モジュール側 1/3 27 src/duct_hierachy.ednにprepで呼び出すキーを登録 :duct/moduleを継承する {:duct.module/message [:duct/module]}
モジュール側 2/3 28 :duct/moduleを継承したキーがprepで呼び出される :duct/message/pubsubをコンフィグマップに追加 (defmethod ig/init-key :duct.module/message [_ options]
{:fn (fn [config] (core/merge-configs config ; ユーザが定義したコンフィグ {:duct.message/pubsub ;追加するキー {:logger (ig/ref :duct/logger)}}))}) :duct/module
モジュール側 3/3 29 prepで追加されたキーはinitするときに呼び出される SubscriptionNameのインスタンス化 (defmethod ig/init-key :duct.message/pubsub [_ {:keys
[p-id s-id] :as opt}] (assoc opt :s-name (SubscriptionName/create p-id s-id)))
アプリケーション側 1/3 30 config.ednに作ったモジュールを宣言する config.ednにモジュールを宣言 {:duct.message/pubsub {:p-id "clj-p" :s-id "clj-s"}
:duct.module/message {} :ebis.boundary/message #ig/ref :duct.message/pubsub } モジュールが初期化する
アプリケーション側 2/3 31 boundaryでprotocolを宣言する Receiverの宣言 (defprotocol Receiver (start [this]) (stop
[this])) (defrecord PubSubReceiver [subscriber logger] (start [this] (l/log logger :info “start”) (. subscriber startAsync)) ..)
アプリケーション側 3/3 32 Receiverをinit-keyの中で作る Receiverの生成 (defmethod :ig/init-key :ebis.boundary/message [_ {:keys
s-name logger}] (let [subscriber (... (reify MessageReceiver ...)) receiver (->PubSubReceiver subscriber logger)] (start receiver) (receiver)))
おさらい 33 ➔ Integrantだけだとコンフィグマップの適用がたいへん ➔ Ductのモジュールはコンフィグ化を助けてくれる ➔ しかしモジュールの数は少なく,作り方の説明は不十分 ➔ そこでモジュールの作り方を紹介した
参考資料 34 ➔ Arachne: building a framework in Clojure https://skillsmatter.com/skillscasts/8717-arachne-building-a-framework-in-clojure
➔ Productive Duct https://skillsmatter.com/skillscasts/10836-productive-duct ➔ Integrant: a micro-framework for data-driven architecture with James Reeves https://skillsmatter.com/skillscasts/9820-enter-integrant-a-micro-framework-for-data-driven-architecture-with-james-r eeves ➔ Duct, Covered https://skillsmatter.com/skillscasts/7229-duct-covered ➔ Duct Framework and supporting libraries https://github.com/duct-framework