sobota, 10 lutego 2018

Resource-oriented client architecture (ROCA)

What is ROCA ?


Recently I've encountered ROCA - resource-oriented client architecture, which is a lightweight set of recommendations / guidelines for a good web application architecture. It's available here: http://roca-style.org.

Downsides


After reading thru I can say that authors tended to stay conservative in their approach, especially regarding front-end. It's usually a good thing, as typical development process usually relaxes the rules set at the beginning (due to lack of time, business pressure etc.) so being too constrained at the beginning usually means appropriate constraints at the end ;-)
In ROCA case however, I have following comments:
"JavaScript is used unobtrusively and the application remains usable (albeit with a decrease in usability and convenience) if JavaScript is disabled."
Well, this one is rarely possible nowadays. Most rich web applications use a lot of JavaScript not only to make UX better, but also for core processing (transformation of data from REST, validation etc.). For applications (SPAs) based on JS frameworks (Angular, vue, react, ...) it's totally impossible. It's also not practical to provide a separate, HTML-only version for clients without JavaScript, taking into account decent support of JS by all modern browsers and OSes.

"The same functionality must not be implemented redundantly on both the client (JavaScript) and the server. Thus, due to the application logic requirement, application logic must not reside on the client-side."
This one is also hard to apply in modern web apps. I believe that it's good to minimise redundancy, especially regarding "heavy" business logic. But parts like data validation are often implemented in both places. Backend needs to do it in order to maintain data consistency. Frontend needs to do it in order to provide better user experience (interactive feedback).

"All JavaScript code and CSS code must be static, and must not be dynamically generated by the server in a form specific to the resource requested"
Out of my personal experience, there are some solid cases when JavaScript has to be generated online. One example is a distributed system in which parts (let's call them "microservices" ;-) ) can be turned on/off, virtually enabling/disabling parts of the frontend. Then, such change has to be reflected in JavaScript returned. However these are very specific and therefore limited cases.

Upsides


Rest of the rules I'm OK with. Some sound very basic in modern world (like "server adheres to REST principles" or "client uses RESTful HTTP queries"). Others, however, are more tricky, easy to miss during web app develpoment and should be reminded, like:
"A user must be able to link to a specific piece of information, e.g. by copying the address from the browser's address bar and pasting it into an e-mail, creating a bookmark, or using any of the fancier ways to share URIs."
or
"The browser controls like the back, forward and refresh buttons must work as expected. I.e. the back button should take the users where they expect to be taken to (the last meaningful resource they worked with). A browser refresh should not cause a re-rendering of the login or home page instead of the page the user was looking at, or a (to the user) unexpected question about wanting to submit the same data again (when the user doesn't recall submitting any data, indicating a mis-use of the POST verb)."

Summary


To sum up, I think that ROCA is a good idea worth reading (especially during project's start). However as any given kind of recommendations, should be applied carefully, with respect to the domain and problem.

piątek, 26 stycznia 2018

Type safe Java DTOs in Angular with Maven

Introduction

New Angular, as opposed to "old" Angular.JS, uses TypeScript (https://www.typescriptlang.org/). Among others, TS usage allows for a static type checking, a language feature that can prove very useful on the backend / frontend border (namely - REST API level). With a TypeScript interface / class definition for each and every DTO (Java class sent thru API), errors in usage are easily discovered at the compilation stage, well before the code reaches testing.

But how to get TS definitions for all DTOs easily, automatically, without boring process of converting Java to TypeScript? Well, if your build uses good old Maven, your're lucky ;-) There is a plugin that properly configured will output .d.ts file for all of the DTOs. Let me show you how to configure the plugin for a simple Angular application.

Maven configuration

First, we need to configure the plugin in the pom.xml of your application. Fragment may look as follows:
It simply binds the plugin's generate goal to process-classes phase, configuring by the way that:
  • Java enumerations will be mapped to TypeScript string enum (requires TypeScript 2.4)
  • plugin will consider all classes conforming to com.example.**.**Dto
  • namespace in which all of the types will be stored is yournamespace
  • output will be stored in the src/main/webapp/app/dto-definitions.d.ts file (standard Maven web app layout)
  • the output will be global (in a declared namespace, not separate module)

Angular usage

OK, so we have a .ts.d file generated, how to use it now in the Angular application? First, you need to make TypeScript compiler aware of the typings. This differs between frontend builds. In my example, I use grunt with grunt-ts plugin for TypeScript compilation. Therefore, example looks as follows:
Now, once TS compiler is aware of the namespace and contained types (interfaces actually as per configuration), rest is simple. any type can be imported in a following way:
import MyClassDto = yournamespace.MyClassDto;

Tips and tricks

Duplicated and nested Java classes

The example is really minimal and simplified. There are a lot of corner cases that will require additional configuration (or black magic ;-) ) to resolve. My favourite ones are nested classes and duplicated class names.
The first one is problematic as "$" can't be part of the class name in the TypeScript - so Outer$Nester as per Java standard won't work. What can we do? Well, my solution is to rename the class to take simple form of OuterNested.
The second one is problematic as we store all classes in one module - so duplicates from different Java packages will land in the same module - and that's a name clash. What to do then? Well, I simply join duplicated class name with last part of the package declaration. Maybe it doesn't look perfect, but in limited number of duplicated cases is just works ;-)
But how to enable such conversions for the plugin? Let's just configure a customTypeNamingFunction that transforms the name as it comes from Java into TypeScript name. Simple example may look as follows:

Fully-qualified TypeScript names

What about configuring the plugin to output Java types as fully qualified TypeScript types? After all, namespace is similar to package in this regard. Well, don't do that. Why? Because of the type ordering. Plugin and compiler will understand classes in a single namespace - that is order classes referencing other classes. But this does not work for separate packages. If you have (and you certainly do) a Java class that references another Java class in other package, the plugin may output namespace with referenced classes later than the namespace with class referring. As a result, TypeScript compilation will fail as the required type will not be found. Sorry, TS ain't Java ;-) 

czwartek, 18 stycznia 2018

Notes on password handling in Java

The title is probably a bit misleading. No there will be nothing about how to securely hash and store a password, salt etc. Instead, I wanted to emphasize one little thing that is often missed when implementing password handling, that is which data structure should be used for this purpose.

The obvious choice is of course String. This happens however not to be the best one, as char array will serve the same purpose better. Why? Because of the security. 
Java String is immutable. Therefore once created, can't be modified (cleared). There is of course a way to bypass immutability using reflection, but it should never be recommended as String is JVM class and internal (private) implementation can be changed anytime. Even once the reference is abandoned, there is no way to make GC run or actually erase the data (underlying char[]). Well-known Runtime::gc() method is only a request, not a command to JVM. What is more - it's possible that a garbage collection will mark location as empty, without actually erasing the data. On the other hand, char[] can be simply zeroed.

Above is especially important nowadays, once meltdown and spectre attacks have been uncovered. If there is a chance that a malicious process can read the data kept on heap, real programmers are enforced to minimise the risk and shrink window of opportunity for such attacks.

So, how this should be done? Well, I'd personally implement a small class (eg Password) that keeps the data as char[] and provides a dispose method, zeroing internal structure once it's no longer needed. Of course the class should be used right from the API level, so that there is no intermediate String instance keeping the password before it's copied into Password. The only issue is that caller of this class needs to remember to call the method and dispose the password data explicitely. Unfortunately as we all know, Object::finalize() method can't be relied upon, as there is completely no guarantee that such method will be ever called  (and even if it does - only by GC!). 

wtorek, 16 stycznia 2018

Hibernate performance tips & tricks

Thanks to twitter I've recently found a very nice and comprehensive list of Hibernate performance tips & tricks, written by Vlad Mihalcea. It's available on his blog here: https://vladmihalcea.com/14-high-performance-java-persistence-tips/
Really recommend it! Even with years of experience with Hibernate as a persistence provider I managed to find something new :-)