Sunteți pe pagina 1din 5

GET STARTED GUIDES EXTENSIONS COMMUNITY BLOG

Quarkus and Web UI


Development
By Kabir Khan | June 05, 2019

In this blog post we will take advantage of the respective development


modes of both Quarkus and Angular CLI and see how we can develop a zero
turnaround web application backed by a RESTful API on Quarkus. While I am
using Angular, the concepts are the same for other modern web
application frameworks.

The source code for this blog can be found at https://github.com/kabir/blog-


quarkus-ui-development. It contains a README which explains in detail how
the application was set up and how we implemented each step, addressing
problems we uncovered along our way.

You need to have Node, Yarn and Angular CLI installed on your system, and
familiarity with Angular and Quarkus is assumed.

Clone the project, and go into its folder. First run:

$mvn -Dui.deps compile

This downloads all the dependencies needed to build our web application.
Then run:

$mvn package -Dui.dev -Dui.proxy quarkus:dev

The -Dui system property enables a Maven pro le to build the web
application. The output directory for the web application
webapp/dist/webapp gets bundled into the Quarkus application. We will
talk about -Dui.proxy later on.

Go to http://localhost:8080 in your browser and take a look at our sample


application. It contains a few di erent pages. Go to the one called Rest
which makes a REST call. We can change the return value of the
SampleServlet.hello() method. If you refresh the page you will see the
changes made re ected automatically!

With what we have so far, if we were to make changes to the user interface in
our web application, we would need to stop Quarkus and run the above
command to build the web application again and restart quarkus. This is not
what we want, so we take advantage of Angular’s proxy. React and Vue have
something similar.

In another terminal window go into the webapp/ folder of the cloned project,
and run:
$yarn proxy
$y p y

This will start the Angular development server in proxy mode on port 4200.
Go to http://localhost:4200 and you will see the same application as you saw
earlier on port 8080, but served by the Angular development server while
accessing the REST endpoints from the running Quarkus application. If you
make any changes to any of the Angular components set up in
app.component.ts you will see your changes re ected.

This is great!!! We can now be super-productive and make changes in both


our front-end and our back-end, and see the changes immediately without
needing to rebuild, repackage and restart our application!

Adjustments Summary
The example project has already been set up with the needed adjustments
to work properly both as a bundled application and in development mode.
These are the main tweaks:

1. Handle the Angular routes in the UI rather than on the back-end. This is
important for the bundled version (running on port 8080).

2. Enable the Angular proxy to allow for the UI to call REST endpoints
served by Quarkus.
a. Signal to the back-end that the front-end is running in a proxy, i.e.
not served by us. This is important if the back-end needs to
redirect to a page in the front-end.

We will focus on the changes needed to make this work well, and not go into
the details of how the application is set up.

Handle Angular Routes

Add a lter, AngularRouteFilter. The essence of its doFilter() method is:

chain.doFilter(request, response);

if (response.getStatus() == 404) {
String path = request.getRequestURI().substring(
request.getContextPath().length()).replaceAll(
if (!FILE_NAME_PATTERN.matcher(path).matches()) {
// We could not find the resource, i.e. it is not
// endpoint or a servlet), and does not look like
request.getRequestDispatcher("/").forward(request,
}
}

This lter is only needed when running the application bundled in Quarkus
(port 8080). It is not needed when connecting to the application running in
Angular (port 4200). It’s purpose is to allow us to bookmark pages in the
application. All the server knows about are things like:

the REST endpoints


deployed servlets
the resources in the META-INF/resources/ folder of the application

The META-INF/resources/ in our case contains the application’s


index.html and the transpiled resources.

Without this lter if you go to one of the Angular routes directly (e g if you try
Without this lter, if you go to one of the Angular routes directly (e.g if you try
to refresh when on http://localhost:8080/rest which is the Rest page we saw
earlier) Quarkus will think it is a le, a REST endpoint or a servlet. Since
Quarkus has no knowledge of anything called /rest you end up with a 404
(Not Found) status. The lter checks the status code of the request after
calling chain.doFilter(). If the status is 404 and does not seem to be a
le, we forward this request to /, which in turn serves up the index.html
le. By doing a forward the path and parameters of the request are
preserved. Angular then gures out that /rest is one of its known routes
and displays the appropriate page of the application. Once the web
application is loaded in the browser, Angular takes over and handles all the
internal links to other routes in the web application (as an example, if you are
on http://localhost:8080 and click on the link taking you to
http://localhost:8080/other there is no round-trip to the server).

There are other ways you can handle this too, e.g. by checking the path
against a set of hard-coded known paths that are to be handled by the back-
end, but for my purposes the above has worked very well. The key is to
invoke:

request.getRequestDispatcher("/").forward(request, response);

if it is something that should be handled by Angular.

Set up the Angular proxy

The proxy is con gured in proxy.conf.json. All REST calls to anything under
/api will be passed to the back-end running on port 8080. To run the
Angular development server with this con guration, we have added a proxy
con guration to the scripts section of package.json.

In our case, we have a servlet which needs to redirect back to the front-end
(something I found I needed to implement OAuth in my main project). That
has a check for the -Dui.proxy system property we saw earlier when
handling the /callback path in SampleServlet. If this property is set, we
prepend https://localhost:4200 (the address of the Angular proxy) to
the redirect URL if we nd the proxy is running on port 4200.

Finally, DefaultComponent in app.component.ts has a direct link to our


servlet running in the back-end. It has a check to see if the web application is
running in the proxy (i.e. its port is 4200), and if this is the case it adjusts the
url from /servlet/make-external-call to point to the Quarkus back-end
running on port 8080.

Last words
We have seen how with a minimum amount of con guration we can have
both the back-end and front-end of our application running in Quarkus’s and
Angular’s respective development modes. During development this removes
the need to rebuild the application when we change something. You can just
code away, and see the changes when you refresh your browser. This is done
by starting Quarkus with:

$mvn package -Dui.dev -Dui.proxy quarkus:dev

and starting the Angular application (from the webapp/ folder) with

$yarn proxy

Packaging for development


Packaging for development

If you want to do a rebuild now and again to package the application and run
it all in Quarkus run

$mvn package -Dui.dev quarkus:dev

By not passing in -Dui.proxy we disable the checks for whether the front-end
runs in a proxy. -Dui.dev builds the web application so it is part of the
Quarkus application.

Packaging for production

To package the application for production, use

$mvn package -Dui

-Dui builds the web application just like -Dui.dev, but it does more
optimisations for production. Those optimisations take some time.

Packaging for cloud native

Finally to build a native image, make sure you have set up GraalVM as
outlined here. Then build the application to generate the native executable.

$mvn package -Dui -Pnative

Running this we see the super-fast startup time Quarkus gives us in native
mode:

$./target/blog-quarkus-ui-development-0.1.0-runner
2019-06-06 10:57:02,254 INFO [io.quarkus] (main) Quarkus 0.15.0 started in 0.005s. Listening
2019-06-06 10:57:02,464 INFO [io.quarkus] (main) Installed features: [cdi, resteasy, resteasy

Quarkus is open. Navigation Contribute Get Help Quarkus is proudly made of


Quarkus and its Home Follow us Chatroom Hibernate
extensions are
Guides GitHub Google Groups Netty
available under the
Apache Software Get FAQ RESTEasy

License 2.0 or Started


Eclipse MicroPro le
compatible license.
Eclipse Vert.x

Apache Camel
This website was
built with Jekyll is
hosted on Github
Pages and is
completely open
source. If you want
to make it better,
fork the website
and show us what
you’ve got.

 CC by 3.0 | Red Hat Privacy Policy a Red Hat sponsored project

S-ar putea să vă placă și