= Vert.x Web Proxy

Vert.x Web Proxy provides a handler that handles the reverse proxy logic using
https://github.com/eclipse-vertx/vertx-http-proxy[Vert.x Http Proxy].

WARNING: This module has _Tech Preview_ status, this means the API can change between versions.

== Using Vert.x Web Proxy
To use Vert.x Web Proxy, add the following dependency to the _dependencies_ section of your build descriptor:

* Maven (in your `pom.xml`):

[source,xml,subs="+attributes"]
----
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-web-proxy</artifactId>
  <version>5.0.7</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy,subs="+attributes"]
----
dependencies {
  compile 'io.vertx:vertx-web-proxy:5.0.7'
}
----

== Basic Web Proxy

In order to accomplish local reverse proxy with Vert.x Web Proxy you need the following:

1. *Proxy Server* that handles front requests and forward them to the *origin server* using `ProxyHandler`.
2. *Origin Server* that handles requests from the *proxy server* and handles responses accordingly.

Now, you have the overall concept so let's dive in implementation and begin with *origin server* then
the *proxy server* using `ProxyHandler`:

== Origin Server (Backend)

You simply create the *origin server* and handle requests with Vert.x Web `Router`, the *origin server*
listens to port `7070`

[source,java]
----
HttpServer backendServer = vertx.createHttpServer();

Router backendRouter = Router.router(vertx);

backendRouter.route(HttpMethod.GET, "/foo").handler(rc -> {
  rc.response()
    .putHeader("content-type", "text/html")
    .end("<html><body><h1>I'm the target resource!</h1></body></html>");
});

backendServer.requestHandler(backendRouter).listen(7070);
----

== Proxy Server

Create the *proxy server* that listens to port `8080`

[source,java]
----
HttpServer proxyServer = vertx.createHttpServer();

Router proxyRouter = Router.router(vertx);

proxyServer.requestHandler(proxyRouter);

proxyServer.listen(8080);
----

== Using `ProxyHandler`

The last interesting part is to route *proxy server* requests to the *origin server*, so you need to create `HttpProxy`
with specified target and `ProxyHandler`.

[source,java]
----
HttpClient proxyClient = vertx.createHttpClient();

HttpProxy httpProxy = HttpProxy.reverseProxy(proxyClient);
httpProxy.origin(7070, "localhost");

proxyRouter
  .route(HttpMethod.GET, "/foo").handler(ProxyHandler.create(httpProxy));
----

Or you can specify the target in `ProxyHandler` instead.

[source,java]
----
HttpClient proxyClient = vertx.createHttpClient();

HttpProxy httpProxy = HttpProxy.reverseProxy(proxyClient);

proxyRouter
  .route(HttpMethod.GET, "/foo")
  .handler(ProxyHandler.create(httpProxy, 7070, "localhost"));
----

Finally, the *proxy server* requests will be routed as a reverse proxy to the *origin server* conveniently.

[WARNING]
====
The `link:../../apidocs/io/vertx/ext/web/handler/BodyHandler.html[BodyHandler]` is not compatible with the `link:../../apidocs/io/vertx/ext/web/proxy/handler/ProxyHandler.html[ProxyHandler]`.
It shouldn't be installed on the same route or a previous route.

[source,java]
----
router.post().handler(BodyHandler.create()); // Don't do this
router.route("/product").handler(ProxyHandler.create(productServiceProxy));

router.route("/product")
  .handler(BodyHandler.create()) // Don't do this
  .handler(ProxyHandler.create(productServiceProxy));
----
====

== Using `ProxyHandler` for multiple targets

In order to route *proxy server* requests to multiple *origin servers* you simply create `HttpProxy` for
each one and specify the target independently.

[source,java]
----
HttpClient proxyClient = vertx.createHttpClient();

HttpProxy httpProxy1 = HttpProxy.reverseProxy(proxyClient);
httpProxy1.origin(7070, "localhost");

HttpProxy httpProxy2 = HttpProxy.reverseProxy(proxyClient);
httpProxy2.origin(6060, "localhost");

proxyRouter
  .route(HttpMethod.GET, "/foo").handler(ProxyHandler.create(httpProxy1));

proxyRouter
  .route(HttpMethod.GET, "/bar").handler(ProxyHandler.create(httpProxy2));
----