Fork me on GitHub
#yada
<
2019-12-01
>
lispyclouds08:12:22

Hello, Im playing around with yada and evaluating it for an existing API only app. Here is the code Im trying:

(ns yada-yada.core
  (:require [clojure.repl :as repl]
            [yada.yada :as yada]
            [yada.swagger :as swag]
            [mount.core :as m]
            [schema.core :as s]
            [manifold.deferred :as d])
  (:gen-class))

(m/defstate db
  :start (atom {})
  :stop (reset! db {}))

(defn get-value
  [ctx]
  (let [key (get-in ctx [:parameters :query :key])]
    {:value (@db key)}))

(defn set-value
  [ctx]
  (let [{:keys [key value]} (get-in ctx [:parameters :body])]
    (swap! db assoc key value)
    {:message "Ok"}))

(s/defschema Pair
  {:key   String
   :value s/Int})

(def data-resource
  (yada/resource
   {:produces "application/json"
    :consumes "application/json"
    :methods  {:get  {:parameters {:query {:key String}}
                      :response   get-value}
               :post {:parameters {:body Pair}
                      :response   set-value}}}))

(defn async
  [ctx]
  (d/let-flow [x             4
               y             5
               {:keys [a b]} (get-in ctx [:parameters :query])]
    {:message (+ a b x y)}))

(def async-resource
  (yada/resource
   {:produces "application/json"
    :methods {:get {:parameters {:query {:a s/Int
                                         :b s/Int}}}}
    :response async}))

(def routes
  [""
   (swag/swaggered
    ["/"
     [["data" data-resource]
      ["async" async-resource]]]
    {:info {:title       "Hello World!"
            :version     "1.0"
            :description "A yada service"}})])

(m/defstate server
  :start (yada/listener routes {:port 3000})
  :stop ((:close server)))

(defn shutdown!
  [_]
  (m/stop)
  (System/exit 0))

(defn -main
  [& _]
  (repl/set-break-handler! shutdown!)
  (m/start))

(comment
  (m/start)

  (m/running-states)

  (m/stop))
I have 2 questions: • How to give a 404 here when none of the routes match with a resp like: {:message "Wrong route"} ? • Whats a good way to ignore the trailing slash on routes?

malcolmsparks08:12:52

1. Use a bidi 'backstop' route of [true (yada/yada nil)]

malcolmsparks08:12:33

2. Use bidi redirects

lispyclouds08:12:22

for the backstop one i tried:

(def routes
  [""
   (swag/swaggered
    ["/"
     [["data" data-resource]
      ["async" async-resource]
      [true (yada/yada nil)]]]
    {:info {:title       "Hello World!"
            :version     "1.0"
            :description "A yada service"}})])
but this gives an error: No implementation of method: :encode of protocol: #'yada.swagger/SwaggerPath found for class: java.lang.Boolean Im guessing the place is wrong?

lispyclouds08:12:00

the other places in the tree it gives a 204 when no routes matched

malcolmsparks08:12:01

Do it outside the swagger routes

malcolmsparks08:12:38

Wrap the whole routes structure

lispyclouds09:12:55

should this be like

(def routes
  (swag/swaggered
   [""
    [["/data" data-resource]
     ["/async" async-resource]]]
   {:info {:title       "Hello World!"
           :version     "1.0"
           :description "A yada service"}}))

malcolmsparks09:12:21

No, what you had before looked right. Just wrap the whole thing in another route. In bidi you can keep wrapping

lispyclouds09:12:58

tried

(def routes
  [""
   [""
      (swag/swaggered
       ["/"
        [["data" data-resource]
         ["async" async-resource]]]
       {:info {:title       "Hello World!"
               :version     "1.0"
               :description "A yada service"}})]
   [true (yada/yada nil)]])
but got No implementation of method: :match-pattern of protocol: #'bidi.bidi/Pattern found for class: nil Sorry probably not really grasping the routing you're mentioning 😞