0

I have a server hosting my API. My API relies on data requested from a third-party API (Spotify). Here are the relevant parts of my API handler:

(ns myapp.api.handler
  (:require
    [compojure.api.sweet :refer :all]
    [ring.util.http-response :refer [ok forbidden no-content not-found bad-request]]
    [clj-spotify.core :as spotify]))

(defroutes api-routes
  (api
    {:middleware [wrap-api]
     :swagger {:ui "/api-docs"
               :spec "/swagger.json"
               :data {:info {:title "My API"
                             :description "A description for My API"}
                      :consumes ["application/json"]
                      :produces ["application/json"]}}}
    
    (context "/api" []
      (context "/me" []
        (PUT "/player" []
          :query-params [device_id :- String]
          (handle-player-put device_id))))))

As you'll be able to tell from my route handler, I'd essentially like to forward the response of the third-party API to my API. Here is the handler function, handle-player-put:

(defn handle-player-put [device-id]
  (let [available-devices (-> (spotify/get-current-users-available-devices
                                {}
                                (lm/oauth-token :spotify))
                              :devices)]
    (doseq [device available-devices]
      (when (= (:id device) device-id)
        (if (not (:is_restricted device))
          (let [response (spotify/transfer-current-users-playback
                           {:device_ids [device-id]
                            :play false}
                           (lm/oauth-token :spotify))]
            (case (-> response :error :status)
              nil (no-content)
              404 (do
                    (println "Playback response: 404")
                    (not-found "Spotify could not find the requested resource."))
              {:status (-> response :error :status)
               :headers {}
               :body (-> response :error :message)})))))))

After a successful (spotify/transfer-current-users-playback) request, response binds to {}. An example of a response after an error looks like {:error {:status 502, :message "Bad gateway."}}

No matter whether transfer-current-users-playback is successful or not, I always get a 404 error (with body text Not Found [404]). What am I doing wrong?

duplic8
  • 109
  • 1
  • 9

1 Answers1

1

doseq always returns nil so your handler returns nil - which is interpreted by compojure as “this handler won’t handle the request; skip to the next handler” and if no other handler handles the request you get a 404 not found.

You should not use (doseq … (when … expr))) if you need to return expr

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53