Toyokumo Tech Blog

トヨクモ株式会社の開発本部のブログです。

Clojureで作るAPI 開発用のコードを分離する

[連載]Clojureで作るAPIの5記事目です。

前回の記事はこちらです。

tech.toyokumo.co.jp

この記事では開発用のコードと実際のコードとを分離し、開発用の関数が評価された状態でREPLが起動されるようにすることで、今後の生産性を上げるようにします。

aliasを追加

今のところdeps.ednで :paths ["src"] と指定しているので、ライブラリ以外でクラスパスに含まれるファイルはsrc以下のものです。 しかしsrc以下に開発のためのコードを含めてしまうと、それらもビルドの対象になってしまうので避けたいです。

そこで、開発時にだけクラスパスに含まれるディレクトリを設定することでこの問題を回避します。 deps.ednに :aliases を追加します。

;; ./.deps.edn
{:paths ["src"]
 :deps {org.clojure/clojure {:mvn/version "1.11.1"}
        info.sunng/ring-jetty9-adapter {:mvn/version "0.17.6" :exclusions [org.slf4j/slf4j-api]}
        spootnik/unilog {:mvn/version "0.7.30"}
        com.stuartsierra/component {:mvn/version "1.1.0"}}
 :aliases {:dev {:extra-paths ["dev"]}}}

EmacsとCIDERを利用している人は.dir-locals.elを追加しておく必要があります。

;; ./.dir-locals.el
((clojure-mode . ((cider-clojure-cli-aliases . ":dev")
                  )))

user.clj

ClojureのREPLはデフォルトではuserというnamespaceで起動します。

この挙動を利用して、 ./dev/user.clj に開発用の関数を定義します。ディレクトリがsrcじゃないことに注意してください。

;; ./dev/user.clj
(ns user
  (:require
   [cljapi.system :as system]))

(defonce system (atom nil))

(defn start []
  (reset! system (system/start)))

(defn stop []
  (when @system
    (reset! system (system/stop @system))))

(defn go []
  (stop)
  (start))

system.cljからは不要になったものを削除して次のようにしておきます。

;; ./src/cljapi/system.clj
(ns cljapi.system
  (:require
   [cljapi.component.handler :as c.handler]
   [cljapi.component.server :as c.server]
   [com.stuartsierra.component :as component]))

(defn- new-system []
  (component/system-map
   :handler (c.handler/map->Handler {})
   :server (component/using
            (c.server/map->Jetty9Server {:opts {:join? false
                                                :port 8000}})
            [:handler])))

(defn start []
  (let [system (new-system)]
    (component/start system)))

(defn stop [system]
  (component/stop system))

REPLを起動してうまくいっていることを確かめます。

user> (ns-interns *ns*)
{go #'user/go, system #'user/system, start #'user/start, stop #'user/stop}
user> (go)
16:03:35.893 [nREPL-session-9adbd434-340f-4921-8f28-60926ca9be17] DEBUG org.eclipse.jetty.util.component.AbstractLifeCycle - STOPPING Server@4b5f2286{STARTED}[10.0.9,sto=0]

おわりに

これで開発用のコードはdevディレクトリに置くことができるようになりました。

devディレクトリは :dev aliasを有効にしたときしかソースとして認識されないため、開発用のコードを分離できるようになっています。

コードはGitHubのリポジトリに上げてあります。 05_開発用のコードを分離するというタグからご覧ください。

次は実際にビルドしてJARファイルを生成して、javaコマンドで実行できるようにしていきます。


トヨクモでは一緒に働いてくれる技術が好きなエンジニアを募集しております。

採用に関する情報を公開しております。 気になった方はこちらからご応募ください。