<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jedrzej Serwa</title>
    <description>The latest articles on DEV Community by Jedrzej Serwa (@jedrzej_serwa).</description>
    <link>https://dev.to/jedrzej_serwa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F366506%2Fd3d65031-34de-49c3-be54-69a17977a0cb.jpg</url>
      <title>DEV Community: Jedrzej Serwa</title>
      <link>https://dev.to/jedrzej_serwa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jedrzej_serwa"/>
    <language>en</language>
    <item>
      <title>Towards better functional programming in Java with Vavr</title>
      <dc:creator>Jedrzej Serwa</dc:creator>
      <pubDate>Tue, 14 Jul 2020 11:34:16 +0000</pubDate>
      <link>https://dev.to/sonalake/towards-better-functional-programming-in-java-with-vavr-3dem</link>
      <guid>https://dev.to/sonalake/towards-better-functional-programming-in-java-with-vavr-3dem</guid>
      <description>&lt;p&gt;The functional paradigm in programming is over 62 years old, first presented in the Lisp language in 1958&lt;strong&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/strong&gt;. In the context of the Java language, it began to be widely spoken relatively recently from the perspective of these years because from version 1.8 or 6 years ago. So what is functional programming, can we program functionally in Java, can we reconcile this paradigm with OOP and how can Vavr library help us in all this?&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Starting from the beginning&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Before we get into the library itself, let’s briefly recall what functional programming is and what its assumptions are.&lt;/p&gt;

&lt;p&gt;The most important assumption of functional programming (FP) is the lack of the so-called side effects where there are many approaches, solutions or language features that bring us closer to this goal, and they include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immutability&lt;/li&gt;
&lt;li&gt;Lazy initialization&lt;/li&gt;
&lt;li&gt;Declarative programming language&lt;/li&gt;
&lt;li&gt;First-class functions&lt;/li&gt;
&lt;li&gt;Higher-order functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explanation what each of these mean is beyond the scope of this article, but for those interested in learning more, I’ve listed some good reading material &lt;strong&gt;&lt;a href="https://www.amazon.com/Functional-Programming-Java-functional-techniques/dp/1617292737" rel="noopener noreferrer"&gt;in the references&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As for the FP pillar, lack of side effects, it is a situation where a given function call does not cause a side effect in the system and retains the so-called referential transparency. This means, no less, no more that we should be able to replace the call of our function for given input parameters with its value. In other words, the function should be deterministic for the arguments given to it and should always return the same result without causing any change in the state of the system except the function scope.&lt;/p&gt;

&lt;p&gt;However this does not mean that we must completely abandon mutation operations, after all, it would be impossible to write a system based on business requirements without a database, cache or even http requests. The main thing is that actions that change some state should be extracted as far as possible, should be explicitly marked and ideally be performed at one point in the codebase, ideally in the main class or some dedicated module.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Functional Programming in Java?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;A common complaint against Java is its simple syntax and the lack of so-called syntactic sugar. The amount of code needed to write a given functionality, compared to the languages ​​that put the functional paradigm in the first place in their foundations&lt;sup&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/sup&gt;, is definitely larger. It is also true that these languages ​​have a higher entry threshold than Java, it is definitely easier to find a Java programmer than Clojure or Scala, which often has an impact on the main language in which the project will be written. In addition, Java is a huge percentage of the current market, many projects have been written or are in the process of writing in Java, and it would often be impossible to rewrite it to a new language with better language constructions to enjoy the benefits of using the FP paradigm. Simply put – sometimes we have no way of changing the language, and yet we would like to try working with a new paradigm. That is why, starting from Java version 8 and thanks to constructions implemented in the Vavr library&lt;sup&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/sup&gt;, this desire becomes feasible.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Vavr&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/vavr-io/vavr" rel="noopener noreferrer"&gt;Vavr&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="http://blog.vavr.io/javaslang-changes-name-to-vavr/" rel="noopener noreferrer"&gt;formerly Java Slang&lt;/a&gt;&lt;/strong&gt;, is a library made available under Apache 2.0 license, which provides us with tools that facilitate functional programming using Java. It is worth noting that Vavr does not contain any dependencies on external libraries, and is based solely on the API offered by Java.&lt;br&gt;
Thanks to lambda expressions&lt;strong&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/strong&gt;, functional interfaces&lt;strong&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/strong&gt;, var keyword&lt;strong&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/strong&gt; along with the use of components from the Vavr library, functional programming in Java becomes possible. The library itself consists of logically separated modules such as: gwt, match, test, jackson, gson, render, which have been implemented around the main core module and we will look at the selected elements of this module.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Scary Monads and how to embrace them&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;To better understand the concepts implemented in the Vavr library we will need another definition, the definition of Monad. This sinister-sounding name, which has its roots in Category Theory&lt;strong&gt;&lt;sup&gt;7&lt;/sup&gt;&lt;/strong&gt;, for the purposes of this article and in simplification, it can be broken down to simple to understand description – a Monad is a container for data, which allows us to operate declaratively on the data, using operations that are common to other Monads. There is a high probability that if you have not come across this term before, you have unwittingly used the Monads themselves, e.g. using the Monad introduced in JDK 1.8 – Optional&lt;strong&gt;&lt;sup&gt;8&lt;/sup&gt;&lt;/strong&gt; class. In the context of the description presented earlier, the Optional class is a container for data or lack thereof, and provides a set of API enabling declarative operations on this data, including among others operations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;map&lt;/strong&gt; – enabling a function to be performed on a given data&lt;br&gt;
&lt;strong&gt;flatmap&lt;/strong&gt; – enabling a function to be performed on data that is already a monad, in other words, flattening data&lt;br&gt;
&lt;strong&gt;filter&lt;/strong&gt; – filtering-out data that is not of interest for us&lt;br&gt;
&lt;strong&gt;stream&lt;sup&gt;9&lt;/sup&gt; &lt;/strong&gt;– converting from Optional Monad to Stream&lt;strong&gt;&lt;sup&gt;10&lt;/sup&gt;&lt;/strong&gt; Monad&lt;/p&gt;

&lt;p&gt;It is worth noting that, as already mentioned, the counterparts of these operations can also be found in other Monads, so when we have to work with the Monad supplied from a given library, we should be able to call functions on data, flatten data, filter data or convert to another Monad. These are, of course, only some of the operations available on Monads, and the available API strongly depends on the library provider or own creative invention of the author.&lt;/p&gt;

&lt;p&gt;Getting to the point, the Vavr library provides us with 5 basic monads, and these are:&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/control/Either.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Either&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Either represents the result in which we can return one of two values ​​- left or right. Used when the call to our method can have two waveforms, for example in a situation where the result of a given operation may fail – assigning it the value left, and in the case of success the value right.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/control/Option.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Option&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Monad used in a situation where we explicitly want to express the intention in which calling our method may return the result or lack of result. The main advantage as opposed to using the @Nullable annotation&lt;strong&gt;&lt;sup&gt;11&lt;/sup&gt;&lt;/strong&gt; or Javadoc describing a possible null result is that we described the situation using an object that is part of the method signature, and thus handling the situation where the result would be not present is required and checked by the compiler. The most important difference between Option and Optional is that the mapping function that returns null will throw an exception. In addition, this Monad provides a richer set of APIs, including the fold method, which allows us to perform a value mapping operation in the absence or existence of it. Examples of using the Option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l_78LYdj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6yfbfwcmvlr5kpr36a1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l_78LYdj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6yfbfwcmvlr5kpr36a1z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
In the presented implementation, the Book module provides the operation of finding information about a book based on ISBN using the findBookDetails method, which uses the Option Monad in its signature. The API user is obliged to handle the situation in which the data about the book is not available through the type contained in the signature, otherwise he will receive a compilation error.&lt;/p&gt;

&lt;p&gt;An example implementation of operations based on the Option API along with Either API looks following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0mUGOqUr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vaw8l64ew762l2yvd6lh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0mUGOqUr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vaw8l64ew762l2yvd6lh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;br&gt;
Lines 11-12 handle potential null values ​​from the ISBN object passed from the user of our API, to further on line 13 perform http request which will return the result wrapped in Either Monad. The whole is handled in line 14, where in the absence of values ​​from previous calls we return an empty result, and in the case of having data and invoking the request, we handle the result by mapping Either Monad to the Option Monad and calling the toDto method from the BookData object.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/control/Try.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Try&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Monad Try is similar to Option Monad, except that in contrast to missing values ​​it stores an exception that may have been thrown when calling the function. It is worth considering using this monad instead of using checked-exception or instead of throwing runtime exceptions and catching them with the help of framework mechanisms. Instead, we can treat our exceptions as standard Objects and handle errors on a regular basis or postpone their handling to a selected place. Examples of using Try Monad with the Either Monad:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s_613Gdf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/86bd6cvhkdjiv4ickf4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s_613Gdf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/86bd6cvhkdjiv4ickf4z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;br&gt;
Line 16 starts using Try by wrapping the getBookData method call from the ThirdPartyBookStoreLibrary class with the checked-exception signature.&lt;br&gt;
Thanks to the Vavr library, we can move on and give up the imperative style – the definition of the try catch block, to the declarative style, while handling an exception.&lt;br&gt;
On line 17, in the case of an exception thrown by the getBookData method, we log the situation, then on line 18 we convert to Either Monad by calling mapLeft in line 19, in which we translate the exception from the library into a comprehensible one inside our system.&lt;/p&gt;

&lt;p&gt;In addition, on line 19 the property of functional interfaces was used – use of a qualifier, so we can skip the name of the called method.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/Lazy.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Lazy&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Monad Lazy represents the value obtained not at the stage of initialization, but at the moment of referring to the value itself, in this context we refer to this as lazy initialization. Its operation can be compared to the known from Java 8 interface Supplier&amp;lt;T&amp;gt;, which returns a given value, with the difference that Lazy Monad has implemented the Memoization functionality and meets the aforementioned Referential transparency and which means that for the same set of arguments Monad calculates the result only once and stores it, returning calculated value for further invocations. An example of using Lazy Monad:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MuC1-yBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u6m092fkzvb897fy7jvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MuC1-yBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u6m092fkzvb897fy7jvb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;br&gt;
On line 5 we passed a dependency returning a list of available books, the operation of fetching available books was defined outside the Library class and is expensive because it requires invoking multiple HTTP requests. By using Lazy Monad, we postpone the invocation of expensive calls until the first invocation of the getAvailableBooks method, and this result is saved thanks to the previously mentioned memoization functionality.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/concurrent/Future.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Future&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Last of the Monads provided in the Vavr library – Future Monad represents value, the result of which will be made available somewhere in time. Operations on this monad are non-blocking. In its behaviour, it resembles the Future / CompletableFuture classes known from JDK. An example of using Future Monad:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--id9_baDw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/htrwey0g7l912mj2h74w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--id9_baDw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/htrwey0g7l912mj2h74w.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;br&gt;
Line 13 transforms the passed Set collection to Stream Monad&lt;br&gt;
Line 14 calls the findBookDetails method that wraps the call of the BookService method in the Future.of method call with the use of the injected Executor dependency&lt;br&gt;
Line 15 collects the result, transforms it to a list and then the result is passed to the sequence method from the Future class&lt;br&gt;
Last Lines 16 and 17 are responsible for collecting the result and creating a new AvailableBooksResult object and returning it in the Future monad. In this way we have achieved functionality in which we can, without blocking, download information about available books.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Briefly about collections and pattern matching&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;When it comes to the modification of state mentioned many times, you might have the irresistible impression that we have a problem in the Java world. This problem is the lack of the immutable collections. They all modify the internal state, and when it comes to &lt;em&gt;unmodifiable view&lt;/em&gt; methods from the Collections class, they only make our collection become read only, which in many cases may not be enough. In the case that we would like our collection to be fully immutable, Vavr library provides us with a solution in the form of newly defined “Functional Data Structures”, which includes Seq, Set and Map interfaces, all implementing a common interface – Iterable. The review of implementations available in the Vavr library goes far beyond this article, after all, we have available at the time of writing this article 15 implementations, but I strongly encourage you to read &lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/collection/package-summary.html" rel="noopener noreferrer"&gt;&lt;strong&gt;their documentation&lt;/strong&gt;&lt;/a&gt; about it.&lt;/p&gt;

&lt;p&gt;Another element provided in the Vavr library, and often a part of many functional languages&lt;strong&gt;&lt;sup&gt;12&lt;/sup&gt;&lt;/strong&gt; is Pattern Matching. Simply put, Pattern Matching allows you to declaratively define control based on a given condition so-called “Match predicate”. An example of using Pattern Matching from the Vavr library looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cp7lud4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1sizu7jwivpk9exevf79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cp7lud4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1sizu7jwivpk9exevf79.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;br&gt;
Line 2 Starts Pattern Matching consisting of predicates from lines 2 to 5 and when:&lt;br&gt;
Instance of Number object is BigDecimal type, it calls and returns the result of add method from BigDecimal&lt;br&gt;
Instance of Number object is of the BigInteger type, it calls and returns the result of the add method from the BigInteger class.&lt;br&gt;
Instance of the Number object is of the Integer type, sums the value and returns the result.&lt;br&gt;
Instance of the Number object is of the Float type, sums the value and returns the result.&lt;/p&gt;

&lt;p&gt;In addition to the &lt;a href="https://www.javadoc.io/static/io.vavr/vavr/0.10.1/io/vavr/Predicates.html" rel="noopener noreferrer"&gt;&lt;strong&gt;predicates&lt;/strong&gt; &lt;/a&gt;provided by the Vavr library, it is possible to define your own predicates and use them with the mechanism presented above by utilizing the &lt;a href="https://github.com/vavr-io/vavr-match" rel="noopener noreferrer"&gt;&lt;strong&gt;vavr-match&lt;/strong&gt;&lt;/a&gt; module.&lt;/p&gt;

&lt;p&gt;It is worth adding that Type Pattern Matching is slowly being implemented in Java. Switch expressions have been added the JDK 14&lt;strong&gt;&lt;sup&gt;13&lt;/sup&gt;&lt;/strong&gt; which makes it possible to use the switch statement also as expressions moreover in the JDK 14 version, authors introduced Pattern Matching for the &lt;strong&gt;instance of&lt;/strong&gt; instruction in the preview version, which has been further transferred to the JDK 15 version in the second preview version&lt;strong&gt;&lt;sup&gt;14&lt;/sup&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Despite being 62 years old, functional programming is doing very well and has not been forgotten but is a paradigm that is used on a daily basis. Languages ​​are more and more boldly adapting the functional paradigm, and programmers are noticing the benefits behind its use. The world of Java and OOP does not necessarily exclude the use of FP in existing or new projects, Java syntax has been improved over the years, which is why together with the use of libraries supporting functional programming and concepts implemented there, nowadays we can be tempted to introduce a new paradigm to our codebase. This will allow us to better abstract side effects, help us create code resistant to multithreading problems, code that is more predictable and thus better maintained over time. In the article I have included basic concepts regarding FP and briefly presented the use of selected elements of the Vavr library, which are only a brief introduction to the whole range of solutions and approaches that can be implemented. If you first came across the approaches described in the article I strongly encourage you to explore the subject further because this knowledge will definitely pay off in the future and can give a different point of view on certain problems.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;




&lt;p&gt;&lt;sup&gt;1 &lt;/sup&gt; &lt;small&gt;For those interested, I present a &lt;a href="https://www.cs.kent.ac.uk/people/staff/dat/tfp12/tfp12.pdf"&gt;paper &lt;/a&gt;describing the history of functional languages.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;2 &lt;/sup&gt; &lt;small&gt; In the world of JVM it will be, for example, &lt;a href="https://www.scala-lang.org" rel="noopener noreferrer"&gt;Scala&lt;/a&gt; or &lt;a href="https://clojure.org" rel="noopener noreferrer"&gt;Clojure&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;3 &lt;/sup&gt; &lt;small&gt;For Java, there are other libraries that facilitate functional programming, such as &lt;a href="https://github.com/aol/cyclops" rel="noopener noreferrer"&gt;Cyclops&lt;/a&gt; or &lt;a href="https://github.com/functionaljava/functionaljava" rel="noopener noreferrer"&gt;Functional Java&lt;/a&gt;, however the article focuses solely on the Vavr library.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;4 &lt;/sup&gt; &lt;small&gt;Added in JDK 1.8, &lt;a href="https://openjdk.java.net/jeps/126" rel="noopener noreferrer"&gt;JEP 126&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;5 &lt;/sup&gt; &lt;small&gt;Added in &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html" rel="noopener noreferrer"&gt;JDK 1.8&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;6 &lt;/sup&gt; &lt;small&gt;Added in JDK 11, &lt;a href="https://openjdk.java.net/jeps/286" rel="noopener noreferrer"&gt;JEP 286&lt;/a&gt;. The keyword var is not required for a functional approach, but it helps when reading heavily nested Monads for example.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;7 &lt;/sup&gt; &lt;small&gt;For those interested, I’m leaving a &lt;a href="https://github.com/hmemcpy/milewski-ctfp-pdf" rel="noopener noreferrer"&gt;link&lt;/a&gt; to a GitHub page with a source of the book “Category Theory for Programmers” written by Bartosz Milewski. The book in pdf version published under the GNU GPL v.3 license.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;8 &lt;/sup&gt; &lt;small&gt;In the context of Monad laws, the Optional class does not meet all the criteria needed to be considered a true Monad, while for the purposes of this article I have adopted a simplified comparison.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;9 &lt;/sup&gt; &lt;small&gt;&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Optional.html#stream()" rel="noopener noreferrer"&gt;The method&lt;/a&gt; added in JDK 9.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;10 &lt;/sup&gt; &lt;small&gt;Again, for the purposes of the article, I assumed that &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html" rel="noopener noreferrer"&gt;Stream&lt;/a&gt; class meets all Monad laws, in practice this class is not a full-fledged Monad, more can be read &lt;a href="https://patternsinfp.wordpress.com/2010/12/31/stream-monad/" rel="noopener noreferrer"&gt;in this article&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;11 &lt;/sup&gt; &lt;small&gt;Although current IDEs are able to catch such errors and there are &lt;a href="https://github.com/spotbugs/spotbugs" rel="noopener noreferrer"&gt;plugins&lt;/a&gt; that can analyze our annotations and at the build stage allowing to capture such places, while these are external tools and you should take care of their appropriate configuration.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;12 &lt;/sup&gt; &lt;small&gt;&lt;a href="https://docs.scala-lang.org/tour/pattern-matching.html" rel="noopener noreferrer"&gt;Scala Pattern Matching&lt;/a&gt;, &lt;a href="https://www.haskell.org/tutorial/patterns.html" rel="noopener noreferrer"&gt;Haskell Pattern Matching&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;13 &lt;/sup&gt; &lt;small&gt;&lt;a href="https://openjdk.java.net/jeps/361" rel="noopener noreferrer"&gt;JEP 361&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;sup&gt;14 &lt;/sup&gt; &lt;small&gt;&lt;a href="https://openjdk.java.net/jeps/305" rel="noopener noreferrer"&gt;JEP 305&lt;/a&gt; and &lt;a href="https://openjdk.java.net/jeps/375" rel="noopener noreferrer"&gt;JEP 375&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>vavr</category>
      <category>functional</category>
    </item>
    <item>
      <title>Instrumenting Software with Micrometer</title>
      <dc:creator>Jedrzej Serwa</dc:creator>
      <pubDate>Mon, 20 Apr 2020 08:34:21 +0000</pubDate>
      <link>https://dev.to/sonalake/instrumenting-software-with-micrometer-58h1</link>
      <guid>https://dev.to/sonalake/instrumenting-software-with-micrometer-58h1</guid>
      <description>&lt;p&gt;In recent years many of our clients have embraced microservices. This architectural pattern employs software services that are more fine-grained and heterogeneous than their monolithic predecessors and aim to bring productivity and performance gains by allowing teams to work in parallel and systems to scale horizontally and, in doing so, enable faster feature delivery.&lt;/p&gt;

&lt;p&gt;There’s no such thing as a free lunch though – microservices come at an operational cost. In the world of the monolith tracking down a production issue may well be as straightforward as tailing and grepping a single log file. In the world of microservices we may have 10-100s of distributed software services, running containers – how can engineers build a picture of what’s happening in the system? How can they carry out root cause analysis to identify performance bottlenecks?&lt;/p&gt;

&lt;p&gt;The answer is by instrumenting the services and exposing meaningful metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metrics
&lt;/h2&gt;

&lt;p&gt;In the abstract, a metric can be described as a unit of length – any numerical value characterising the software that can be easily compared with other numerical values within the same category. Examples include number of cache hits, time to invoke certain flow/method or, in the context of JVM-based solutions Garbage Collector pause time.&lt;/p&gt;

&lt;p&gt;There are many existing approaches to monitoring metrics, with differences in the way metrics are collected (push or pull), differences in architecture (client-side or server-side), as well as differences in metric transport and storage mechanism. Despite these differences, they all aim to solve the same problem and, as developers, we are challenged with making technology choices in a fast-changing monitoring space.&lt;/p&gt;

&lt;p&gt;To decouple the software we build from that of the systems we use to instrument it is to make use of an API. &lt;a href="https://micrometer.io/" rel="noopener noreferrer"&gt;Micrometer&lt;/a&gt; is a library that exposes such an API and one that we’ve had great success using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Micrometer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://micrometer.io/" rel="noopener noreferrer"&gt;Micrometer&lt;/a&gt; is a library that acts as a facade for monitoring systems. As it says on the website, “Think SLF4J, but for metrics”. It provides a unified API to most popular monitoring systems, allowing you to instrument your JVM-based application code without vendor lock-in.&lt;/p&gt;

&lt;p&gt;Here’s a selection of the systems Micrometer supports, there are a bunch more listed in the &lt;a href="https://micrometer.io/docs" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;System&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/Netflix/atlas" rel="noopener noreferrer"&gt;Atlas&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;In-memory dimensional time series database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.datadoghq.com/" rel="noopener noreferrer"&gt;Datadog&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Dimensional time-series SaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.elastic.io/" rel="noopener noreferrer"&gt;Elastic&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Search and analytics platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://ganglia.sourceforge.net/" rel="noopener noreferrer"&gt;Ganglia&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Hierarchical metrics system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://graphiteapp.org/" rel="noopener noreferrer"&gt;Graphite&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Hierarchical metrics system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.influxdata.com/products/influxdb-overview/influxdb-2-0/" rel="noopener noreferrer"&gt;InfluxDB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Time series database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://prometheus.io/" rel="noopener noreferrer"&gt;Prometheus&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;In-memory dimensional time series database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.wavefront.com/" rel="noopener noreferrer"&gt;Wavefront&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SaaS monitoring platform system&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In addition, Micrometer is now included as part of Spring Boot Actuator 2.x so it is already a part of the well known and widely used Spring stack. It provides four main methods of measurements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Timer – measure short-duration latencies and the frequency of such events&lt;/li&gt;
&lt;li&gt;  Distribution Summary – track the distribution of non-temporal event attribute&lt;/li&gt;
&lt;li&gt;  Counter – increment a value by a fixed amount&lt;/li&gt;
&lt;li&gt;  Gauge – monitor things with natural upper bounds (e.g. CPU load)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not going into the details of what these are used for exactly, since authors of Micrometer already did a great in the &lt;a href="http://micrometer.io/docs/concepts/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Within Spring Boot Actuator 2.x, as a part of Spring autoconfiguration, Micrometer gets integrated with applications by providing a set of Beans that can be further used for monitoring purposes. For example, if we want to monitor and measure the time taken for certain methods to end, it’s as simple as annotating the Spring managed Bean method. Alternatively we have the option of using the Micrometer &lt;a href="https://www.javadoc.io/doc/io.micrometer/micrometer-core/1.1.4" rel="noopener noreferrer"&gt;Timer API&lt;/a&gt;. In a simplified way implementation will look as follows:&lt;/p&gt;

&lt;p&gt;Annotation based&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nd"&gt;@Timed&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"add-book-flow"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BookDTO&lt;/span&gt; &lt;span class="nf"&gt;addBook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BookDTO&lt;/span&gt; &lt;span class="n"&gt;bookDTO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookDTO&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;     
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fromDTO&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookDTO&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;saveBook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;API based&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BookDTO&lt;/span&gt; &lt;span class="nf"&gt;addBook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BookDTO&lt;/span&gt; &lt;span class="n"&gt;bookDTO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;         &lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookDTO&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;         &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fromDTO&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookDTO&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;saveBook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;});&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conveniently, Micrometer also provides a &lt;a href="http://micrometer.io/docs/ref/spring/1.5" rel="noopener noreferrer"&gt;legacy bridge&lt;/a&gt; that can be used to integrate older Spring 1.5 applications with Micrometer library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visualisation
&lt;/h2&gt;

&lt;p&gt;Assuming that we successfully integrated with a metrics collecting system and exposed desired data the question arises as to what we can do with the data. The most popular answer to that question will likely be &lt;a href="https://grafana.com/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt;. Grafana is a powerful visualisation and alerting system for metrics. It ships with &lt;a href="https://grafana.com/dashboards" rel="noopener noreferrer"&gt;predefined dashboards&lt;/a&gt; and supports over thirty metric data sources. Users can also configure custom dashboards like the one shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sonalake.com/wp-content/uploads/2019/06/graphana-screenshot.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsonalake.com%2Fwp-content%2Fuploads%2F2019%2F06%2Fgraphana-screenshot-1024x391.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I strongly encourage you to visit &lt;a href="https://play.grafana.org" rel="noopener noreferrer"&gt;Grafana demo page&lt;/a&gt; – where you can experiment with a running instance and explore the full potential of Grafana dashboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;So far we have identified the building blocks of our metrics collecting system. Combining them together allows us to create a system to collect, store and track crucial data during the application runtime, as well as to alert us to undesirable system behaviour.&lt;/p&gt;

&lt;p&gt;A sample architecture for a microservice with monitoring is as follows:&lt;/p&gt;

&lt;p&gt;For the application we used Spring Boot 2.x along with Spring Boot Actuator and Micrometer. Within the application we have defined metrics that are crucial for our domain such as time to invoke important business methods as well as JVM and response time metrics.&lt;/p&gt;

&lt;p&gt;For monitoring we decided to use Prometheus so we included the &lt;a href="https://micrometer.io/docs/registry/prometheus" rel="noopener noreferrer"&gt;Micrometer Prometheus registry client&lt;/a&gt; dependency in the microservice itself so that Spring can easily detect our client and connect it to Prometheus.&lt;/p&gt;

&lt;p&gt;The last element is Grafana. It’s where we query and visualise data stored in Prometheus. We can fetch the metrics and create self-describing dashboards that can be used to easily monitor the application runtime. In addition we can define alerting that can message us via &lt;a href="https://grafana.com/docs/alerting/notifications/" rel="noopener noreferrer"&gt;notification providers&lt;/a&gt; when some of our metric values change in an undesirable way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sonalake.com/wp-content/uploads/2019/06/Distributed-Systems-and-Metrics.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsonalake.com%2Fwp-content%2Fuploads%2F2019%2F06%2FDistributed-Systems-and-Metrics.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sample application with Monitoring&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Microservices have made it more difficult to get a coherent view of  the state and health of applications.  The building blocks presented, in combination with well defined measurement criteria, help us build microservice-based software systems that can be readily monitored, diagnosed, and maintained. The combination of using Spring Boot and Micrometer gives us the flexibility to use a variety of monitoring systems without having to fundamentally change our architecture, while Grafana provides us with a powerful monitoring system.&lt;/p&gt;

&lt;p&gt;If you’d like to experiment with the code described, our colleague Jędrzej Serwa has put together a &lt;a href="https://github.com/jedrzejserwa/micrometer-spring-boot-sandbox/" rel="noopener noreferrer"&gt;sample repo on GitHub&lt;/a&gt;. Feedback welcome!&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>monitoring</category>
    </item>
  </channel>
</rss>
