简体   繁体   中英

How can I communicate with the backend using ClojureScript and Figwheel?

Note: I'm a moderately experienced programmer in general and using clojure but have never done serious web development.

I set up a basic ClojureScript project using Chestnut and walked through the "Hello World" steps just fine. However I would really like to talk to my backend as well. For this purpose I redefined the Reagent code to be

(defn greeting []
  [:input {:type "button"
       :value (:text @app-state)
       :on-click #(http/get {})}])

Which gets a 404 response when clicked. So at least I'm talking to somebody. I can also see evidence of my get-requests in the server.log file. However at this point I'm struggling with a number of conceptual points.

First of all http/get is a function defined in clj-http.client, which wasn't part of the Chestnut setup. It feels like I'm already off track if I have to go hunting for libraries to send something as basic as a get-request.

Secondly the file for the user namespace has the following lines predefined by Chestnut:

(def http-handler
  (wrap-reload #'mypage.server/http-handler))

(defn run []
  (figwheel/start-figwheel!))

I can't see any place where the http-handler is ever used. So I don't understand what that definition even does.

Also the way I understand Figwheel, when I call "run" it'll spin up a new web server which then a) serves the index.html and b) connects to my browser via some TCP port and starts pumping new JavaScript through that connection. This second part is very speculative on my part. If this is actually what happens my next question would be if Figwheel also needs to sit on the other side of that connection or if browsers have some common API that allows code reloading from the outside.

Lastly I can kinda tell that the ring routes and http-handler defined in the mypage/server.clj file (below) are being called somehow, since modifying these changes the error from the get-request, however it's a complete mystery to me how this works. The way I understand it the get-request I'm sending from the browser is sent to the Figwheel-server, the origin of the site. I have no reason to believe that Figwheel knows anything about the http-handlers I've defined in the server file.

(defroutes routes
  (GET "/" _
    {:status 200
     :headers {"Content-Type" "text/html; charset=utf-8"}
     :body (io/input-stream (io/resource "public/index.html"))})
  (resources "/"))

(def http-handler
  (-> routes
      (wrap-defaults api-defaults)
      wrap-with-logger
      wrap-gzip))

对于ClojureScript项目(即不是Clojure),我相信你想要这个: https//github.com/r0man/cljs-http

I don't have a complete answer, but I do have a couple points that might help.

  1. Clojurescript ultimately compiles down to JavaScript, and makes heavy use of (and has access to) the Google Closure library. So if you really want to, you can use JavaScript interop to just make an AJAX call from the client-side, just like you would in JS. The closure library provides a wrapper for this---see docs here https://developers.google.com/closure/library/docs/xhrio . But there are also several easy http and Ajax libraries for clojurescript, so why not use them? Another part of the joy and magic of clojurescript is that the Google closure optimizations that get applied do lovely things like strip out dead code, so I believe (and someone else can correct me if I'm wrong) that there is little (no?) production cost to putting some extra libraries in.

  2. Figwheel is ultimately dev, not production, and doesn't depend on the http server that you set up for production use. Indeed, there are templates out there for front-end-only cljs projects that still use figwheel--- here's one example . Figwheel spins its own server to push changes to the browser, I'm not quite sure how it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM