pedestal

kommen 2019-02-19T15:05:48.039400Z

I’m trying to upgrade from pedestal 0.5.3 to 0.5.5, but it breaks some of our url-for calls, raising this:

[{:type java.lang.IllegalArgumentException
   :message "Don't know how to create ISeq from: clojure.lang.Keyword"
   :at [clojure.lang.RT seqFrom "RT.java" 553]}]
 :trace
 [[clojure.lang.RT seqFrom "RT.java" 553]
  [clojure.lang.RT seq "RT.java" 533]
  [clojure.core$seq__5387 invokeStatic "core.clj" 137]
  [clojure.core$empty_QMARK_ invokeStatic "core.clj" 6206]
  [clojure.core$empty_QMARK_ invoke "core.clj" 6206]
  [io.pedestal.http.route$link_str invokeStatic "route.clj" 252]
  [io.pedestal.http.route$link_str invoke "route.clj" 230]
  [io.pedestal.http.route$url_for_routes$fn__23926 doInvoke "route.clj" 369]

kommen 2019-02-19T15:06:11.039600Z

debug logging shows this:

kommen 2019-02-19T15:06:15.039800Z

2019-02-19 15:01:27.001 DEBUG io.pedestal.http.route - {:in :link-str, :path-parts [:profile-handle], :context-path-parts [""], :line 247}

2019-02-19T15:10:31.041500Z

@kommen, sorry to hear about the issues you are having. Can you share an example url-for call that is failing?

kommen 2019-02-19T15:13:09.042100Z

(url-for :show-named-profile :params {:profile-handle "foo"})

kommen 2019-02-19T15:13:33.042500Z

with this route: ["/:profile-handle" :get [profile/fetch profile/show] :route-name :show-named-profile]

2019-02-19T15:14:19.042700Z

ok thanks

kommen 2019-02-19T15:17:03.043300Z

I guess the problem is that we don’t have a string before the first url param?

2019-02-19T15:22:07.044800Z

hrm not sure. I drop that route and url-for invocation into a new pedestal app using version 5.3 and I don’t see an issue.

2019-02-19T15:22:10.045Z

Can you try this

2019-02-19T15:22:43.045300Z

(def my-url-for (route/url-for-routes (route/expand-routes routes)))

 (my-url-for :show-named-profile :params {:profile-handle "foo"})

2019-02-19T15:22:59.045600Z

I’m assuming that your routes are bound to a var named routes

2019-02-19T15:23:06.045800Z

replace with the correct value

kommen 2019-02-19T15:26:06.046300Z

ok, thanks. we use table routes, so I did this:

kommen 2019-02-19T15:26:12.046500Z

(def my-url-for (route/url-for-routes (table/table-routes routes)))
(my-url-for :show-named-profile :params {:profile-handle "foo"})

kommen 2019-02-19T15:26:17.046700Z

which works

2019-02-19T15:26:36.047Z

ok so it fails in context of a request, right?

kommen 2019-02-19T15:26:43.047200Z

right

2019-02-19T15:27:43.048100Z

Ok, so I don’t see that behavior in the quick sample I generated but I generated it using the pedestal-service template 0.5.5 and just updated the pedestal deps to 0.5.3

kommen 2019-02-19T15:30:11.049800Z

ok, thank you. I guess I hoped it was some thing obvious, will investigate further

2019-02-19T15:33:31.051200Z

It’s definitely due to :context ""

2019-02-19T15:34:02.051400Z

(def my-url-for (route/url-for-routes (route/expand-routes routes) :context ""))

 (my-url-for :show-named-profile :params {:profile-handle "foo"})

2019-02-19T15:34:05.051600Z

IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:550)

2019-02-19T15:34:29.052Z

I’m not sure why :context is set to an empty string. I don’t see that in my sample

2019-02-19T15:35:08.052800Z

I’ll look into that further when I have a chance. I’m curious. Tracking down where :context "" is being set is where I’d start looking

kommen 2019-02-19T15:49:21.053800Z

@ddeaguiar It looks like in pedestal 0.5.5 there is always a :context-path on the request in https://github.com/pedestal/pedestal/blob/0.5.5/route/src/io/pedestal/http/route.clj#L209

kommen 2019-02-19T15:49:51.054500Z

which causes context-path-parts to be [""] instead of nil

2019-02-19T15:54:02.056500Z

Ok, thanks for digging through that. I’ll take a closer look. I’ll likely update the release notes with breaking change info and possibly open an issue around it.

kommen 2019-02-19T15:56:06.057100Z

I’ll file an issue with the info I found

2019-02-19T16:03:13.057300Z

:thumbsup:

kommen 2019-02-19T16:03:42.057800Z

it also reproduces with the stock lein example in the context of a request

kommen 2019-02-19T16:16:41.058100Z

https://github.com/pedestal/pedestal/issues/610

2019-02-19T16:19:25.058400Z

thanks again 🙂

👍 1
v3ga 2019-02-19T20:18:59.060100Z

Does anyone here have any basic examples of a pedestal CRUD project with mount/component and a database?

2019-02-19T20:23:32.061Z

@decim creating such an example has been on my todo list for a while. If you have specific questions perhaps I can provide some guidance

v3ga 2019-02-19T20:26:33.063500Z

@ddeaguiar i’m very much at the beginning of it. I’ve gone through the provided tutorials and I’m really just trying to figure out where to go, what all is necessary. Even something as simple as making a post. For starters i’d like to know how to just serve a basic index.html page from my resources folder. As I get a hold on things I’ll start to make blog posts for people in the future interested.

2019-02-19T20:28:58.064500Z

To serve files, add the :io.pedestal.http/resource-path key to your system map. This will serve any files which match url from that dir

v3ga 2019-02-19T20:30:44.066Z

@ddeaguiar ok, nice. I really have to start looking through the source as well today. I’m coming from frameworks like ruby on rails so these libraries are very bare bones which isn’t a bad thing, it’s good to know exactly what’s taking place

2019-02-19T20:33:32.067500Z

I’ve experimented with component and pedestal quite a bit on various projects and I’m now more discerning about bringing the two together.

2019-02-19T20:34:26.068200Z

Pedestal provides a configuration map which you can append anything to at runtime, during system startup

2019-02-19T20:35:03.068900Z

They key concept is to create interceptors which provide access to those things you need (i.e., db connection, etc…)

2019-02-19T20:35:38.069600Z

If you need to start things, you already have the facilities to do it and append the started thing to the service map

2019-02-19T20:35:43.069800Z

same with stopping

2019-02-19T20:35:44.070Z

but

2019-02-19T20:36:17.070600Z

If you really want to use component or mount or whatever, you can

2019-02-19T20:39:10.073300Z

My current line of thinking here is: - Define routes in one place - Limit components to external dependency needs (db, queueing system, etc…) - Use interceptors as glue to make those dependencies available on the context map and/or request - Do more processing in interceptors and limit handlers to formatting responses - With Component, have the Pedestal component depend on all other components and be responsible for putting their interceptor glue on the interceptor chain

2019-02-19T20:41:20.073900Z

Here are some examples of component+pedestal that I’ve tinkered with: https://github.com/pointslope/elements/blob/master/src/pointslope/elements/pedestal.clj#L1, https://github.com/ddeaguiar/component-pedestal

2019-02-19T20:41:35.074500Z

TBH, I’m not happy with either of them but you can use that for inspiration

v3ga 2019-02-19T20:47:23.075400Z

Hmm ok, I see. Looking at ‘elements’ now. It almost seems as if it’s better to start from scratch opposed to lein new pedestal service app-name

2019-02-19T20:48:29.075700Z

yeah it’s a different way of building a service

2019-02-19T20:50:40.076500Z

Again, take it with a grain of salt. Those projects are old and I’ve not had the need leverage component + pedestal lately

2019-02-19T20:50:54.076900Z

But if you are just learning pedestal, then stick with the service template

2019-02-19T20:56:17.078800Z

It’s perfectly acceptable to provision dependencies on system startup via -main or run-dev and add the interceptors which provide access to those started resources at that point.

v3ga 2019-02-19T21:09:48.080700Z

@ddeaguiar yeah i’m wondering if using component or mount is overkill as well. I may be experimenting with too many things at once. long term for this toy project i’d like to use it but I suppose I shouldn’t fear a complete rewrite after I know what’s taking place. So you do prefer component over mount? I’ve seen a bit of discussion about that.

mkvlr 2019-02-19T21:41:52.081Z

@decim I prefer integrant

mkvlr 2019-02-19T21:42:52.081600Z

@decim check out https://lambdaisland.com/episodes/integrant