Fork me on GitHub

Hey all, I've been away for a while, will try to catch up and answer some of the questions that have been posted here in the last couple of weeks. This is my one day in Slack before heading out on vacation until mid-July. If you post a question here and don't get an answer, I'd encourage you to post to the pedestal-users list. (!forum/pedestal-users)


@mpenet Regarding the double-colon... without a namespace you get a keyword in the current namespace. But ::http/port uses whatever the local alias http expands to. So as long as there was a (require '[io.pedestal.http :as http]) then ::http/port expands to :io.pedestal.http/port.


@lxsameer The docs do suck, but we can make them better. I added to make sure we document resource and fast-resource.


@mtnygard good, I'm happy to help with it as much as i can


@mgrbyte As you've deduced, #vase/transact is limited to assert and retract. There are three ways you can go:


1. Create a new reader literal in your own namespace. This is the high-effort approach but will give you something that feels native to Vase.


2. Use #vase/intercept to write an interceptor directly in your Vase file. This will get a little wordy but it definitely works.


mtnygard: Thanks for these pointers 👍 So, to check I understand correctly; I could write my own fn which does d/transact w :db.fn/cas and call that within #vase/intercept?


Yes, exactly.


great, thanks 🙂


Attempting to write a custom interceptor #vase/intercept just to test I've got this down, I do:

#vase/intercept  {:name :roscoff.service/intercept
                        :enter (fn [ctx]
                                 (roscoff.service/intercept ctx))}


That looks like it should work. You just need to make sure you require roscoff.service before you load the descriptor file.


which work (that "intercept" fn just does a println right now - but I always get "Not found" from the client (even tho the fn is being called as I see the prints in my repl)


I assume I'm not obeying the contract/interface for vase/intercept - I assumed it should return the ctx


The 404 is probably because you're not supplying a response anywhere. Pedestal assumes that if no interceptor adds a response, it means the request can't be handled.


Yes, the interceptor should definitely return the ctx


hmm. So I thought: (assoc ctx :response {:my-key "some data"}) would be enough to add a response, but still get the not found. thanks for all your help here.


It needs a body. Try (assoc ctx :response {:body {:my-key "something"}})


No idea what I've not got right, but that work either 😕


So I changed it to ` (assoc ctx :response (ring-resp/response "{:something 1}")))`


and that does work


Hmm. All that does is create a map with a body and a status. So I must be misremembering... Pedestal must be looking for a :status on the response too.


yep - that does the trick (requries status too)


Sorry about that.


So I have :vase.api/interceptors [io.pedestal.http/json-body] and a custom #vase/intercept working now, which I think gives me the basis to not re-invent/fork vase (which I was considering!)


no, thank you! 💯 🙂


3. Write a function in your own namespace and use #vase/intercept in your Vase file to call that function.


I've got some changes in the works that will make it easier to add new interceptors and literals, but that's still a few weeks away from landing in master. If you want a sneak peek you can check my fork at


Keep in mind that troubleshooting errors with #vase/intercept defined interceptors is difficult


at least atm


@jjttjj I think you're asking if you can define specs in regular namespaces, then refer to them in Vase under the :vase/specs key. If you've registered the specs, then you can use them in validate literals even without referring to them in the :vase/specs key.


@shaun-mahood I hope the new section in the hello-world-content-types guide helped with the transition to cond->. LMK if it's still too big a jump.


@shaun-mahood Re: syntax quoting. You can provide a fully-qualified symbol in a route and Pedestal will assume you want to use a keyword with the same namespace and name as your route name. That's the only place it works. That's only needed if you use a "handler function" in the last position and let Pedestal turn it into an interceptor. Personally, I prefer to write my interceptors directly and provide a :name key in the map. It's largely a matter of style.


@lxsameer I've created about extending Pedestal via protocols.


@lxsameer The short answer is: the best protocol to extend is Interceptor. The second-best is IntoInterceptor. If you're doing something fancy with routing then RouterSpecification is interesting.


If you want to do something custom with response bodies, you can extend WriteableBody or WriteableBodyAsync to any kind of arbitrary object.


@shaun-mahood I've added an issue for the docs about syntax-quoting.


@jjttjj Re: payload for the vase-component sample. The payload must actually be json. I don't know why the docs imply that EDN works for input. I'm kind of surprised that it didn't work when you used the json content-type though. Do you still have the client-side code around? If so, can you share it with me?


@mtnygard: Thanks, I'll take a read through and follow up on that issue if I still don't understand the syntax quoting details. The change to the cond-> bit in the docs was much clearer too!


@mtnygard nice, I'm trying to create a router