How to do web directory reverse proxy on Go ?
Before we going further, lets discuss about what is reverse proxy. Reverse Proxy is a server process to retrieves resources on behalf of client request from one or more servers. These resources then returned to client, appearing as they originating from the proxy itself. The definition sounds smart heh, that is because I copied from this wikipedia link :)
Lets do some image to make it more crystal clear about this reverse proxy
So as you may see, user will send a request to reverse proxy server. Server then will re-send this request to respective application to obtain response/resources and send back this response to user appearing as it is originated from reverse proxy server
Why we have to do reverse proxy ?
Well, this reverse proxy can be used for many case. We will discuss that part on end of topic, but for now, I will give a simple use case why on earth we need this reverse proxy
Let say, we build 2 web applications, and since we have only one server to deploy those apps, we will need to run them on different port. Say first app, HelloApp on port 9123 and second app, WelcomeApp on port 9124. It will be quite messy for user to access these app. Don’t we want to offer easy access to our user ? this is how we can use reverse proxy.
Reverse Proxy on Go
Go has a built-in struct to manage reverse proxy. It is called ReverseProxy
on httputil
package, and the way to use this also very easy
appUrl, _ := url.Parse(target)
proxy := httputil.NewSingleHostProxyServer(appUrl)
proxy.ServerHTTP(writer, request)
Challenge
Like mentioned earlier, reverse proxy by default just re-submit the request from proxy server to application server.
In above case, say we access http://myreverseproxy/greet how do we know which greet method we will access, will it be helloApp/greet or welcomeApp/greet ?
This is the reason why common reverse proxy need subdomain, because if we have more than one applications to be reversed-proxied we need to have mechanism to recognised which app will be use. Hence, it maybe something like this
http://hello.myproxy.com/greet => http://myproxy.com:9123/greet
http://welcome.myproxy.com/greet => http://myproxy.com:9124/greet
But, this is not what I want. Because …, on above case, I need to do DNS record to be added, hello.myproxy.com
and welcome.myproxy.com
. I don’t really want to create so many ticket to be submitted and awake Production Support Team officer to do these stuff
I want to do reverse proxy on Web Directory instead of subdomain. This is what I want
http://myproxy.com/hello/greet => http://myproxy.com:9123/greet
http://myproxy.com/welcome/greet => http://myproxy.com:9124/greet
Kinda cool isn’t ?
Let’s do full use case of this Web Directory Reverse Proxy
I will start by creating 2 web app, helloApp and welcomeApp
This is first app, HelloApp
I initiate Server
and Mux
object separately rather than use default one, because I need to create 3 applications to demonstrate ReverseProxy capabilities and I am too lazy to create 3 different project, hence will combine them all in one project code
Now lets do, 2nd app, Welcome App
And finally proxy app
So, this proxy app called a magic function reverseProxy
, and yes, this function is the key. Here is the code
Combine them all in one main
Showwwwwtime…
Where the code is ?
All of the code are using standard Go package and can be found on https://github.com/ariefdarmawan/reverseproxysample
What we can do next with this reverse proxy
Well there are tons of possibility to extend usability of reverse proxy
- Enables reverse proxy to multiple server and do process load balance
- Simplifies micro-service process orchestration
- And others
I hope this post can help us understand what is reverse proxy and how to do reverse proxy (on web directory) using Go. If you have any questions, thoughts or suggestions then I’d love to hear from you!
Cheers, happy coding