Fork me on GitHub
#pedestal
<
2019-02-19
>
kommen15:02:48

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]

kommen15:02:11

debug logging shows this:

kommen15:02:15

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

ddeaguiar15:02:31

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

kommen15:02:09

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

kommen15:02:33

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

kommen15:02:03

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

ddeaguiar15:02:07

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.

ddeaguiar15:02:10

Can you try this

ddeaguiar15:02:43

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

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

ddeaguiar15:02:59

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

ddeaguiar15:02:06

replace with the correct value

kommen15:02:06

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

kommen15:02:12

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

kommen15:02:17

which works

ddeaguiar15:02:36

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

ddeaguiar15:02:43

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

kommen15:02:11

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

ddeaguiar15:02:31

It’s definitely due to :context ""

ddeaguiar15:02:02

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

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

ddeaguiar15:02:05

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

ddeaguiar15:02:29

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

ddeaguiar15:02:08

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

kommen15:02:21

@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

kommen15:02:51

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

ddeaguiar15:02:02

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.

kommen15:02:06

I’ll file an issue with the info I found

kommen16:02:42

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

ddeaguiar16:02:25

thanks again 🙂

👍 5
v3ga20:02:59

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

ddeaguiar20:02:32

@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

v3ga20:02:33

@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.

ddeaguiar20:02:58

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

v3ga20:02:44

@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

ddeaguiar20:02:32

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

ddeaguiar20:02:26

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

ddeaguiar20:02:03

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

ddeaguiar20:02:38

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

ddeaguiar20:02:43

same with stopping

ddeaguiar20:02:17

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

ddeaguiar20:02:10

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

ddeaguiar20:02:35

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

v3ga20:02:23

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

ddeaguiar20:02:29

yeah it’s a different way of building a service

ddeaguiar20:02:40

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

ddeaguiar20:02:54

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

ddeaguiar20:02:17

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.

v3ga21:02:48

@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.

mkvlr21:02:52

@decim I prefer integrant