1

I have a simple Node JS app that serves an API. I can node main.js to get the server running and call localhost:3000/api/names to successfully get a list of names. I want to build on this with Reagent/Cljs.

I can get a Reagent app up an running on localhost:3030. My problem is, how do I make API calls to the Node app from the Reagent app? Or is my architecture all wrong? Should I combine the two apps, and if so, how?

I have tried combining them, but Reagent wants to run on Ring, while the Node app wants to run on the node server. So I still have no communication between the two. I've tried going through the Quick Start guide, but this isn't quite same situation. I've also given this approach a go to no avail. What is the easiest way to put these pieces together so that I can bring the API response data from the Node app to the Reagent app? Or is there a way to call make the API calls from within the Reagent app that I'm missing?

1 Answer 1

1

Yes, you need to communicate between the code running in the browser and the code running on the server.

The basic approach is to use XHR. The client should do something like this:

(ns foo
  (:require [goog.net.XhrIo :as xhr]))

(xhr/send "/api/names"
          (fn [e]
            (prn (.. e -target getResponseText))))

Alternatively there is a very widely used library cljs-http

 (ns foo
  (:require
    [cljs.core.async :refer [<!]]
    [cljs-http.client :as http])
  (:require-macros
    [cljs.core.async.macros :refer [go]]))

(go (let [response (<! (http/get "data.edn"))]
      (prn (:status response))
      (prn (:body response))))

It uses core.async to return the results to you over a channel. You don't really need to care about that to use it though, except to note that things in go blocks are going to happen 'later'.

For advanced usage, you can create websockets with sente

One important consideration with web pages is that they can only perform XHR with the same host on the same port that served the page. So if you are hosting your API at localhost:3030, then the page must be served from localhost:3030 for you to be able to communicate with it. (This is called the same origin policy).

You stated in your question that you have your API on port 3000 and the Reagent app served from 3030. This will not work because of the same origin policy. There is a standard called CORS Cross Origin Resource Sharing which technically you can use, but in practice just don't do this. Instead serve the HTML/Javascript from the same server as the API.

What this means for you is just that you need to be sure that when you build your Reagent app, the HTML page that includes the final JavaScript needs to be served by the same server that serves your API. Usually this is a matter of putting the HTML and JavaScript into a resources folder on the server.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.