昨日はDuct
でルーティングを実装しました
今日はDB接続したいと思います。
今回の記事ではpostgresqlに接続しますが、
DBの立ち上げ部分に関しては省略します
データベース接続を作るのに、HikariCP
というものを使おうと思います
DB接続プール
HikariCP
は高速かつ効率的なデータベース接続プールライブラリです。
さっそくproject.clj
に追加します
:dependencies [[org.clojure/clojure "1.10.3"]
[duct/core "0.8.0"]
[metosin/ring-http-response "0.9.4"]
[duct/module.ataraxy "0.3.0"]
[duct/module.logging "0.5.0"]
[duct/module.web "0.7.4"]
[duct/database.sql.hikaricp "0.4.0"] ; 追加
[org.postgresql/postgresql "42.7.4"] ; 追加
[com.github.seancorfield/next.jdbc "1.3.981"] ; 追加]
ついでにpostgresql
ドライバーと、jdbc
というデータベースアクセスライブラリを入れました
次にconfig.edn
に設定を追加していきます
:duct.database.sql/hikaricp
{:adapter "postgresql"
:server-name "localhost"
:port-number "5432"
:username "user"
:password "password"
:database-name "feed"}
:clojure-rss-reader.handler.feeds/get
{:db #ig/ref :duct.database.sql/hikaricp}
ここでは、DB接続情報を:duct.database.sql/hikaricp
に設定しています。
そしてその設定情報をhandlerに渡しています。
#ig/ref
はIntegrantの依存関係の参照を表していて、:db
に渡しています
データ取得
次に、ハンドラー側の実装をいじっていきます
(ns clojure-rss-reader.handler.feeds
(:require [ataraxy.response :as response]
[integrant.core :as ig]
[next.jdbc :as jdbc]
[next.jdbc.result-set :as rs]))
(defn get-feeds [db]
(let [result (jdbc/execute! db ["SELECT * FROM feed"] {:builder-fn rs/as-unqualified-lower-maps})]
{:feeds result}))
(defmethod ig/init-key ::get [_ {{:keys [spec]} :db}]
(fn [_]
[::response/ok (get-feeds spec)]))
こんな感じで実装しました
db
を受け取りデータベースの値を返すget-feeds
という関数を作り、それをhandlerで呼び出しています
実際にリクエストを送ってみましょう
まずサーバーを起動します
$ lein repl
user=> (dev)
:loaded
dev=> (go)
:duct.server.http.jetty/starting-server {:port 3000}
:initiated
そしてリクエストを送ってみます
解説はしていませんが、postgresqlをローカルに立てています。
$ curl localhost:3000/v1/feeds | jq .
{
"feeds": [
{
"id": 1,
"url": "https://www.google.com",
"title": "Google",
"description": "Googleのトップページです。",
"created_at": "2024-12-19T05:24:36Z"
},
{
"id": 2,
"url": "https://www.yahoo.co.jp",
"title": "Yahoo! JAPAN",
"description": "Yahoo! JAPANのトップページです。",
"created_at": "2024-12-19T05:24:36Z"
}
]
}
いい感じでDBに入っているデータを取得することができました。