reitit

https://cljdoc.org/d/metosin/reitit/ https://github.com/metosin/reitit/
Jen W 2021-03-10T12:09:44.014600Z

Hi, how would I go about adding a custom Last-Modified header to all responses at router level? I’m assuming this should be done at a response coercion level but I’m not sure how to wire it up.

bartuka 2021-03-10T13:05:27.016400Z

hi, I have some name-based routing in a project and I would like to add more methods to the same route path. Something like this:

["/add"
  {:name :my-route/list
   :get {:handler ...}}

 {:name :my-route/create
  :post {:handler ..}}]
This snippet does not work, what is the proper way to achieve this? thanks!

dharrigan 2021-03-10T13:12:12.016700Z

Hi...like this

dharrigan 2021-03-10T13:12:16.016900Z

["" {:get {:handler (search app-config)
               :parameters {:query specs/search}
               :swagger {:produces [poi-search-api-version]}}
         :post {:handler (create app-config)
                :parameters {:body specs/create}
                :swagger {:produces [poi-create-api-version]}}}]

bartuka 2021-03-10T13:16:13.017200Z

but I would like to keep the :name key.. On testing I've been using match by name on other endpoints

dharrigan 2021-03-10T13:16:51.017400Z

Don't know then

juhoteperi 2021-03-10T13:32:06.017600Z

IIRC :name matches just the route, not the method

juhoteperi 2021-03-10T13:33:51.017800Z

["" {:name :my-route
         :get {:handler (search app-config)
               :parameters {:query specs/search}
               :swagger {:produces [poi-search-api-version]}}
         :post {:handler (create app-config)
                :parameters {:body specs/create}
                :swagger {:produces [poi-create-api-version]}}}]

(get (match-by-name routes :my-route) ...)
(post (match-by-name routes :my-route) ...)

dharrigan 2021-03-10T13:37:00.018Z

:thumbsup:

bartuka 2021-03-10T14:01:16.018500Z

got it, thanks @juhoteperi and @dharrigan

dharrigan 2021-03-10T14:09:28.018700Z

np

jmckitrick 2021-03-10T14:41:54.019300Z

So I see that `reitit` supports `malli` (of course), and `reitit` supports `swagger`, and `malli` supports `swagger`. But... can I use `malli` on my `reitit` routes and produce `swagger` docs in one fell swoop?

jmckitrick 2021-03-10T15:39:58.022900Z

Thanks!

jmckitrick 2021-03-10T15:55:32.023600Z

Well, my current codebase will not let me switch to Malli at the moment.

jmckitrick 2021-03-10T15:55:59.024100Z

So my question now is about the 'or' specs, such as (s/or :string spec/string? :int spec/number?)

jmckitrick 2021-03-10T15:56:36.024900Z

How can I make swagger show the string as the preferred type? The order of the specs does not seem to matter... 'int' appears to take precedence.

ikitommi 2021-03-10T16:00:15.028700Z

spec doesn't support metadata, but you could wrap you spec into spec-tools.core/schema , something like (st/schema (s/or ...) {:swagger/type "string"}). Not at computer, so the syntax might be wrong.

ikitommi 2021-03-10T16:02:14.031500Z

it's basically a no-op wrapper with support for metadata (among other add-ons)

jmckitrick 2021-03-10T16:03:36.032500Z

So that wouldn't require moving away from our current 'data spec' use on endpoints? I'll be adding more spec to other endpoints, but I would like to stay consistent.

ikitommi 2021-03-10T16:10:31.038500Z

well, that's one of the root causes for developing malli: data-specs (or plumatic) syntax is good for simple things, but gets messy when one needs to add things like meta-data. You can mix data-specs and specs, but it's two systems instead of one.

ikitommi 2021-03-10T16:11:03.039500Z

if there are ideas how to extend data-specs to support metadata without tears, happy to add that.

jmckitrick 2021-03-10T16:11:16.039800Z

I'm afraid tears will be part of my job, lol.

jmckitrick 2021-03-10T16:13:16.040800Z

I'm looking for the 'schema' function to add metadata, and I'm not seeing it...

jmckitrick 2021-03-10T16:13:27.041200Z

Going to browse the ns and keep looking...

ikitommi 2021-03-10T16:13:43.041700Z

oh, st/spec

jmckitrick 2021-03-10T16:14:31.041900Z

Aha! Thanks

jmckitrick 2021-03-10T16:15:12.042100Z

Those look like all predicates....

2021-03-10T16:26:18.044300Z

Hi 👋! Is there a way to gradually migrate a giant api server built with compojure to reitit routing? I'd like to showcase a small working example within my organization without having to rewrite the world. Thanks 🙏

ikitommi 2021-03-10T16:48:34.049700Z

Maybe:

(def compojure-app 
  (c/GET "/old" [] handler)

(def reitit-app
  (rr/ring-handler
    (rr/router
      ["/new" {:get handler}])))

(def app
  (rr/routes compojure-app reitit-app))

ikitommi 2021-03-10T16:49:53.051700Z

... then move stuff one by one. I recommend to run a perf test before and after (full migration)

2021-03-10T16:53:46.052600Z

Oh! Really cool. Thanks; I will try that!

Jen W 2021-03-10T16:59:23.053500Z

Hello again, I wonder if anyone’s got any ideas for the response headers Q? (sorry to double post, I’ve just not had any luck looking through the codebase or docs for this) https://clojurians.slack.com/archives/C7YF1SBT3/p1615378184014600

ikitommi 2021-03-10T17:03:41.056600Z

@jen you should mount a middleware to all routes for that. It's all ring: all request/response handling is done either in the mw (reusable) or in the handler.

🙇 1
Jen W 2021-03-10T17:41:27.057900Z

thanks I’ll go hunt in ring docs rather than reitit then for wiring up examples. Thanks!