Tools.namespace usage with Pedestal basic web service

Hi,
I’m trying to make use of clojure.tools/namespace to be able to reload my very basic web service that I build with Pedestal… and obviously there’s something I don’t understand.
My goal was to be able to, start the server, test it, make some changes on the code, stop, refresh and start the server again to see my changes… and all this without having to restart the Repl. My problem is that applying this workflow doesn’t reflect the changes I made to the code and I can’t see why.

The project can be found here, and here is a summary to what I did:

  • added clojure.tools/namespace to deps.edn in a dedicated :dev profile
  • create a ./dev/user.clj at project root - in here I plan to put the code to start/stop and refresh. I’m also calling (set-refresh-dirs "src") because I don’t whant ./dev to be reloaded
  • start Repl (Im using Calva)
  • evaluate user.clj and then start the server.
(def srv (server/start))

At this point the server is started and everything seems fine.

  • make some modification in the /greet handler function and save
  • from user.clj stop, refresh, and start the server again
(server/stop srv)
(refresh)
;;clj꞉user꞉>  
;;:reloading (play-3.play-3)
;;:ok
(def srv (server/start))

The server is up, but /greet returns the exact same response as before :frowning:
Any help would be very appreciated …
Thanks in advance

You can have your changes take effect without restarting your server and without using tools.namespace. :smiley:

Change (routes) to routes here: clojure-playground/play_3.clj at 28e7778aee2e598430f4c12bdb07744efb3213aa · raoul2000/clojure-playground · GitHub

When :io.pedestal.http/routes in your service map is a function, pedestal evaluates it to get the routes each time a request comes into your service (if I understand correctly).

With that change in place, update your response in respond-hello to something new, evaluate the respond-hello function again in your repl, then hit your greet endpoint again and you’ll see the change. I tested this myself with your project.

1 Like

Thanks for your reply @bpringe it works as expected… :+1:

…actually my goal also to understand how to use tools.namespace. I still don’t get why calling refresh didn’t reload the /greet handler. There may be soms persistent stuff that is not refreshed … but what ? …

:sunglasses:

You’re welcome. I think what’s happening when you see the old version of the handler code running after you call refresh is that it is reloading the play_3.clj, but the user ns still refers to the old version of that namespace, referred in user as server. So at that point, stopping the server and restarting it restarts the old version of the server, which uses the old version of the /greet handler.

After you run refresh, if you try to load the user ns, you’ll get an error that server is already defined. You can fix that by running (ns-unalias 'user 'server), then loading the user ns again. This loads the new version of the play-3.play-3 ns, aliased as server. After that you can start your server again and see the change reflected when you hit the greet handler.

I actually had the code update work a couple of times without the user ns load error mentioned above (I believe I stopped and started the server after calling refresh and loading the user ns without error), but I think those times were only after just starting a new repl. I don’t know why it worked differently then.

1 Like

Thanks again for this clear explanation…

I understand better this case now and more important I understand I need to study some more about namespaces in clojure (because obviously I’m not comfortable with them) :slight_smile:

That I will do …

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.