Fork me on GitHub
#reitit
<
2022-03-16
>
xbrln11:03:17

Hey all 👋, I am setting up my first project with Reitit (backend api) and trying to figure out how to make a query parameter optional. When I add a query parameter, it is by default, added as mandatory. So far I could not figure out how, if someone can give me a tip on how to make a query parameter optional that would be super helpful 🙂 Here is my code Router.clj (this is the router file where I set up all the basics for route handling)

(ns user-service.router
  (:require
    [reitit.ring :as ring]
    [user-service.favourites.routes :as favourites]
    [reitit.swagger :as swagger]
    [reitit.swagger-ui :as swagger-ui]
    [muuntaja.core :as m]
    [reitit.ring.middleware.muuntaja :as muuntaja]
    [reitit.coercion.spec :as coercion-spec]
    [reitit.ring.coercion :as coercion]
    [reitit.ring.middleware.exception :as exception]
    [ring.middleware.cors :refer [wrap-cors]]))

(def swagger-docs
  ["/swagger.json"
   {:get
    {:no-doc  true
     :swagger {:basePath "/"}
     :handler (swagger/create-swagger-handler)}}])

(def router-config
  {:data {:coercion   coercion-spec/coercion
          :muuntaja   m/instance
          :middleware [swagger/swagger-feature
                       muuntaja/format-middleware
                       exception/exception-middleware
                       coercion/coerce-request-middleware
                       coercion/coerce-response-middleware
                       [wrap-cors
                        :access-control-allow-origin [#".*"]
                        :access-control-allow-methods [:get :put :post :patch :delete]]
                       ]}})

(defn routes
  [env]
  (ring/ring-handler
    (ring/router
      [swagger-docs
       ["/v1"
        (favourites/routes env)]]
      router-config)
    (ring/routes
      (swagger-ui/create-swagger-ui-handler {:path "/"}))))
routes.clj (this is where I define the actual route)
(ns user-service.favourites.routes
  (:require
    [user-service.favourites.handlers :as favourites]))

(defn routes
  [env]
  (let [db (:jdbc-url env)]
    ["/favourites" {:swagger {:tags ["Favourites"]}}
     [""
      {:get  {:handler    (favourites/retrieve-favourite-posts db)
              :parameters {:header {:user-authorization string?}
                           :query  {:x int?}}}}]]))

xbrln11:03:01

This was one of those things when you ask a question and then you figure out the answer 🙂 I solved it by adding spec in the routes.clj like [clojure.spec.alpha :as s] And then define the query parameter like this (s/def ::x int?) Add it in query parameter with :opt-un like

:parameters {:header {:user-authorization string?}
             :query  (s/keys :opt-un [::x])}

dharrigan12:03:36

Additionally, if using malli, you can do [:x {:optional true]

v3ga18:03:50

I'm having an issue figuring out i'm getting a java.classcastexception, ByteArrayInputStream error here? It occurs write at the format-response and format-negotiate middleware. I've been toying with it for two days and i'm lost. https://gist.github.com/v3gal0g/0f902bb97882b8453637fa78d7d536d0

George Peristerakis20:03:16

Hello everyone, I'm trying to debug my ring/reitit router, and I was wandering if there's a way see the router final map expanded from the ring/handler?