I am using jet for asynchronous ring adapter.
Jet also comes with async http-client which returns a channel whose value's :body is also a channel.
Also, async server route handler can return a map whose :body key can contain a channel. When this channel would be closed, the response would be returned to the client.
I am writing following go code :
(defn- api-call-1 []
(go (-> (jet-client/get "api-url-1")
<!
:body ;; jet http client :body is also a channel.
<!
api-call-1-response-parse)))
(defn- api-call-2 []
(go (-> (jet-client/get "api-url-2")
<!
:body
<!
api-call-2-response-parse)))
(defn route-function []
(let [response-chan (chan)]
(go
(let [api-call-1-chan (api-call-1) ;; using channel returned by go
api-call-2-chan (api-call-2)]
(-> {:api-1 (<! api-call-1-chan)
:api-2 (<! api-call-2-chan)}
encode-response
(>! response-chan)))
(close! response-chan))
;; for not blocking server thread, return channel in body
{:body response-chan :status 200}))
In my route-function, i can not block.
Though this code works fine, Is using go in api-call-1 is bad ?
I found that to use <! in api-call-1 i need to put it in a go block.
Now i use this go block's channel in route-function. Does this look unidomatic ? I am concerned about not exposing api-call-1-response-parse or even :body as channel to the route-function.
What is the right way to structure go block code and functions ?
Should i care about extra go blocks in functions api-call-1/2 ?