Доступ к строке запроса Compojure

Я пытаюсь извлечь значение из строки запроса URL-адреса, однако я могу вернуть то, что, по моему мнению, является картой, однако, когда я использую приведенный ниже код, он не обрабатывает его должным образом. Может ли кто-нибудь посоветовать, как получить доступ к определенным значениям в возвращаемой структуре данных строки запроса?

http://localhost:8080/remservice?foo=bar

(defroutes my-routes
  (GET "/" [] (layout (home-view)))
  (GET "/remservice*" {params :query-params} (str (:parameter params))))

person Dale    schedule 22.01.2012    source источник
comment
Вот два вопроса. Эта функция принимает параметр? Что такое ПОЛУЧИТЬ? Вот почему я спрашиваю. Вы должны иметь возможность извлечь то, что вам нужно, из параметров, но где параметры?   -  person octopusgrabbus    schedule 22.01.2012


Ответы (4)


Вам нужно будет обернуть обработчик в compojure.handler/api или compojure.handler/site, чтобы добавить соответствующее промежуточное ПО для получения доступа к :query-params. Раньше это происходило автоматически в defroutes, но больше не происходит. Как только вы это сделаете, форма деструктурирования {params :query-params} приведет к тому, что params будет привязана к {"foo" "bar"}, когда вы нажмете /remservice с foo=bar в качестве строки запроса.

(Или вы можете добавить wrap-params и т. д. вручную — они находятся в разных ring.middleware.* пространствах имен; см. rel="noreferrer">код compojure.handler (ссылка на соответствующий файл в Compojure 1.0.1) для их имен.)

E.g.

(defroutes my-routes
  (GET "/remservice*" {params :query-params}
       (str params)))

(def handler (-> my-routes compojure.handler/api))

; now pass #'handler to run-jetty (if that's what you're using)

Если вы сейчас нажмете http://localhost:8080/remservice?foo=bar, вы должны увидеть {"foo" "bar"} — текстовое представление строки вашего запроса, преобразованное в карту Clojure.

person Michał Marczyk    schedule 23.01.2012
comment
Хорошо, я получил карту, но я не могу получить доступ к отдельным записям, например. (:foo params) или (get params foo) или (map :foo params) ничего не возвращает. Я думаю, что моя основная путаница вокруг этой структуры карты вернулась. - person Dale; 23.01.2012
comment
Это потому, что ключи хранятся в виде строки — вам нужно будет использовать (get params "foo"). В качестве альтернативы вы можете использовать :params вместо :query-params -- api Compojure добавляет промежуточное ПО wrap-keyword-params, поэтому карта :params является ключевой -- но обратите внимание, что :params включает оба типа параметров (другие параметры формы; параметры запроса переопределяют параметры формы в :params карту). - person Michał Marczyk; 23.01.2012
comment
Как сделать что-то вроде этого: /users/123?sort=desc У меня есть параметры, переданные вектору. - person Justin Thomas; 08.12.2015

В приложении по умолчанию для compojure 1.2.0 промежуточное ПО строки запроса включено по умолчанию. Вы можете проверить запрос как таковой.

(GET "/" request (str request))

В нем должно быть много всего, включая ключ params.

{ . . .  :params {:key1 "value1" :key2 "value2} . . . }

Таким образом, вы можете включить стандартную форму деструктурирования Clojure для доступа к параметрам запроса в свой ответ.

(GET "/" {params :params} (str params))

Ваша страница должна выглядеть следующим образом.

{"key1" "value1", "key2" "value2"}

Однако, как отмечено в комментарии Михала выше, ключи преобразуются в строки, и если вы хотите получить к ним доступ, вам нужно использовать функцию получения, а не более удобный поиск символов.

(GET "/" {params :params} (get params "key1"))

;;the response body should be "value1"
person rewon    schedule 29.10.2014

С compojure 1.6.1 HTTP-запросом-деструктуризация у меня работает так:

  1. добавить [ring/ring-defaults "0.3.2"] в :dependencies в project.clj (поскольку пространство имен compojure.handler устарело с версии 1.2 в пользу [ring-defaults])
  2. добавить [ring.middleware.defaults :refer :all] в :require в your.routes.namespace
  3. добавить (def site (wrap-defaults app site-defaults)) в your.routes.namespace, где app объявлено через (defroutes app ...
  4. добавить :ring {:handler your.routes.namespace/site} в project.clj
person Dedkov Vadim    schedule 24.06.2018

Мне повезло в compojure 1.1.5, не нуждающемся в обертке и могущем использовать директиву :as

(GET "/tweet/:folder/:detail" [folder detail :as req]
  (twitter-controller/tweet folder detail (-> req :params :oauth_verifier))
person Dax Fohl    schedule 26.09.2013