2

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 Answers2

1

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.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
  • I see, I was thinking about using clj in that case also, thanks for pointing out But imagine for a group of resources (a lot of them), e. g. /customer/* all requests can be directly forwarded to the external server, without aggregation. Would it not be easier to have a proxy-like solution to forward all requests if they are in some wildcard url? Then for other ones defined in the routes, I can for sure, as you told, use clj-http – Mateus Carvalho Apr 21 '20 at 15:18
1

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.

jarmond
  • 1,372
  • 1
  • 11
  • 19