Конфигурирование MongoDB в веб-фреймворке Clojure Luminus
У меня проблемы с настройкой базы данных MongoDB внутри проекта Luminus. Это должно быть довольно просто, учитывая шаблоны lein: https://github.com/yogthos/luminus-template. Typing lein new luminus <name> +mongodb
даст вам установку по умолчанию mongoDB, которая является файлом: src/app-name/db/core.clj
Чтобы запустить сервер, введите lein ring server
который должен открыть веб-браузер и указать его localhost:3000
по умолчанию.
Будет отображена домашняя страница по умолчанию, и для меня она говорит мне, что "Требуется конфигурация MongoDB". Это говорит мне, что я могу настроить его в том же файле: src/app-name/db/core.clj.
Я пробовал несколько разных вещей, но то, что я сейчас пытаюсь, и что для меня наиболее важно, это следующее:
(defonce coll "collection-name")
(defonce db (let [uri "mongodb://127.0.0.1/db-name"
{:keys [conn db]} (mg/connect-via-uri uri)]
db))
К сожалению, когда я подключаю свой браузер, я все равно получаю сообщение "Требуется конфигурация MongoDB". Я также пытался использовать CURL и различные HTTP-маршруты, определенные в моем приложении, которые безуспешно обращаются к базе данных. Что странно, так это то, что это работает в REPL.
РЕДАКТИРОВАТЬ: Чтобы быть более ясным, вот пример в REPL:
clj-project-name.db.core> (get-replies 2)
["mew-mew" [1.0 "hello"]]
В коде у меня есть следующие кусочки:
(ns clj-project-name.routes.home
(:require [compojure.core :refer :all]
[clj-project-name.layout :as layout]
[clj-project-name.util :as util]
[clj-project-name.db.core :as project-db]))
(defn get-replies [id] (mc/distinct db coll "replies" {:_id id}))
(GET "/user" [id] (user-page id)) ; defined in home-routes inside namespace clj-project-name.routes.home
(defn user-page [& [id]] ;defined inside namespace clj-project-name.routes.home
(layout/render "user.html"
{:id id
:replies (projectl-db/get-replies id)}))
<h1>User {{id}}'s page</h1> ; part of the HTML template
<p> <b>Replies:</b> {{replies}} </p>
Вот страница, загруженная в браузер:
Как мы видим, replies
список пуст, когда это должно быть ["mew-mew" [1.0 "hello"]]
как мы видели в REPL.
РЕДАКТИРОВАТЬ: Другая странность заключается в том, что только когда браузер загружается после ввода lein ring server
Я вижу следующий вывод из mongodb
в терминале:
2014-12-02T21:16:57.941-0500 [initandlisten] connection accepted from 127.0.0.1:38854 #28 (5 connections now open).
Что еще я могу сделать, чтобы подключиться к MongoDB? Спасибо за вашу помощь.
3 ответа
Я следовал вашим шагам и создал новый проект Luminus, используя шаблон luminus.
Я также изучил сгенерированный код и нашел, что домашняя страница по умолчанию на 100% статична. Итак, это показывает MongoDB Configuration is Required
независимо от того, настроено ли оно на самом деле:
(defn home-page []
(layout/render
"home.html" {:content (util/md->html "/md/docs.md")}))
Другими словами, это просто делает resources/public/md/docs.md
в .html
и показывает, всегда одна и та же HTML-страница.
Что касается вашей конфигурации, это абсолютно нормально.
Что касается вашего user.html
страница, реальная проблема в том, что id
в user-page
маршрут - это строка, а _id
в вашей базе есть номер. Итак, вместо (get-replies 2)
ты звонишь (get-replies "2")
, Попробуйте использовать stringified _id
s, или разобрать входящие id
с read-string
функция или Long/parseLong
первый:
(defn user-page [& [id]]
(layout/render "user.html"
{:id id
:replies (-> id
Long/parseLong ; throws NumberFormatException
project-db/get-replies)}))
Я бы порекомендовал использовать stringified _id
s, потому что это проще и безопаснее, чем разбирать строки на числа.
В вашем приложении слишком много движущихся частей, и вы предоставили нам доступ к слишком немногим из этих движущихся частей, чтобы мы могли четко определить, что вызывает у вас проблемы. Все, что мы можем сделать, это дать общий совет по устранению неполадок.
- Убедитесь, что у вас чистая среда. Выключите ваш REPL, ваш веб-сервер, возможно, даже ваш редактор. Перезапустите все по порядку и запомните этот порядок.
- Я вижу кучу странностей в коде в вашем посте, но не могу сказать, что они из вашей кодовой базы или из-за того, что вы копируете код в вопрос. Что такое проектl-db? Является
get-replies
в том же пространстве имен, что иuser-page
или нет? Убедитесь, что вы не ссылаетесь на старое определениеget-replies
в вашем репл. - В каком порядке вещи определены в
db
Пространство имен? Может бытьcoll
,db
, или жеget-replies
находятся в неправильном порядке и тихо терпят неудачу. - Ты говоришь
(get-replies)
работает в репл. Что значитuser-page
говорите в REPL? - Вы говорите, что видите сообщение "Требуется конфигурация MongoDB", но я его не вижу. Это с сервера звонков, отображается в браузере или в консоли браузера?
- Что происходит при переключении текущего определения на значение
replies
к целочисленному значению? Например, внутриuser-page
, верните карту{:id id, :replies 5}
вместо вызоваget-replies
, Ответ на этот вопрос поможет сузить источник проблемы. - Ты можешь взять
user-page
из уравнения и вернуть строку из вашегоget-routes
? Если у вас есть это, что произойдет, если вы вернетесьget-replies
(опять же, безuser-page
)?
Принцип здесь, как и при любой отладке, состоит в том, чтобы уменьшить проблему до наименьшего количества частей, которые воспроизводят проблему. Прямо сейчас у вас есть много частей, которые могут быть проблемой, и вы только показываете нам их проблески. Помогите себе, удаляя элементы, пока у вас не будет кратчайшей возможной последовательности вызовов, которая вызывает проблему. При обращении за помощью или сообщении об ошибке покажите людям этот минимальный пример, чтобы им не приходилось изучать всю вашу кодовую базу. Что еще более важно, скопированная версия кода (которую вы создаете для людей, помогающих отлаживать) может даже не иметь ошибки!
Вы также можете отлаживать в другом направлении, начиная с нового рабочего репозитория и добавляя элементы из вашего сломанного репо по одному, пока не возникнет ошибка. Это может быть полезно при изучении возможностей новой структуры, такой как Luminus.
Может быть, потому что вы используете defonce
вместо def
те вары (coll
а также db
в пространстве имен app-name.db.core
) не были перезагружены. Попробуйте остановить процесс lein и начните снова с:
lein do clean, ring server
Когда вы закончите с этим, рассмотрите возможность сделать еще один шаг с component
рабочий процесс: