Конфигурирование 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>  

Вот страница, загруженная в браузер:

страница, показывающая, что звонок на mongodb не работает

Как мы видим, 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 _ids, или разобрать входящие 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 _ids, потому что это проще и безопаснее, чем разбирать строки на числа.

В вашем приложении слишком много движущихся частей, и вы предоставили нам доступ к слишком немногим из этих движущихся частей, чтобы мы могли четко определить, что вызывает у вас проблемы. Все, что мы можем сделать, это дать общий совет по устранению неполадок.

  1. Убедитесь, что у вас чистая среда. Выключите ваш REPL, ваш веб-сервер, возможно, даже ваш редактор. Перезапустите все по порядку и запомните этот порядок.
  2. Я вижу кучу странностей в коде в вашем посте, но не могу сказать, что они из вашей кодовой базы или из-за того, что вы копируете код в вопрос. Что такое проектl-db? Является get-replies в том же пространстве имен, что и user-page или нет? Убедитесь, что вы не ссылаетесь на старое определение get-replies в вашем репл.
  3. В каком порядке вещи определены в db Пространство имен? Может быть coll, db, или же get-replies находятся в неправильном порядке и тихо терпят неудачу.
  4. Ты говоришь (get-replies) работает в репл. Что значит user-page говорите в REPL?
  5. Вы говорите, что видите сообщение "Требуется конфигурация MongoDB", но я его не вижу. Это с сервера звонков, отображается в браузере или в консоли браузера?
  6. Что происходит при переключении текущего определения на значение replies к целочисленному значению? Например, внутри user-page, верните карту {:id id, :replies 5} вместо вызова get-replies, Ответ на этот вопрос поможет сузить источник проблемы.
  7. Ты можешь взять user-page из уравнения и вернуть строку из вашего get-routes? Если у вас есть это, что произойдет, если вы вернетесь get-replies (опять же, без user-page)?

Принцип здесь, как и при любой отладке, состоит в том, чтобы уменьшить проблему до наименьшего количества частей, которые воспроизводят проблему. Прямо сейчас у вас есть много частей, которые могут быть проблемой, и вы только показываете нам их проблески. Помогите себе, удаляя элементы, пока у вас не будет кратчайшей возможной последовательности вызовов, которая вызывает проблему. При обращении за помощью или сообщении об ошибке покажите людям этот минимальный пример, чтобы им не приходилось изучать всю вашу кодовую базу. Что еще более важно, скопированная версия кода (которую вы создаете для людей, помогающих отлаживать) может даже не иметь ошибки!

Вы также можете отлаживать в другом направлении, начиная с нового рабочего репозитория и добавляя элементы из вашего сломанного репо по одному, пока не возникнет ошибка. Это может быть полезно при изучении возможностей новой структуры, такой как Luminus.

Может быть, потому что вы используете defonce вместо defте вары (coll а также db в пространстве имен app-name.db.core) не были перезагружены. Попробуйте остановить процесс lein и начните снова с:

lein do clean, ring server

Когда вы закончите с этим, рассмотрите возможность сделать еще один шаг с component рабочий процесс:

https://github.com/stuartsierra/component

Другие вопросы по тегам