Posts

An introduction to Spark, your next REST Framework for Java

This is a post I wrote for the Java Advent. It was initially published here.

Today we’re going to look into a refreshing, simple, nice and pragmatic framework for writing REST applications in Java. It will be so simple, it won’t even seem like Java at all.

We’re going to look into the Spark web framework. No, it’s not related to Apache Spark. Yes, it’s unfortunate that they share the same name.

I think the best way to understand this framework is to build a simple application, so we’ll build a simple service to perform mathematical operations.

We could use it like this:

Screenshot from 2015-11-26 14-57-18

Note that the service is running on localhost at port 4567 and the resource requested is “/10/add/8”.

Set up the Project Using Gradle (what’s Gradle?)

Now we can run:

  • ./gradlew idea to generate an IntelliJ IDEA project
  • ./gradlew test to run tests
  • ./gradlew assemble to build the project
  • ./gradlew launch to start our service

Great. Now, Let’s Meet Spark

Do you think we can write a fully functional web service that performs basic mathematical operation in less than 25 lines of Java code? No way? Well, think again:

In our main method we just say that when we get a request which contains three parts (separated by slashes) we should use the Calculator route, which is our only route. A route in Spark is the unit which takes a request, processes it, and produces a response.

Our calculator is where the magic happens. It looks in the request for the paramters “left”, “operatorName” and “right”. Left and right are parsed as long values, while the operatorName is used to find the operation. For each operation we have a Function (Function2<Long, Long>) which we then apply to our values (left and right). Cool, eh?

Function2 is an interface which comes from the Javaslang project.

You can now start the service (./gradlew launch, remember?) and play around.

The last time I checked Java was more verbose, redundant, slow… well, it is healing now.

Ok, but what about tests?

So Java can actually be quite concise, and as a Software Engineer I celebrate that for a minute or two, but shortly after I start to feel uneasy… this stuff has no tests! Worse than that, it doesn’t look testable at all. The logic is in our calculator class, but it takes a Request and produces a Response. I don’t want to instantiate a Request just to check if my Calculator works as intended. Let’s refactor a little:

We just separate the plumbing (taking the values out of the request) from the logic and put it in its own method: calculate. Now we can test calculate.

I feel better now: our tests prove that this stuff works. Sure, it will throw an exception if we try to divide by zero, but that’s how it is.

What does that mean for the user, though?

Screenshot from 2015-11-26 15-14-08

It means this: a 500. And what happens if the user tries to use an operation which does not exist?

Screenshot from 2015-11-26 15-14-30

What if the values are not proper numbers?

Screenshot from 2015-11-26 15-16-01

Ok, this doesn’t seem very professional. Let’s fix it.

Error handling, functional style

To fix two of the cases we just have to use one feature of Spark: we can match specific exceptions to specific routes. Our routes will produce a meaningful HTTP status code and a proper message.

We have still to handle the case of a non-existent operation, and this is something we are going to do in ReallyTestableCalculator.

To do so we’ll use a typical function pattern: we’ll return an EitherAn Either is a collection which can have either a left or a right value. The left typically represents some sort of information about an error, like an error code or an error message. If nothing goes wrong the Either will contain a right value, which could be all sort of stuff. In our case we will return an Error (a class we defined) if the operation cannot be executed, otherwise we will return the result of the operation in a Long. So we will return an Either<Error, Long>.

Let’s test this:

The result

We got a service that can be easily tested. It performs mathematical operations. It supports the four basic operations, but it could be easily extended to support more. Errors are handled and the appropriate HTTP codes are used: 400 for bad inputs and 404 for unknown operations or values.

Conclusions

When I first saw Java 8 I was happy about the new features, but not very excited. However, after a few months I am seeing new frameworks come up which are based on these new features and have the potential to really change how we program in Java. Stuff like Spark and Javaslang is making the difference. I think that now Java can remain simple and solid while becoming much more agile and productive.

You can find many more tutorials either on the Spark tutorials website.

Functional programming for Java: getting started with Javaslang

Java is an old language and there are many new kids in the block who are challenging it on its own terrain (the JVM). However Java 8 arrived and brought a couple of interesting features. Those interesting features enabled the possibility of writing new amazing frameworks like the Spark web framework or Javaslang.

In this post we take a look at Javaslang which brings functional programming to Java.

Functional programming: what is that good for?

It seems that all the cool developers want to do some functional programming nowadays. As they wanted to use Object-oriented programming before. I personally think functional programming is great to tackle a certain set of problems, while other paradigms are better in other cases.

Functional programming is great when:

  • you can pair it with immutability: a pure function has not side-effect and it is easier to reason about. Pure functions means immutability, which drastically simplifies testing and debugging. However not all solutions are nicely represent with immutability. Sometimes you just have a huge piece of data that it is shared between several users and you want to change it in place. Mutability is the way to go in that case.
  • you have code which depends on inputs, not on state: if something depends on state instead than on input it sounds more like a method that a function to me. Functional code ideally should make very explicit which information is using (so it should use just parameters). That also means more generic and reusable functions.
  • you have independent logic, which is not highly coupled: functional code is great when it is organized in small, generic and reusable functions
  • you have streams of data that you want to transform: this is in my opinion the easiest place where you can see the values of functional programming. Indeed streams received a lot of attention in Java 8.

Discuss the library

As you can read on javaslang.com:

Java 8 introduced λ which dramatically increases the expressiveness of our programs, but “Clearly, the JDK APIs won’t help you to write concise functional logic (…)”jOOQ™ blog

Javaslang™ is the missing part and the best solution to write comprehensive functional Java 8+ programs.

This is exactly as I see Javaslang: Java 8 gave us the enabling features to build more concise and composable code. But it did not do the last step. It opened a space and Javaslang arrived to fill it.

Javaslang brings to the table many features:

  • currying: currying can be use to implement the partial application of functions
  • pattern matching: let’s think of it as the dynamic dispatching for functional programming
  • failure handling: because exceptions are bad for function compositions
  • Either: this is another structure which is very common in functional programming. The typical example is a function which returns a value when things go well and an error message when things go not so well
  • tuples: tuples are a nice lightweight alternatives to objects and perfect to return multiple values. Just do not be lazy and use classes when it makes sense to do so
  • memoization: this is caching for functions

For developers with experience in functional programming this will all sound very well known. For the rest of us let’s take a look at how we can use this stuff in practice.

Ok, but in practice how can we use this stuff?

Obviously showing an example for each of the feature of Javaslang is far beyond the scope of this post. Let’s just see how we could use some of them and in particular let’s focus on the bread and butter of functional programming: functions manipulation.

Given that I am obsessed with manipulation of Java code we are going to see how we can use Javaslang to examine the Abstract Syntax Tree (AST) of some Java code. The AST can be easily obtained using the beloved JavaParser.

If you are using gradle your build.gradle file could look like this:

We are going to implement very simple queries. Queries we can be answered just looking at the AST without solving symbols. If you want to play with Java ASTs and solve symbols you may want to take a look at this project of mine: java-symbol-solver.

For example:

  • find classes with a method with a given name
  • find classes with a method with a given number of parameters
  • find classes with a given name
  • combining the previos queries

Let’s start with a function which given a CompilationUnit and a method name returns a List of TypeDeclarations defining a method with that name. For people who never used JavaParser: a CompilationUnit represents an entire Java file, possibly containing several TypeDeclarations. A TypeDeclaration can be a class, an interface, an enum or an annotation declaration.

getTypesWithThisMethod is very simple: we take all the types in the CompilationUnit (cu.getTypes()) and we filter them, selecting only the types which have a method with that name. The real work is done in hasMethodNamed.

In hasMethodNamed we start by creating a javaslang.collection.List from our java.util.List (List.ofAll(typeDeclaration.getMembers())Then we consider that we are only interested in the MethodDeclarations: we are not interested in field declarations or other stuff contained in the type declaration. So we map each method declaration to either Option.of(true) if the name of the method matches the desidered methodName, otherwise we map it toOption.of(false). Everything that is not a MethodDeclaration is mapped to Option.none(). Note that we do that in two steps: first the method is mapped to an Option<String> then the Option<String> is mapped to an Option<Boolean>.

So for example, if we are looking for a method name “foo” in a class which has three fields, followed by methods named “bar”, “foo” and “baz” we will get a list of:

Option.none(), Option.none(), Option.none(), Option.of(false)Option.of(true)Option.of(false)

The next step is to map both Option.none() and Option.of(false) to false and Option.of(true) to true. Note that we could have than that immediately instead of having two maps operation concatenated. However I prefer to do things in steps. Once we get a list of true and false we need to derive one single value out of it, which should be true if the list contains at least one true, and false otherwise. Obtaining a single value from a list is called a reduce operation. There are different variants of this kind of operation: I will let you look into the details 🙂

We could rewrite the latest method like this:

Why we would like to do so? It seems (and it is) much more complicate but it shows us how we can manipulate functions and this is an intermediate step to obtain code which is more flexible and powerful. So let’s try to understand what we are doing.

First a quick note: the class Function1 indicates a function taking one parameter. The first generic parameter is the type of the parameter accepted by the function, while the second one is the type of the value returned by the function. Function2 takes instead 2 parameters. You can understand how this goes on 🙂

We:

  • reverse the order in which parameters can be passed to a function
  • we create a partially applied function: this is a function in which the first parameter is “fixed”

So we create our originalFunctionReversedAndCurriedAndAppliedToMethodName just manipulating the original function hasMethodNamed. The original function took 2 parameters: a TypeDeclaration  and the name of the method. Our elaborated function takes just a TypeDeclaration. It still returns a boolean.

We then simply transform our function in a predicate with this tiny function which we could reuse over and over:

Now, this is how we can make it more generic:

Ok, now we could generalize also hasMethodWithName:

After some refactoring we get this code:

Now let’s see how it can be used:

The source file we used in this tests is this one:

This is of course a very, very, very limited introduction to the potentialities of Javaslang. What I thinki is important to get for someone new to functional programming is the tendence to write very small functions which can be composed and manipulates to obtain very flexible and powerful code. Functional programming can seem obscure when we start using it but if you look at the tests we wrote I think they are rather clear and descriptive.

Functional Programming: is all the hype justified?

I think there is a lot of interest in functional programming but if that becomes hype it could lead to poor design decisiong. Think about the time when OOP was the new rising star: the Java designers went all the way down forcing programmers to put every piece of code in a class and now we have utility classes with a bunch of static methods. In other words we took functions and asked them to pretend to be a class to gain our OOP medal. Does it make sense? I do not think so. Perhaps it helped to be a bit extremist to strongly encourage people to learn OOP principles. That is why if you want to learn functional programming you may want to use functional-only languages like Haskell: because they really, really, really push you into functional programming. So that you can learn the principles and use them when it does make sense to do so.

Conclusions

I think functional programming is a powerful tool and it can lead to very expressive code. It is not the right tool for every kind of problem, of course. It is unfortunate that Java 8 comes without proper support for functional programming patterns in the standard library. However some of the enabling features have been introduced in the language and Javaslang is making possible to write great functional code right now. I think more libraries will come later, and perhaps they will help keeping Java alive and healthy for a little longer.

 

Note: thanks to Lorenzo Bettini for pointing out a couple of mistakes