2
votes

Summary

I am developing a server to be like a sort of a proxy in Clojure, with pedestal service + lein as a base:

  • Receive requests
  • Forward requests to external servers
  • Make multiple requests server-to-server to feed a bigger json and return as a single request to the client

It's easy to code and there are many resources on how to serve a route,
however I could not find any easy way, how to have a Clojure pedestal rest
service together with forwarding routes

Example

  • Client calls [GET] /billing => proxy-clojure-server
  • proxy-clojure-server authenticate request with client credentials => auth-server
  • proxy-clojure-server fills json with billing data => billing-server
  • proxy-clojure-server fills json with customer data => customer-server
  • proxy-clojure-server returns 200 with complete JSON resolved

Setup

  • I have a project with a similar structure as doing: lein new pedestal-service my-app

What I've been trying

Example:

(ns your-ns
  (:require [tailrecursion.ring-proxy :refer [wrap-proxy]]))

(def app
  (-> routes
      (wrap-proxy "/remote" "http://some.remote.server/remote")))

I am just not able to mix routing system from pedestal with this proxy solution, routes are different, seems like, maybe I will need to do it with a different approach

Disclaimer

  1. I know basic forwarding can be done by nginx, varnish, any other load balancer also. But my idea here is to fill up data from different servers making it simplified for the client
  2. I am a newbie with Clojure, as you may have noticed. And I ran out of options, because google about that is also complicated, sometimes useless
2

2 Answers

1
votes

Take a look at ring-request-proxy over here. From the docs:

(ns myapp.core
  (:require [ring-request-proxy.core :as proxy])

; Middleware format: Delegates request to handler when request can't be forwarded
(def app (-> not-found-handler
             (proxy/proxy-request {:identifier-fn :server-name
                                   :host-fn {"my-server" "http://my-internal-server"}})))

You should be set it as a middleware for all routes you want to proxy.

1
votes

You are creating a server that receives requests. Within your server, you can act as a client making a request to another server. You can then modify or aggregate the response you receive into the response you send to the original client.

See the clj-http library to make requests. The Clojure Toolbox lists many other options.

You may also be interested in this list of documentation resources.