<?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: Philipp Gysel</title>
    <description>The latest articles on DEV Community by Philipp Gysel (@pmgysel).</description>
    <link>https://dev.to/pmgysel</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%2F351732%2Fcead063a-45c2-454e-962a-725494f41e02.PNG</url>
      <title>DEV Community: Philipp Gysel</title>
      <link>https://dev.to/pmgysel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pmgysel"/>
    <language>en</language>
    <item>
      <title>Learn Aspect Oriented Programming by Example</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 01 Feb 2021 12:04:33 +0000</pubDate>
      <link>https://dev.to/pmgysel/learn-aspect-oriented-programming-by-example-m8o</link>
      <guid>https://dev.to/pmgysel/learn-aspect-oriented-programming-by-example-m8o</guid>
      <description>&lt;p&gt;This post offers a great way for you to learn &lt;a href="https://en.wikipedia.org/wiki/Aspect-oriented_programming" rel="noopener noreferrer"&gt;Aspect Oriented Programming&lt;/a&gt; by studying &lt;strong&gt;concrete examples&lt;/strong&gt;. In particular, I will showcase &lt;strong&gt;SpringBoot AOP&lt;/strong&gt; by implementing &lt;strong&gt;4 Aspects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What is an Aspect?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Cacheable&lt;/code&gt;&lt;/strong&gt;: a standard Spring Advice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log REST calls&lt;/strong&gt; (with a custom Aspect)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance monitoring&lt;/strong&gt; (with AOP)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry mechanism&lt;/strong&gt; (with AOP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re the person who wants to skip lengthy descriptions and just look at concrete code, I’ve got you covered:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pmgysel" rel="noopener noreferrer"&gt;
        pmgysel
      &lt;/a&gt; / &lt;a href="https://github.com/pmgysel/aop-examples" rel="noopener noreferrer"&gt;
        aop-examples
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Some examples of Aspect Oriented Programming (AOP) with SpringBoot
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; What is an Aspect?
&lt;/h1&gt;

&lt;p&gt;So there are some great resources out there for an overview of Spring AOP, including this &lt;a href="https://www.baeldung.com/spring-aop" rel="noopener noreferrer"&gt;Baeldung article&lt;/a&gt; and the &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop" rel="noopener noreferrer"&gt;official Spring AOP documentation&lt;/a&gt;. But since we don’t wanna focus on boring theory and rather keep things practical, here’s a really short summary how AOP works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxafk877crjt6kflq9yt1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxafk877crjt6kflq9yt1.PNG" alt="Aspect oriented programming explained" width="567" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’ll need the following terms in this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Advice&lt;/strong&gt;: the method which implements some common task like logging or caching&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pointcut&lt;/strong&gt;: a pattern expression which matches the places where your Advice should be invoked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aspect&lt;/strong&gt;: The Advice plus the Pointcut expression&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bonus - Join point&lt;/strong&gt;: All places in your code that represent candidates for a Pointcut&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; &lt;code&gt;@Cacheable&lt;/code&gt;: a standard Spring Advice
&lt;/h1&gt;

&lt;p&gt;Let’s start simple and consider an already implemented Advice by &lt;a href="https://spring.io/" rel="noopener noreferrer"&gt;Spring&lt;/a&gt;, namely the &lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/annotation/Cacheable.html" rel="noopener noreferrer"&gt;@Cacheable annotation&lt;/a&gt;. Say your web service must compute numbers of the &lt;a href="https://en.wikipedia.org/wiki/Fibonacci_number" rel="noopener noreferrer"&gt;Fibonacci&lt;/a&gt; series.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don’t know what the Fibonacci series is: it’s the series starting with 0 and 1 and each consecutive number is the sum of the previous two numbers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We implement the Fibonacci computation in a &lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Service.html" rel="noopener noreferrer"&gt;@Service&lt;/a&gt; class:&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="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FibonacciService&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;Long&lt;/span&gt; &lt;span class="nf"&gt;nthFibonacciTerm&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&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;n&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;nthFibonacciTerm&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;nthFibonacciTerm&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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="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;Next, we use this service class in our &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer" rel="noopener noreferrer"&gt;REST&lt;/a&gt; controller:&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="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Autowired&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;FibonacciService&lt;/span&gt; &lt;span class="n"&gt;fibonacciService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/fibonacci/{number}"&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;Long&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;)&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;fibonacciService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nthFibonacciTerm&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;);&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;Our implementation is &lt;a href="https://en.wikipedia.org/wiki/Recursion_(computer_science)" rel="noopener noreferrer"&gt;recursive&lt;/a&gt; and thus rather slow. So how do you make your web service faster? One way would be to use a &lt;a href="https://www.baeldung.com/java-fibonacci#3-binets-formula" rel="noopener noreferrer"&gt;faster algorithm&lt;/a&gt;, but let’s solve the problem with Spring’s &lt;code&gt;@Cacheable&lt;/code&gt; feature. This annotation creates a cache in the background where all previous results get stored. All we must do, is add the &lt;code&gt;@Cacheable&lt;/code&gt; annotation to our method:&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="nd"&gt;@Cacheable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fibonacci"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/fibonacci/{number}"&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;Long&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&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;Now we’re ready to test our caching mechanism by firing a REST request to &lt;code&gt;http://localhost:8080/api/fibonacci/40&lt;/code&gt;. I tried to compute the 40th Fibonacci on my own laptop and here are the results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First REST call: 1902ms&lt;/li&gt;
&lt;li&gt;Second REST call: 1ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty good result eyyy🤙😎&lt;/p&gt;

&lt;p&gt;One last thing I’d like to mention: in order to activate Spring’s cacheable feature, you have to add &lt;code&gt;@EnableCaching&lt;/code&gt; to a &lt;code&gt;@Configuration&lt;/code&gt; class.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Log REST calls with a custom Aspect
&lt;/h1&gt;

&lt;p&gt;That was pretty easy right? So let’s move on to a more advanced use case: now we create a custom Aspect!&lt;/p&gt;

&lt;p&gt;Our goal is to &lt;strong&gt;create a log message every time some REST method gets called&lt;/strong&gt;. Since we might wanna add this functionality to future REST methods too, we want to generalize this task in an &lt;strong&gt;Aspect&lt;/strong&gt;:&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="nd"&gt;@Before&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@annotation(com.example.aop.LogMethodName)"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logMethodName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSignature&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getArgs&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Method ["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"] gets called with parameters "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;params&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;The first line defines the &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-pointcuts" rel="noopener noreferrer"&gt;Pointcut expression&lt;/a&gt;, and the subsequent method represents the &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-advice" rel="noopener noreferrer"&gt;Advice&lt;/a&gt;. Let’s break the two down one by one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pointcut&lt;/strong&gt;:&lt;br&gt;
The Pointcut expression defines the places where our Advice is inserted to. In our case, the Aspect is applied &lt;strong&gt;before&lt;/strong&gt; every method with a &lt;code&gt;@LogMehtodName&lt;/code&gt; annotation. Note that &lt;code&gt;@LogMethodName&lt;/code&gt; is our &lt;strong&gt;custom annotation&lt;/strong&gt; which we use as Pointcut marker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advice&lt;/strong&gt;:&lt;br&gt;
The advice method is the piece of logic that generalizes a task common to many different objects. In our case, the Advice finds the originating method’s name as well as its calling parameters and logs them to the console.&lt;/p&gt;

&lt;p&gt;With our Aspect in place, there are three additional code lines required to get everything working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, add the marker &lt;code&gt;@LogMethodName&lt;/code&gt; to our &lt;code&gt;fibonacci()&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;Second, we have to add &lt;code&gt;@Aspect&lt;/code&gt; to the class containing our Aspect&lt;/li&gt;
&lt;li&gt;Third, enable Spring’s Aspect scanning with &lt;code&gt;@EnableAspectJAutoProxy&lt;/code&gt; in any &lt;code&gt;@Configuration&lt;/code&gt; class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it, we’ve implemented our own Advice!🙌 Let’s run a test! We fire a REST request to the web service to compute the 40th Fibonacci number and have a look at the console output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;gets&lt;/span&gt; &lt;span class="nx"&gt;called&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;parameters&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It goes without saying that such log messages will be of great help if you ever must track down bugs in your application.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Performance monitoring with AOP
&lt;/h1&gt;

&lt;p&gt;In the previous example, we used a Pointcut expression of type &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-advice-before" rel="noopener noreferrer"&gt;@Before&lt;/a&gt; - here, the Advice runs before the actual method. Let’s switch gears and implement an &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-ataspectj-around-advice" rel="noopener noreferrer"&gt;@Around&lt;/a&gt; Pointcut. Such an Advice runs partly before the target method and partly after it.&lt;/p&gt;

&lt;p&gt;Our goal now is to &lt;strong&gt;monitor the execution time of any REST call&lt;/strong&gt;. Let’s go ahead and implement the monitoring requirement in a generalized fashion, namely an Aspect:&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="nd"&gt;@Around&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@annotation(com.example.aop.MonitorTime)"&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;Object&lt;/span&gt; &lt;span class="nf"&gt;monitorTime&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;proceed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Execution took ["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"ms]"&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;proceed&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;&lt;strong&gt;Pointcut&lt;/strong&gt;:&lt;br&gt;
Like before, we create a new custom annotation &lt;code&gt;@MonitorTime&lt;/code&gt; for marking our Pointcuts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advice&lt;/strong&gt;:&lt;br&gt;
An &lt;code&gt;@Around&lt;/code&gt; Aspect should have an argument of type &lt;a href="https://javadoc.io/doc/org.aspectj/aspectjweaver/latest/org/aspectj/lang/ProceedingJoinPoint.html" rel="noopener noreferrer"&gt;ProceedingJoinPoint&lt;/a&gt;. This type has a &lt;code&gt;proceed()&lt;/code&gt; method which triggers the execution of the actual target method. So in our Advice, we first query the current time in milliseconds. After the target method is executed, we measure the current time again, and from there we can compute time difference.&lt;/p&gt;

&lt;p&gt;Let’s go ahead and mark our target method with the &lt;code&gt;@MonitorTime&lt;/code&gt; annotation:&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="nd"&gt;@MonitorTime&lt;/span&gt;
&lt;span class="nd"&gt;@LogMethodName&lt;/span&gt;
&lt;span class="nd"&gt;@Cacheable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fibonacci"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/fibonacci/{number}"&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;Long&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&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;By now, our REST method has quite some Pointcut markers attached to it😉 Anyways, let’s go ahead and test our performance monitoring feature. As before, we compute the 40th Fibonacci number:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;gets&lt;/span&gt; &lt;span class="nx"&gt;called&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;parameters&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;Execution&lt;/span&gt; &lt;span class="nx"&gt;took&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1902&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As you can see, this particular REST call took 1902ms. With this &lt;code&gt;@Around&lt;/code&gt; Aspect in place, you’re definitely an advanced AOP programmer!💪&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Retry mechanism with AOP
&lt;/h1&gt;

&lt;p&gt;Distributed systems can experience concurrency issues. One such example would be when two web service instances are simultaneously trying to access the same record in a database. Oftentimes, such a lock problem can be resolved by retrying the operation. The only requirement here is that the operation is idempotent.&lt;/p&gt;

&lt;p&gt;Let’s go ahead and create an Aspect which &lt;strong&gt;transparently retries an operation until it succeeds&lt;/strong&gt;:&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="nd"&gt;@Around&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@annotation(com.example.aop.RetryOperation)"&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;Object&lt;/span&gt; &lt;span class="nf"&gt;doIdempotentOperation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numAttempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;numAttempts&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
      &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numAttempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;exception&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;&lt;strong&gt;Pointcut&lt;/strong&gt;:&lt;br&gt;
Our Advice runs around any method with the custom annotation &lt;code&gt;@RetryOperation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advice&lt;/strong&gt;:&lt;br&gt;
In the &lt;code&gt;try&lt;/code&gt; statement, we run the target method. This method might throw a &lt;code&gt;RuntimeException&lt;/code&gt;. If this happens, we increment the &lt;code&gt;numAttempts&lt;/code&gt; counter and simply rerun the target method. As soon as the target method succeeds, we exit the Advice.&lt;/p&gt;

&lt;p&gt;For demonstration purposes, let’s create a REST method for storing a String. This method will fail 50% of the time:&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="nd"&gt;@RetryOperation&lt;/span&gt;
&lt;span class="nd"&gt;@LogMethodName&lt;/span&gt;
&lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/storeData"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;storeData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&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;"data"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;nextBoolean&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pretend everything went fine"&lt;/span&gt;&lt;span class="o"&gt;);&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;Thanks to our &lt;code&gt;@RetryOperation&lt;/code&gt; annotation, the above method will be retried until it succeeds. Moreover, we use our &lt;code&gt;@LogMethodName&lt;/code&gt; annotation so we can see every method invocation. Let’s go ahead and test our new REST endpoint; for this purpose we fire a REST request to &lt;code&gt;localhost:8080/api/storeData?data=hello-world&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;storeData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;gets&lt;/span&gt; &lt;span class="nx"&gt;called&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;parameters&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;storeData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;gets&lt;/span&gt; &lt;span class="nx"&gt;called&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;parameters&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;storeData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;gets&lt;/span&gt; &lt;span class="nx"&gt;called&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;parameters&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;Pretend&lt;/span&gt; &lt;span class="nx"&gt;everything&lt;/span&gt; &lt;span class="nx"&gt;went&lt;/span&gt; &lt;span class="nx"&gt;fine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the above case, the operation failed 2 times and only succeeded on the third try.&lt;/p&gt;
&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Congrats, you’re a professional AOP programmer now🥳🚀 You can find a fully working web service with all Aspects on my Github repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pmgysel" rel="noopener noreferrer"&gt;
        pmgysel
      &lt;/a&gt; / &lt;a href="https://github.com/pmgysel/aop-examples" rel="noopener noreferrer"&gt;
        aop-examples
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Some examples of Aspect Oriented Programming (AOP) with SpringBoot
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Thanks so much for reading, please leave a comment if you have any questions or feedback!&lt;/p&gt;

</description>
      <category>java</category>
      <category>aop</category>
      <category>springboot</category>
      <category>programming</category>
    </item>
    <item>
      <title>Aspect Oriented Programming with Java and SpringBoot</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Wed, 06 Jan 2021 13:26:26 +0000</pubDate>
      <link>https://dev.to/pmgysel/aspect-oriented-programming-with-java-and-springboot-2nlg</link>
      <guid>https://dev.to/pmgysel/aspect-oriented-programming-with-java-and-springboot-2nlg</guid>
      <description>&lt;p&gt;This blog covers the basics of &lt;strong&gt;Aspect Oriented Programming&lt;/strong&gt; (AOP). I’ll show a simple working example of AOP: a common task like logging of REST calls can be generically defined in an &lt;strong&gt;Advice&lt;/strong&gt;, which can then be applied to various target places in our code (so called &lt;strong&gt;Pointcuts&lt;/strong&gt;) via an &lt;strong&gt;Aspect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For the impatient: you can find the end result on my Github repo🏎️&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pmgysel" rel="noopener noreferrer"&gt;
        pmgysel
      &lt;/a&gt; / &lt;a href="https://github.com/pmgysel/aop-demo" rel="noopener noreferrer"&gt;
        aop-demo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo for Aspect Oriented Programming
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Programming Paradigms
&lt;/h1&gt;

&lt;p&gt;Back in the 1996, when &lt;a href="https://www.java.com/en/" rel="noopener noreferrer"&gt;Java&lt;/a&gt; 1.0 was released, Java developers were all hyped up about &lt;a href="https://en.wikipedia.org/wiki/Object-oriented_programming" rel="noopener noreferrer"&gt;object oriented programming&lt;/a&gt;, also called OOP. While OOP was one of the foundational drivers for Java, the programming language itself has gone a long way since then and now supports many &lt;a href="https://en.wikipedia.org/wiki/Programming_paradigm" rel="noopener noreferrer"&gt;programming paradigms&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a list of the primary programming paradigms supported in Java (in historical order):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Procedural programming&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Object oriented programming&lt;/strong&gt; (OOP)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functional programming&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aspect oriented programming&lt;/strong&gt; (AOP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this post, we focus on &lt;a href="https://en.wikipedia.org/wiki/Aspect-oriented_programming" rel="noopener noreferrer"&gt;AOP&lt;/a&gt; and show how to create Aspects. You’ll learn both the basics of AOP as well as how to use it with &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;SpringBoot&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why AOP?
&lt;/h1&gt;

&lt;p&gt;Most bigger companies have programming guidelines, and so does mine. One of our guidelines states that every &lt;a href="https://spring.io/guides/gs/rest-service/" rel="noopener noreferrer"&gt;REST&lt;/a&gt; endpoint execution must be logged (name of the Java method + the parameters).&lt;/p&gt;

&lt;p&gt;Here’s how you could solve this:&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="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyRestController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/hello/"&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;String&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Method [hello] gets called with 0 parameters"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello world!"&lt;/span&gt;&lt;span class="o"&gt;;&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;The code snippet above does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@RestController&lt;/code&gt;: Make sure SpringBoot knows this class contains REST endpoints&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@GetMapping&lt;/code&gt;: A method which replies to HTTP GET requests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;System.out.println(...)&lt;/code&gt;: adhere to the aforementioned coding guidelines&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;return&lt;/code&gt; value: the method simply returns a greeting message of type String&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a realistic app, you will have many such REST calls, in many different classes. Doing the &lt;strong&gt;exact same logging&lt;/strong&gt; in all those methods is &lt;strong&gt;cumbersome&lt;/strong&gt;. Moreover, if the coding guidelines slightly change, you will have to change the logging message in each method.&lt;/p&gt;

&lt;p&gt;Here’s where AOP comes to the rescue: with the help of AOP, we can nicely &lt;strong&gt;add common functionality to many different places in our code, without interfering with existing code&lt;/strong&gt;. In literature jargon, &lt;a href="https://en.wikipedia.org/wiki/Aspect-oriented_programming" rel="noopener noreferrer"&gt;AOP&lt;/a&gt; is all about the separation of cross-cutting concerns.🤓 In more human understandable language, AOP enables the modularization of common tasks across different objects.😎&lt;/p&gt;
&lt;h1&gt;
  
  
  Maven Dependency
&lt;/h1&gt;

&lt;p&gt;To start using AOP in &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;SpringBoot&lt;/a&gt; with &lt;a href="https://www.eclipse.org/aspectj" rel="noopener noreferrer"&gt;AspectJ annotations&lt;/a&gt;, we need to import the following dependencies in our &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-aop&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.aspectj&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;aspectjweaver&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  Advice
&lt;/h1&gt;

&lt;p&gt;Let’s create a function which performs our required logging in a generic way:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logMethodExecution&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSignature&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getArgs&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Method ["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"] gets called with parameters "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;params&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;This generic function is called an &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-advice" rel="noopener noreferrer"&gt;Advice&lt;/a&gt;. Note that it can log the name and parameters of &lt;strong&gt;any&lt;/strong&gt; method; let’s break the Advice down step by step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;JoinPoint&lt;/code&gt;: this object contains all information about the &lt;a href="https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html" rel="noopener noreferrer"&gt;Join point&lt;/a&gt;, that is, the "location" where our Aspect will be inserted. In our case, this would be the &lt;strong&gt;REST method&lt;/strong&gt; for which we want to create a log message for.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;joinPoint.getSignature()&lt;/code&gt; and &lt;code&gt;joinPoint.getArgs()&lt;/code&gt; extracts the method signature as well as the calling arguments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;System.out.println(...)&lt;/code&gt;: do the necessary logging&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Pointcut
&lt;/h1&gt;

&lt;p&gt;So where do we want to insert the above Advise method? Well, we want each REST endpoint to be tracked. While there are many ways to mark our REST endpoints, we choose to use a &lt;strong&gt;custom annotation&lt;/strong&gt; to define the &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-pointcuts" rel="noopener noreferrer"&gt;Pointcut&lt;/a&gt;:&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="nd"&gt;@Before&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@annotation(LogMethod)"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logMethodExecution&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&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;As you can see, the Pointcut definition is just a one-liner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Before&lt;/code&gt;: we run the Advice before the REST call gets answered&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@annotation&lt;/code&gt;: we mark Pointcuts via an annotation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LogMethod&lt;/code&gt;: this is the name of our custom annotation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we’re ready to mark our REST method with our custom annotation:&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="nd"&gt;@LogMethod&lt;/span&gt;
&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/hello/"&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;String&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello world!"&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;Note that we prepended the REST method with the annotation &lt;code&gt;@LogMethod&lt;/code&gt;. Moreover, we removed the logging inside the method, this is now done by our Aspect.&lt;/p&gt;
&lt;h1&gt;
  
  
  Aspect
&lt;/h1&gt;

&lt;p&gt;An &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-at-aspectj" rel="noopener noreferrer"&gt;Aspect&lt;/a&gt; is a Pointcut plus an Advice. So, let’s put the two together, and we get:&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="nd"&gt;@Aspect&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoggingAspect&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Before&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@annotation(LogMethod)"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logMethodName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSignature&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getArgs&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Method ["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"] gets called with parameters "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;);&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;Here’s what we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Aspect&lt;/code&gt;: SpringBoot expects all Aspects to be in classes annotated with &lt;a class="mentioned-user" href="https://dev.to/aspect"&gt;@aspect&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Before(...)&lt;/code&gt;: the Pointcut&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;logMethodName(...){...}&lt;/code&gt;: the Advice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So all we did here was just bring together the previously shown Pointcut expression plus the Advice, and wrap everything in a class. Bring out the champagne, we have our Aspect all finished and working 🥂&lt;/p&gt;
&lt;h1&gt;
  
  
  Enable AOP
&lt;/h1&gt;

&lt;p&gt;To wrap up, we have to &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-aspectj-support" rel="noopener noreferrer"&gt;enable AspectJ for our Spring configuration&lt;/a&gt;:&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="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableAspectJAutoProxy&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AspectConfig&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;Remember that we want to be able to work with Beans when using Spring. At the moment, our &lt;code&gt;@RestController&lt;/code&gt; class only contains the REST-call logic, but not our Advice. Spring can create &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-understanding-aop-proxies" rel="noopener noreferrer"&gt;Proxies&lt;/a&gt; for such Beans which contain this additional logic (the Advice), and this is enabled by &lt;code&gt;@EnableAspectJAutoProxy&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s all! You now have a fully working example of AOP😀💪🍾&lt;/p&gt;

&lt;p&gt;We implemented an Advice to be run anytime a method with annotation &lt;code&gt;@LogMethod&lt;/code&gt; is executed. Thanks to our AOP approach, we can add this annotation to future REST methods which will then be advised with the same Aspect!&lt;/p&gt;

&lt;p&gt;Checkout the fully working example on Github:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pmgysel" rel="noopener noreferrer"&gt;
        pmgysel
      &lt;/a&gt; / &lt;a href="https://github.com/pmgysel/aop-demo" rel="noopener noreferrer"&gt;
        aop-demo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo for Aspect Oriented Programming
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Demo for Aspect Oriented Programming&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;This is a simple web service which uses AOP. The REST methods are advised by multiple Aspects.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Dependencies&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Java JDK 15&lt;/li&gt;
&lt;li&gt;Maven:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spring-boot-starter-aop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aspectjweaver&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Aspects for REST calls&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Log method name and parameters&lt;/li&gt;
&lt;li&gt;Log duration of method&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Compile and run web service:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;mvn clean install
mvn spring-boot:run&lt;/pre&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Sample REST calls:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;GET http://localhost:8080/api/greeting/{name}
GET http://localhost:8080/api/order/{menu}&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Sample aspect output&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;Method [greeting] gets called with parameters [John]
Exeution took [21ms]&lt;/pre&gt;

&lt;/div&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pmgysel/aop-demo" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;This Github repo also contains a second advice of type &lt;code&gt;@Around&lt;/code&gt;: Each time a REST method is called, we log the execution time. This can come in handy to measure, monitor and compare the performance of different REST endpoints.&lt;/p&gt;

&lt;p&gt;Thanks for reading, please leave a comment if you have any feedback or questions!😀&lt;/p&gt;




&lt;h1&gt;
  
  
  Further readings
&lt;/h1&gt;

&lt;p&gt;For the curious, here’s some more reading material:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-introduction-defn" rel="noopener noreferrer"&gt;&lt;strong&gt;AOP primer and Advice types&lt;/strong&gt;&lt;/a&gt;: &lt;br&gt;
In our example, we used an Advice of type &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-advice-before" rel="noopener noreferrer"&gt;@Before&lt;/a&gt;. Alternatively, you can use &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-advice-after-finally" rel="noopener noreferrer"&gt;@After&lt;/a&gt;, &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-ataspectj-around-advice" rel="noopener noreferrer"&gt;@Around&lt;/a&gt; or &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-advice-after-throwing" rel="noopener noreferrer"&gt;@AfterThrowing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-pointcuts" rel="noopener noreferrer"&gt;&lt;strong&gt;Pointcuts&lt;/strong&gt;&lt;/a&gt; are predicates that match a set of Join points. We used annotation-driven Pointcuts, but Spring supports many more designator types. For example, Spring supports &lt;code&gt;execution&lt;/code&gt; Pointcuts where a method name has to match a given pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/5.0.0.RELEASE/spring-framework-reference/core.html#aop-introduction-proxies" rel="noopener noreferrer"&gt;&lt;strong&gt;AOP Proxies&lt;/strong&gt;&lt;/a&gt;: an explanation in the official Spring documentation.&lt;/p&gt;

</description>
      <category>java</category>
      <category>aop</category>
      <category>springboot</category>
      <category>beginners</category>
    </item>
    <item>
      <title>From Java 8 to Java 15 in Ten Minutes</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 07 Dec 2020 15:13:51 +0000</pubDate>
      <link>https://dev.to/pmgysel/from-java-8-to-java-15-in-ten-minutes-22f7</link>
      <guid>https://dev.to/pmgysel/from-java-8-to-java-15-in-ten-minutes-22f7</guid>
      <description>&lt;p&gt;This blog will give you samples of awesome new feature added since Java 7. I’ll showcase at least one major improvement for each Java version, all the way to Java 15 which was released in fall 2020. Java now fully supports &lt;strong&gt;lambdas&lt;/strong&gt;, &lt;strong&gt;functional programming&lt;/strong&gt;, type inference via &lt;code&gt;var&lt;/code&gt;, &lt;strong&gt;immutable collections&lt;/strong&gt; with simple constructors, and &lt;strong&gt;multi-line strings&lt;/strong&gt;. Moreover, there are exciting new experimental features like &lt;strong&gt;data classes&lt;/strong&gt; (&lt;code&gt;record&lt;/code&gt;), and &lt;code&gt;sealed&lt;/code&gt; classes. Finally I’ll talk about the &lt;strong&gt;Java REPL&lt;/strong&gt; which offers high value for quick experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Functional programming&lt;/strong&gt; (Java 8)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Streams&lt;/code&gt;&lt;/strong&gt; (Java 8)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Optional&lt;/code&gt;&lt;/strong&gt; (Java 8)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;JShell&lt;/code&gt;&lt;/strong&gt; (Java 9)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Factory Method for Immutable Collections&lt;/strong&gt; (Java 9)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type Inference with &lt;code&gt;var&lt;/code&gt;&lt;/strong&gt; (Java 10)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single Source File Launch&lt;/strong&gt; (Java 11)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Switch Expression&lt;/strong&gt; (Java 12: experimental, full feature: Java 14)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-line Strings&lt;/strong&gt; (Java 13: experimental, full feature: Java 15)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Classes: &lt;code&gt;record&lt;/code&gt;&lt;/strong&gt; (Java 14: experimental)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;instanceof&lt;/code&gt; without Cast&lt;/strong&gt; (Java 14: experimental)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sealed classes&lt;/strong&gt; (Java 15: experimental)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Bonus: Updated Licensing Terms Starting with Java 8&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Functional Programming (Java 8)
&lt;/h1&gt;

&lt;p&gt;In Java 8, functional programming and lambdas were added as language features. The two core paradigms of &lt;a href="https://www.freecodecamp.org/news/an-introduction-to-the-basic-principles-of-functional-programming-a2c2a15c84/" rel="noopener noreferrer"&gt;functional programming&lt;/a&gt; are &lt;strong&gt;immutable values&lt;/strong&gt; and elevating &lt;strong&gt;functions&lt;/strong&gt; to first class citizens. Data goes through a pipeline of modification steps, where each step takes some input and maps it to a new output. Functional programming can be used with &lt;code&gt;Streams&lt;/code&gt; and null-safe monads (&lt;code&gt;Optional&lt;/code&gt;) in Java as shown below...&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Streams (Java 8)
&lt;/h1&gt;

&lt;p&gt;For your average computer program, you often have to work with a list of values and perform a given &lt;strong&gt;transformation on each value&lt;/strong&gt;. Prior to Java 8, you had to use a &lt;strong&gt;&lt;code&gt;for&lt;/code&gt; loop&lt;/strong&gt; for this transformation, but from now, you can use &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html" rel="noopener noreferrer"&gt;&lt;code&gt;Streams&lt;/code&gt;&lt;/a&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;great&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;println&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;great&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; function takes as input a lambda, which will be applied to all elements in the stream.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Streams&lt;/code&gt; can work on &lt;code&gt;Lists&lt;/code&gt;, &lt;code&gt;Sets&lt;/code&gt;, and &lt;code&gt;Maps&lt;/code&gt; (via transformation). Thanks to Streams, you can get rid of pretty much all loops in your code!👌&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Optional (Java 8)
&lt;/h1&gt;

&lt;p&gt;Another common problem in Java were &lt;strong&gt;Null Pointer Exceptions&lt;/strong&gt;. So, Java introduced &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html" rel="noopener noreferrer"&gt;Optional&lt;/a&gt; – a monad that wraps a reference which might or might not be null. Applying updates to this Optional can be done in a functional way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;nextInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number is even: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifPresent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;println&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;even&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the snippet above, we create a random number, wrap it inside an Optional object, and then only print the number if it is even.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; JShell (Java 9)
&lt;/h1&gt;

&lt;p&gt;Finally, we have a &lt;a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop" rel="noopener noreferrer"&gt;REPL&lt;/a&gt; for Java, and its name is &lt;a href="https://docs.oracle.com/javase/9/jshell/introduction-jshell.htm#JSHEL-GUID-630F27C8-1195-4989-9F6B-2C51D46F52C8" rel="noopener noreferrer"&gt;JShell&lt;/a&gt;!😊 In a nutshell, JShell allows to experiment with Java snippets without writing and compiling a full Java class. Instead, you can &lt;strong&gt;execute one command at a time&lt;/strong&gt;, and you immediately see the result. Here’s a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;JDK&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sr"&gt;/bin/&lt;/span&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;
&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Folks familiar with interpreted languages like JavaScript or Python have had the pleasure of a REPL for a long time, but so far, this feature was missing in Java. JShell allows to define &lt;strong&gt;variables&lt;/strong&gt;, but also more complex entities like &lt;strong&gt;multi-line functions&lt;/strong&gt;,  classes, and perform &lt;strong&gt;loops&lt;/strong&gt;. Moreover, JShell supports auto-completion, which comes in handy if you don’t know the exact methods offered by a given Java class.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Factory Methods for Immutable Collections (Java 9)
&lt;/h1&gt;

&lt;p&gt;Simple initialization of &lt;code&gt;Lists&lt;/code&gt; has been missing in Java for a long time, but those times are over now. 😅 Previously you had to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Arrays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is now simplified as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fancy &lt;code&gt;of(...)&lt;/code&gt; method exists for &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/List.html" rel="noopener noreferrer"&gt;List&lt;/a&gt;, &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/Set.html" rel="noopener noreferrer"&gt;Set&lt;/a&gt; and &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/Map.html" rel="noopener noreferrer"&gt;Map&lt;/a&gt;. They all create an immutable object in just one simple line of code.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Type Inference with &lt;code&gt;var&lt;/code&gt; (Java 10)
&lt;/h1&gt;

&lt;p&gt;Java 10 introduced the new &lt;a href="https://developer.oracle.com/java/jdk-10-local-variable-type-inference.html" rel="noopener noreferrer"&gt;var&lt;/a&gt; keyword which allows to &lt;strong&gt;omit the type&lt;/strong&gt; of a variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;$1&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the snippet above, the type of &lt;code&gt;x&lt;/code&gt; can be &lt;strong&gt;inferred&lt;/strong&gt; to be HashSet by the compiler.&lt;/p&gt;

&lt;p&gt;This feature helps to &lt;strong&gt;reduce boilerplate code&lt;/strong&gt; and &lt;strong&gt;improve readability&lt;/strong&gt;. There’s some limitations to it though: you can only use &lt;code&gt;var&lt;/code&gt; inside of method bodies, and the compiler will infer the type at compile time, so everything is still statically typed.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Single Source File Launch (Java 11)
&lt;/h1&gt;

&lt;p&gt;Previously, when you had written a simple Java program consisting of one file, you had to first compile the file with &lt;code&gt;javac&lt;/code&gt; and then run it with &lt;code&gt;java&lt;/code&gt;. In Java 11, you can do both steps with one command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Main.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;java&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;java&lt;/span&gt;
&lt;span class="nx"&gt;hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For simple starter programs or experiments consisting of just one Java class, this feature for &lt;a href="https://www.baeldung.com/java-single-file-source-code" rel="noopener noreferrer"&gt;launching single source files&lt;/a&gt; will make your life easier.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Switch Expression (Java 12)
&lt;/h1&gt;

&lt;p&gt;Java 12 brought us &lt;a href="https://docs.oracle.com/en/java/javase/13/language/switch-expressions.html" rel="noopener noreferrer"&gt;Switch expressions&lt;/a&gt;. Here’s a quick showcase of how the expression differs from the old switch statement.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;old switch statement&lt;/strong&gt; defines the flow of the program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unknown number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;
&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In contrast, the &lt;strong&gt;new switch expression&lt;/strong&gt; returns a value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unknown number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To sum up, the old switch statement is for program flow, and the new switch expression resolves to a value.&lt;/p&gt;

&lt;p&gt;Notice that this new switch statement is a sort of &lt;strong&gt;mapping&lt;/strong&gt; function: there’s one input (in the above case &lt;code&gt;i&lt;/code&gt;), and there’s one output (here &lt;code&gt;x&lt;/code&gt;). This is actually a &lt;a href="https://en.wikipedia.org/wiki/Pattern_matching" rel="noopener noreferrer"&gt;pattern matching&lt;/a&gt; feature which helps to make Java more compatible with the &lt;strong&gt;functional programming&lt;/strong&gt; principles. A &lt;a href="https://docs.scala-lang.org/tour/pattern-matching.html" rel="noopener noreferrer"&gt;similar switch statement&lt;/a&gt; has been available in Scala for a while.&lt;/p&gt;

&lt;p&gt;A couple of things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of double points, we use arrows &lt;code&gt;-&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;There’s no need for &lt;code&gt;break&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The default case can be omitted when all possible cases are considered&lt;/li&gt;
&lt;li&gt;To enable this feature with Java 12, use &lt;code&gt;--enable-preview --source 12&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Multi-line Strings (Java 13)
&lt;/h1&gt;

&lt;p&gt;Did you ever have to define a long &lt;strong&gt;multi-line String&lt;/strong&gt; like JSON or XML? So far, you’d probably squash everything on one line and use newline characters &lt;code&gt;\n&lt;/code&gt;, but this makes the String much harder to read. Here comes Java 13 with &lt;a href="https://blogs.oracle.com/javamagazine/text-blocks-come-to-java" rel="noopener noreferrer"&gt;multi-line Strings&lt;/a&gt;!💪&lt;/p&gt;

&lt;p&gt;Sample case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"""&lt;/span&gt;&lt;span class="s2"&gt;
        {
            &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;recipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;watermelon&lt;/span&gt; &lt;span class="nx"&gt;smoothie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,
            &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="nx"&gt;mins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,
            &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;watermelon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;lemon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;parsley&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;]
        }&lt;/span&gt;&lt;span class="dl"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we run the main Method via single-file-launch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;java&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;enable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;preview&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;java&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;watermelon smoothie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;duration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10 mins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;watermelon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lemon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parsley&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting String spans multiple lines, quotation marks &lt;code&gt;""&lt;/code&gt; are left intact, and even tabs &lt;code&gt;\t&lt;/code&gt; are preserved!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Data Classes: &lt;code&gt;record&lt;/code&gt; (Java 14)
&lt;/h1&gt;

&lt;p&gt;Of all the new features in this article, this is probably the one I’m most excited about: finally, there are &lt;strong&gt;data classes&lt;/strong&gt; in Java! These classes are declared with the &lt;a href="https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Record.html" rel="noopener noreferrer"&gt;record&lt;/a&gt; keyword and have automatic Getters, a constructor, and equals() method etc. In short, you can get rid of a huge chunk of boilerplate code!🙌🎉&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Employee &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;department&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="nx"&gt;created&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;

&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Legal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Anne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;department&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Legal&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;$2&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scala has a similar feature with &lt;a href="https://docs.scala-lang.org/tour/case-classes.html" rel="noopener noreferrer"&gt;case classes&lt;/a&gt;, and Kotlin with &lt;a href="https://kotlinlang.org/docs/reference/data-classes.html" rel="noopener noreferrer"&gt;data classes&lt;/a&gt;. In Java, lots of developers used &lt;a href="https://projectlombok.org/" rel="noopener noreferrer"&gt;Lombok&lt;/a&gt; so far, which offered pretty much the features that now inspired &lt;code&gt;records&lt;/code&gt; for Java 14. More details can be found in this &lt;a href="https://www.baeldung.com/java-record-keyword" rel="noopener noreferrer"&gt;Baeldung article&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; &lt;code&gt;instanceof&lt;/code&gt; without Cast (Java 14)
&lt;/h1&gt;

&lt;p&gt;Prior versions of Java already contained the &lt;code&gt;instanceof&lt;/code&gt; keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;String length: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The unfortunate part: First we check that &lt;code&gt;s&lt;/code&gt; is of type &lt;code&gt;String&lt;/code&gt;, then we cast it again to retrieve its length.&lt;/p&gt;

&lt;p&gt;Now with Java 14, the compiler is smart enough to &lt;a href="https://blogs.oracle.com/javamagazine/pattern-matching-for-instanceof-in-java-14" rel="noopener noreferrer"&gt;infer the type automatically after the instanceof check&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;mystr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;String length: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;mystr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Sealed classes (Java 15)
&lt;/h1&gt;

&lt;p&gt;With the &lt;a href="https://docs.oracle.com/en/java/javase/15/language/sealed-classes-and-interfaces.html" rel="noopener noreferrer"&gt;sealed keyword&lt;/a&gt;, you can &lt;strong&gt;restrict&lt;/strong&gt; which classes can &lt;strong&gt;extend&lt;/strong&gt; a given class or interface. Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;sealed&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Fruit&lt;/span&gt; &lt;span class="nx"&gt;permits&lt;/span&gt; &lt;span class="nx"&gt;Apple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Pear&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Apple&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Fruit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Apple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pear&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Fruit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pear&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So how does this help us? Well, now you know how many &lt;code&gt;Fruits&lt;/code&gt; there are. This is actually an important step into the direction &lt;a href="https://blogs.oracle.com/javamagazine/inside-the-language-sealed-types" rel="noopener noreferrer"&gt;fully supported pattern matching&lt;/a&gt;, where you can sort of treat classes like enums. This &lt;code&gt;sealed&lt;/code&gt; feature goes together nicely with the new &lt;code&gt;switch&lt;/code&gt; expression explained previously.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Bonus: Updated Licensing Terms Starting with Java 8
&lt;/h1&gt;

&lt;p&gt;One last topic for this article: &lt;strong&gt;licensing&lt;/strong&gt;. Most of you heard that &lt;a href="https://www.oracle.com/java/technologies/java-se-support-roadmap.html" rel="noopener noreferrer"&gt;Oracle stopped updates for Java 8&lt;/a&gt; (for the free commercial version). So here are your options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a &lt;strong&gt;newer Oracle JDK&lt;/strong&gt; version (Oracle offers free security updates for only 6 months after each release)&lt;/li&gt;
&lt;li&gt;Use and &lt;strong&gt;old JDK&lt;/strong&gt; version at your own risk&lt;/li&gt;
&lt;li&gt;Use an old &lt;strong&gt;OpenJDK&lt;/strong&gt; Java version, those still get security updates from the open source community or a third party vendor&lt;/li&gt;
&lt;li&gt;Pay Oracle for &lt;strong&gt;premier support&lt;/strong&gt; (e.g. Java 8: support until 2030)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below you can see the tentative Oracle support durations per JDK:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F009ln0icghz4w859acuf.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F009ln0icghz4w859acuf.PNG" alt="Oracle Java SE Support Roadmap" width="625" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oracle’s new licensing model is influenced by the new &lt;a href="https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence" rel="noopener noreferrer"&gt;release cycle&lt;/a&gt;: Oracle will bring out a new Java version every 6 months. This new release cycle helps Oracle to improve Java at a faster pace, get quicker feedback via experimental features, and catch up with more modern languages like &lt;a href="https://www.scala-lang.org/" rel="noopener noreferrer"&gt;Scala&lt;/a&gt;, &lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt; and &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you’re interested in more licensing details, checkout this &lt;a href="https://medium.com/@javachampions/java-is-still-free-2-0-0-6b9aa8d6d244" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; article.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;p&gt;Java has gone a long way in the last 6 years, there's actually been 8 new Java releases since then!🚀 All these awesome new features help to make Java a competitive option compared to other JVM-based rivals (Scala and Kotlin).&lt;/p&gt;

&lt;p&gt;If you're looking for even more in-depth details on new Java features since Java 8, I can recommend this &lt;a href="https://dev.to/awwsmm/20-reasons-to-move-on-from-java-8-1dio"&gt;DEV article by Andrew&lt;/a&gt; as well as this &lt;a href="https://advancedweb.hu/a-categorized-list-of-all-java-and-jvm-features-since-jdk-8-to-15/" rel="noopener noreferrer"&gt;article by David Csakvari&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I had a blast writing this article🔥 Thanks for reading😊 What's your favorite feature in a recent java release? I'd love to get a feedback from you! Cheers!&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>functional</category>
    </item>
    <item>
      <title>From Legacy Projects to CI/CD Pipelines</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Tue, 17 Nov 2020 14:46:42 +0000</pubDate>
      <link>https://dev.to/pmgysel/from-legacy-projects-to-ci-cd-pipelines-2oo4</link>
      <guid>https://dev.to/pmgysel/from-legacy-projects-to-ci-cd-pipelines-2oo4</guid>
      <description>&lt;p&gt;Recently I received the maintenance responsibility for two &lt;strong&gt;legacy projects&lt;/strong&gt; in my company. One of the projects is 8 years old, the other is so old even our tester doesn’t know when the project started – definitely before he joined 12 years ago. Obviously, both projects use pretty old technologies like Ant-scripts and both have many features which aren’t even used any more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So how do you deal with such an old project - as a motivated and &lt;strong&gt;proactive engineer&lt;/strong&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this blog, I’ll show you how you can make the best of such a situation, and how you can have a positive and significant impact. 🚀😎&lt;/p&gt;

&lt;h1&gt;
  
  
  CI / CD Theory
&lt;/h1&gt;

&lt;p&gt;First off, here's the theory for &lt;a href="https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment" rel="noopener noreferrer"&gt;CI/CD&lt;/a&gt;, which stands for &lt;strong&gt;continuous integration, delivery and deployment&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz6eng8e0o6gyuo95xd8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz6eng8e0o6gyuo95xd8d.png" alt="CI/CD Pipeline" width="784" height="717"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From what I hear, there's some &lt;a href="https://dev.to/canarian/let-s-stop-fooling-ourselves-what-we-call-ci-cd-is-actually-only-ci-13c"&gt;misconceptions&lt;/a&gt; out there as to what CI/CD really means. In the graph above, you can see there are three parts to it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;compilation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;bringing the software to a &lt;strong&gt;test system&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;and finally releasing it to the &lt;strong&gt;productive environment&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Flee from the Problem?
&lt;/h1&gt;

&lt;p&gt;Now if you’re ever stranded on a legacy project, one obvious solution is to polish up your LinkedIn and start sending out resumes😜&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ilszvf1m9xhvicy15ze.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ilszvf1m9xhvicy15ze.PNG" alt="Run away from problem" width="313" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember though that every company has legacy projects. So rather than complaining, this article is about the &lt;strong&gt;positive impact&lt;/strong&gt; you can have on a legacy project.&lt;/p&gt;

&lt;p&gt;Before we get into the details, let me just mention that I’m lucky enough to only work part time on these legacy projects – the rest of my time, I spend on developing new software from scratch. There’s a brand-new web service I’m currently working on that uses the latest Java version, &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt;, &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, an elaborate CI/CD pipeline and cloud-hosting, so this keeps me happy😊&lt;/p&gt;

&lt;h1&gt;
  
  
  Version Control
&lt;/h1&gt;

&lt;p&gt;When I started on these 2 legacy projects, the first thing I did was migrating to a decent &lt;strong&gt;version control system&lt;/strong&gt;.  Both projects used &lt;a href="https://subversion.apache.org/" rel="noopener noreferrer"&gt;SVN&lt;/a&gt; for versioning, but luckily, migrating to a new version control system is straight forward and worth the time. So, I used &lt;code&gt;svn2git&lt;/code&gt; and created new &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; repositories. After completion, I could use &lt;strong&gt;branches for quick experiments&lt;/strong&gt;, plus &lt;code&gt;git&lt;/code&gt; is much, much &lt;strong&gt;faster&lt;/strong&gt; than SVN, and finally, you can perform &lt;strong&gt;commits&lt;/strong&gt; without the need to immediately push your changes to the server.&lt;/p&gt;

&lt;h1&gt;
  
  
  Compile
&lt;/h1&gt;

&lt;p&gt;Next, I analyzed the build system of my legacy projects. The question looks easy: how do I compile this code? Well my legacy projects consisted of many sub-components, some of which were easy to compile, some of which were hard to compile. There were easy cases of plain old Java-Maven projects where I could just run &lt;code&gt;mvn clean package&lt;/code&gt;. One particular component though was much harder to compile: it was an old Grails app and getting all &lt;strong&gt;dependency versions&lt;/strong&gt; right like Grails, Java and Maven was tricky.&lt;/p&gt;

&lt;p&gt;In the end, you want to have a &lt;strong&gt;terminal command that will compile the project&lt;/strong&gt; for you. Once you have that, you’re good, since you have a command, and this can be automated. So, in my case, I set up a &lt;a href="https://www.jenkins.io/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt; job for every component which performed the building process for me.&lt;/p&gt;

&lt;p&gt;Note that in rare cases, there might be a need to &lt;strong&gt;re-engineer the compilation process&lt;/strong&gt;. I've seen Java projects that use &lt;a href="http://ant.apache.org/" rel="noopener noreferrer"&gt;Ant&lt;/a&gt; and checked-in Jar dependencies. This is an outdated and cumbersome way to do things, and it would really make sense in this case to move to &lt;a href="https://maven.apache.org/" rel="noopener noreferrer"&gt;Maven&lt;/a&gt; or &lt;a href="https://gradle.org/" rel="noopener noreferrer"&gt;Gradle&lt;/a&gt; instead and use a &lt;a href="https://en.wikipedia.org/wiki/Software_repository" rel="noopener noreferrer"&gt;registry&lt;/a&gt; for dependencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code quality
&lt;/h1&gt;

&lt;p&gt;Is your application &lt;strong&gt;secure&lt;/strong&gt; and your code &lt;strong&gt;clean&lt;/strong&gt;? An easy way to advance on these questions and possibly improve your code quality is by using a &lt;a href="https://en.wikipedia.org/wiki/Static_program_analysis" rel="noopener noreferrer"&gt;static code analysis&lt;/a&gt; tool. Inspecting your code is non-intrusive, all you do is add a new step to your continuous integration pipeline. There are many great tools out there. For my projects I chose &lt;a href="https://www.sonarqube.org/" rel="noopener noreferrer"&gt;SonarQube&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploy to Test System
&lt;/h1&gt;

&lt;p&gt;First off: yes, you need a &lt;strong&gt;test environment&lt;/strong&gt;. If your legacy project doesn’t have one, make sure you get one!💪 You can figure out the dependencies from the productive environment. Installation of &lt;strong&gt;third party software&lt;/strong&gt; like the runtime environment will be easy, however installing (mock versions of) the &lt;strong&gt;external systems&lt;/strong&gt; might be trickier.&lt;/p&gt;

&lt;p&gt;Anyways, the specific legacy project I worked on used Ant scripts to deploy the &lt;a href="http://maven.apache.org/plugins/maven-assembly-plugin/" rel="noopener noreferrer"&gt;distributable Java archive&lt;/a&gt; on the test system. What the Ant script basically did was take the tarball, copy it to the test system machine, inflate the package, stop the old application, and start the new one. The command for starting the application was a Java command including all kinds of important parameters like the &lt;a href="https://en.wikipedia.org/wiki/Java_virtual_machine" rel="noopener noreferrer"&gt;JVM&lt;/a&gt; version, Maven configuration file, the log file location and so on. As it turned out, it was pretty simple to automate this deployment: just use some CD tool like Jenkins and run the Ant script. There were still some bits to get right, like adding additional support Jars to the class path of the Ant command, but I figured that out too.&lt;/p&gt;

&lt;p&gt;If you ever must work with a legacy app, your technology stack might be different from mine, but the basic concept of &lt;strong&gt;bringing your app to the test system and running it&lt;/strong&gt; there remains the same.&lt;/p&gt;

&lt;h1&gt;
  
  
  End-to-End Tests
&lt;/h1&gt;

&lt;p&gt;Anyways, now I had automated things far enough so I could just hit a button to turn my source code into a running application on the test system. Now the last step was to automatically run end-to-end tests. For my legacy projects, I was lucky to have a plethora of existing E2E tests. My specific project used Java &lt;a href="http://fitnesse.org/" rel="noopener noreferrer"&gt;FitNesse&lt;/a&gt; tests. Since Jenkins offers a FitNesse plugin to run such tests, my job was straight forward.&lt;/p&gt;

&lt;p&gt;Now what do you do if you have no automated E2E tests? Well the most basic thing you can do is perform a &lt;strong&gt;health check&lt;/strong&gt;. Every component should have an HTTP health endpoint which will tell whether the app was started properly and if all external systems can be connected to like the database or queues. It’s even better though to perform &lt;strong&gt;functional tests&lt;/strong&gt;. If your app has a &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer" rel="noopener noreferrer"&gt;REST&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/SOAP" rel="noopener noreferrer"&gt;SOAP&lt;/a&gt; interface, you can use it to perform more advanced queries like read/write/update operations. Anyways, the important part is to program out these tests, so you don’t have to manually fire requests via &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; or &lt;a href="https://www.soapui.org/" rel="noopener noreferrer"&gt;SOAP UI&lt;/a&gt;. Moreover, if you're starting from scratch with new E2E tests, there are many modern and powerful frameworks out there, like &lt;a href="https://cucumber.io/" rel="noopener noreferrer"&gt;Cucumber&lt;/a&gt; and &lt;a href="https://gauge.org/" rel="noopener noreferrer"&gt;Gauge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Remember to pay attention to external systems. Since you are performing end-to-end tests, you want to make sure all &lt;strong&gt;surrounding systems&lt;/strong&gt; are present on your test system. Most often, engineers will create &lt;strong&gt;mocks&lt;/strong&gt; for these systems with the most important functionality replicated, or you can ask the maintainers of those externals systems if they already have a mock.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Final CI/CD Pipeline
&lt;/h1&gt;

&lt;p&gt;Here’s a snapshot of the final result, the Jenkins pipeline for continuous integration and delivery:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm27nky7w7arnpz9k2j3q.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm27nky7w7arnpz9k2j3q.PNG" alt="Jenkins pipeline" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that I hadn't changed any line in the old source code of the legacy app, yet I had made the maintenance so much more fun and easy.🎉🥂&lt;/p&gt;

&lt;p&gt;If you ever work on a legacy project yourself, I hope this article will give you some helpful information. Cleaning up legacy code will mostly be tough, plus the customer will probably not want to pay for it. Instead, what I suggest is to first &lt;strong&gt;focus on everything surrounding your code base&lt;/strong&gt;. With a &lt;strong&gt;CI/CD pipeline&lt;/strong&gt; in place, you will be much more motivated to start on a change request, since you can just hit one button which will verify your change all the way from compilation to packaging, deployment and E2E testing.&lt;/p&gt;

&lt;p&gt;Happy coding💻😃🔥&lt;/p&gt;

&lt;p&gt;Credits: Title image from &lt;a href="https://unsplash.com/@rickpsd" rel="noopener noreferrer"&gt;Unsplashed&lt;/a&gt;&lt;br&gt;
This post was inspired by an article from &lt;a href="https://www.freecodecamp.org/news/few-thoughts-on-legacy-hell-e229f76529e0/" rel="noopener noreferrer"&gt;Felipe Lopes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>legacycode</category>
      <category>java</category>
      <category>devops</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Log Capturing App with MongoDB + Spring Boot + Swagger UI</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 14 Sep 2020 11:56:22 +0000</pubDate>
      <link>https://dev.to/pmgysel/log-capturing-app-with-mongodb-spring-boot-swagger-ui-7op</link>
      <guid>https://dev.to/pmgysel/log-capturing-app-with-mongodb-spring-boot-swagger-ui-7op</guid>
      <description>&lt;p&gt;In this story, we will look at a &lt;strong&gt;log capturing app&lt;/strong&gt; using the following technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MongoDB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java + Spring Boot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swagger UI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This demo application showcases the ability of &lt;strong&gt;MongoDB&lt;/strong&gt; to store &lt;strong&gt;data without schema&lt;/strong&gt;. All log entries can have arbitrary fields and we can search logs via those arbitrary fields. To make the app easy to test, we’ll visualize its REST API via Swagger UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiorirpm01h0yzpqez9s6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiorirpm01h0yzpqez9s6.jpeg" alt="Oeschinensee" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Challenge of Schemaless Data
&lt;/h1&gt;

&lt;p&gt;In this story we’ll build an app which captures log data from 3rd party apps. The main challenge here: &lt;strong&gt;we don’t know how the log data from these 3rd party apps looks like&lt;/strong&gt;. Still, we want to store the data in a compact format, plus we want to support queries for this log data.&lt;/p&gt;

&lt;p&gt;Let’s look at a concrete example. Here’s two sample logs we want to store, in JSON format:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3yshm2ap3ewfucram50y.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3yshm2ap3ewfucram50y.PNG" alt="Sample Log Entries" width="592" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have one microservice &lt;code&gt;PAYMENT&lt;/code&gt; which creates logs during a payment process. On the right hand, we have a log from another app called &lt;code&gt;LOGIN&lt;/code&gt;. Some of the log fields are common like &lt;code&gt;severity&lt;/code&gt;, but some are unique to an app like &lt;code&gt;creditCardProvider&lt;/code&gt; which only exists in the PAYMENT app.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SQL Approach
&lt;/h2&gt;

&lt;p&gt;If we wanted to store this data in an &lt;strong&gt;SQL store&lt;/strong&gt;, we’d have a hard time to figure out a neat solution. Either we’d create a huge table which has a column for every log field we ever see. But this would result in many null entries and we would waste storage. Another solution is to store all data in JSON format, so you’d only have two rows in your table: the primary key and the JSON document. However, with this solution, you wouldn’t be able to search by JSON fields in a fast way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The NoSQL Approach
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NoSQL Document Stores&lt;/strong&gt; come to our rescue: they store data in JSON format without any fix schema. Basically, a document store contains JSON documents – and nothing else. Even the ID of a given document is contained in the JSON itself.&lt;/p&gt;

&lt;p&gt;Now, we can do really fast querying by JSON field, so you can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.logEvents.find&lt;span class="o"&gt;({&lt;/span&gt;_appType:&lt;span class="s2"&gt;"PAYMENT"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This would return the first log above. More interestingly, you can perform the following query:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.logEvents.find&lt;span class="o"&gt;({&lt;/span&gt;creditCardProvider:&lt;span class="s2"&gt;"VISA"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The document store is robust to the fact that not every log contains the field &lt;code&gt;creditCardProver&lt;/code&gt;!&lt;/p&gt;
&lt;h1&gt;
  
  
  Implement the Log Capturing App
&lt;/h1&gt;

&lt;p&gt;Enough talk - let’s get started implementing our app!&lt;/p&gt;
&lt;h1&gt;
  
  
  MongoCollection Configuration
&lt;/h1&gt;

&lt;p&gt;We use &lt;a href="https://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html" rel="noopener noreferrer"&gt;MongoCollection&lt;/a&gt; from the official &lt;a href="https://mongodb.github.io/mongo-java-driver/4.0/apidocs/" rel="noopener noreferrer"&gt;MongoDB Java Driver&lt;/a&gt; for DB access. Let’s go ahead and create a Bean with a properly configured MongoCollection:&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="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MongoConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Bean&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;MongoCollection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getMongoCollection&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;MongoClient&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MongoClients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;MongoDatabase&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mydb"&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;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCollection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"logEvents"&lt;/span&gt;&lt;span class="o"&gt;);&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;h1&gt;
  
  
  MongoDB Queries
&lt;/h1&gt;

&lt;p&gt;Let’s use the above declared Bean to search entries in the MongoDB by &lt;code&gt;id&lt;/code&gt;:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MongoDbService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;MongoCollection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;collection&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;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;))).&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;);&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;Using the &lt;code&gt;@Autowired&lt;/code&gt; annotation, we can pull in our Bean of type &lt;code&gt;MongoCollection&lt;/code&gt;. This class offers many query capabilities like searching by id, by key-value pair, and even more complex queries like greater-than etc. On my &lt;a href="https://github.com/pmgysel/mongodb-logging-app/" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;, you can see other query samples.&lt;/p&gt;

&lt;p&gt;One more note: all DB data is represented as &lt;a href="https://mongodb.github.io/mongo-java-driver/4.0/bson/documents/" rel="noopener noreferrer"&gt;Documents&lt;/a&gt;, which are described in the official documentation as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;Document&lt;/code&gt; class can represent dynamically structured documents of any complexity ... &lt;code&gt;Document&lt;/code&gt; implements Map&amp;lt;String, Object&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Java Date Model
&lt;/h1&gt;

&lt;p&gt;Inside our logging app, we don’t want to use Documents, but use a custom POJO instead:&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.Data&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LogEvent&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logEvent&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;We represent each log entry as a map with &lt;code&gt;String&lt;/code&gt; keys and values.&lt;/p&gt;

&lt;p&gt;Side note: the code snippet above uses &lt;a href="https://projectlombok.org/" rel="noopener noreferrer"&gt;Lombok&lt;/a&gt; which offers a neat way to create setter, getters, and constructors.&lt;/p&gt;
&lt;h1&gt;
  
  
  Document to LogEvent Mapper
&lt;/h1&gt;

&lt;p&gt;Our DB layer represents logs as &lt;code&gt;Document&lt;/code&gt;, but our service layer uses &lt;code&gt;LogEvent&lt;/code&gt;. Therefore, we need a mapper method:&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;LogEvent&lt;/span&gt; &lt;span class="nf"&gt;toLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LogEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&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;h1&gt;
  
  
  REST Controller
&lt;/h1&gt;

&lt;p&gt;Now it’s time to create the controller layer. We’ll use REST Controllers, which can be nicely created using Spring Boot’s &lt;code&gt;@RequestMapping&lt;/code&gt; annotation:&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="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/log/{id}"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LogEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getLogById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nd"&gt;@PathVariable&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;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&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;mongoDbService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;documentToLogMapper:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toLog&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;ResponseEntity:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&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;Everything we’ve coded so far comes together now!😎 So let’s go through the above code snippet step by step! First, our REST controller will serve HTTP GET requests to the URI "api/log/{id}", &lt;code&gt;id&lt;/code&gt; is the identifier of the log event. Second, the REST call will return a &lt;code&gt;LogEvent&lt;/code&gt; in JSON format. Third, we use functional programming in the method body. We start with the DB query, pass the result to our mapper, and finally check if everything went fine – and if not: return a 404 NOT_FOUND result.&lt;/p&gt;
&lt;h1&gt;
  
  
  Spring Boot Service
&lt;/h1&gt;

&lt;p&gt;Only one thing is missing to make our app executable:&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="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LogCaptureApp&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LogCaptureApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;();&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;That’s it, that’s all necessary code😊 Now your logging app can serve REST requests to read logs!&lt;/p&gt;
&lt;h1&gt;
  
  
  Swagger UI Documentation
&lt;/h1&gt;

&lt;p&gt;One more thing – let’s add a simple GUI to our log capturing app. We use &lt;a href="https://swagger.io/tools/swagger-ui/" rel="noopener noreferrer"&gt;Swagger UI&lt;/a&gt; for this purpose. Swagger UI allows to visualize your API without any further hustle. All you need is configure Swagger:&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="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableSwagger2&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SwaggerUIConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Bean&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Docket&lt;/span&gt; &lt;span class="nf"&gt;apiDocu&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Docket&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SWAGGER_2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apiInfo&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestHandlerSelectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basePackage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.example.controller"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PathSelectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ApiInfo&lt;/span&gt; &lt;span class="nf"&gt;apiInfo&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ApiInfoBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Log capturing app with MongoDB + SpringBoot"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&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;h1&gt;
  
  
  Run the App
&lt;/h1&gt;

&lt;p&gt;The complete code can be found on Github:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pmgysel" rel="noopener noreferrer"&gt;
        pmgysel
      &lt;/a&gt; / &lt;a href="https://github.com/pmgysel/mongodb-logging-app" rel="noopener noreferrer"&gt;
        mongodb-logging-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo app for MongoDB: manage log events of varying schema type
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;My Github repo contains more functionality than what we saw in this story, like searching log events by date range and storing log events from JSON data.&lt;/p&gt;

&lt;p&gt;So, if you have implemented the log app as you read through this story, go ahead and run it now. If not, no problem, you can use my fully working example from Github.&lt;/p&gt;

&lt;p&gt;Also, make sure you have a MongoDB Server running locally on the standard port. Then, compile and run the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/pmgysel/mongodb-logging-app.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;mongodb-logging-app
&lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean package
&lt;span class="nv"&gt;$ &lt;/span&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/mongodb-logging-app-0.0.1-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to the Swagger UI page in your favorite web browser: &lt;a href="http://localhost:8080/swagger-ui.html" rel="noopener noreferrer"&gt;http://localhost:8080/swagger-ui.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ncnolclmjbm6na1d4ob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ncnolclmjbm6na1d4ob.png" alt="Swagger UI REST API" width="677" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use the log capturing app as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;createLogRadom&lt;/code&gt;: Create random log entries to get some data into the DB&lt;/li&gt;
&lt;li&gt;Alternatively, create arbitrary log entries using the &lt;code&gt;createLog&lt;/code&gt; endpoint. Swagger UI will show sample request to make your life easy 😊&lt;/li&gt;
&lt;li&gt;Now search for logs by key-value pair (&lt;code&gt;getLogByOneField&lt;/code&gt;) or via date range (&lt;code&gt;getLogByDateRange&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Sample search:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0faw0kihweoii8o6jixq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0faw0kihweoii8o6jixq.PNG" alt="Search Logs by Field" width="561" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So, in this story, we built a fully working log capturing app in Java. Since our requirements were to support flexible log entries, we chose MongoDB as database solution.&lt;/p&gt;

&lt;p&gt;This scenario is very well suited to NoSQL Document Stores. Note that every application calls for another database – if your data has a fix schema, you might be better off with a traditional SQL store.&lt;/p&gt;

&lt;p&gt;Feel free to drop a comment with your ideas! Also, like ❤️ this story if it was helpful for you!&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>swagger</category>
      <category>springboot</category>
      <category>java</category>
    </item>
    <item>
      <title>MongoDB CRUD Queries from Java and Shell</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 31 Aug 2020 13:44:56 +0000</pubDate>
      <link>https://dev.to/pmgysel/mongodb-crud-queries-from-java-and-shell-1gmo</link>
      <guid>https://dev.to/pmgysel/mongodb-crud-queries-from-java-and-shell-1gmo</guid>
      <description>&lt;p&gt;Liquid syntax error: Tag '{% &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%}' was not properly terminated with regexp: /\%\}/&lt;/span&gt;&lt;/p&gt;
</description>
      <category>mongodb</category>
      <category>java</category>
      <category>springboot</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Introduction to MongoDB and Document Databases</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Thu, 27 Aug 2020 13:08:36 +0000</pubDate>
      <link>https://dev.to/pmgysel/introduction-to-mongodb-and-document-databases-462l</link>
      <guid>https://dev.to/pmgysel/introduction-to-mongodb-and-document-databases-462l</guid>
      <description>&lt;p&gt;This tutorial teaches you the &lt;strong&gt;basics of NoSQL Document Databases&lt;/strong&gt;. To keep things practical, we’ll also look at a concrete implementation, namely &lt;strong&gt;MongoDB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, we’ll start with the &lt;strong&gt;data model&lt;/strong&gt; in document databases and compare it to the SQL data model. Second, we dive into the characteristics of MongoDB, like: &lt;strong&gt;queries&lt;/strong&gt;, &lt;strong&gt;data replication&lt;/strong&gt;, &lt;strong&gt;sharding&lt;/strong&gt;, and &lt;strong&gt;consistency&lt;/strong&gt;. We’ll wrap things up with some &lt;strong&gt;real world uses cases&lt;/strong&gt; well suited for MongoDB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frld1fbhno2u5n54xsqy9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frld1fbhno2u5n54xsqy9.jpeg" alt="Oeschinensee" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Data Model
&lt;/h1&gt;

&lt;p&gt;The fundamental difference between SQL and NoSQL is how the data gets stored. Relational databases are like &lt;strong&gt;Excel tables with rows and columns&lt;/strong&gt;. This way of storing data means each row has the exact same fields. In contrast, NoSQL allows for more &lt;strong&gt;flexibility&lt;/strong&gt; in what you store. It’s easier to persist arrays, fields of unknown length, or add new data fields. Let’s look at an example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UML data model&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkssdciyswxqd6d6ajjfd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkssdciyswxqd6d6ajjfd.PNG" alt="UML data model" width="379" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above you see the data model for a simple online store: we store &lt;strong&gt;customers&lt;/strong&gt; and their &lt;strong&gt;orders&lt;/strong&gt;. A given customer can have multiple orders, and each order is associated with a &lt;strong&gt;delivery address&lt;/strong&gt; and all &lt;strong&gt;items purchased&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL tables&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhiwyxyvmnyj078qrgr65.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhiwyxyvmnyj078qrgr65.PNG" alt="SQL tables" width="637" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In SQL, a convenient way for storing this data is by having 4 tables (see graph above). We would connect the orders to the customer and the items through &lt;strong&gt;foreign keys&lt;/strong&gt;. In order to fetch a given order, you’d perform a join over the &lt;code&gt;Order&lt;/code&gt;, &lt;code&gt;Address&lt;/code&gt; and &lt;code&gt;Item&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Let's switch from the relational storage model to the non-relational one. In a &lt;strong&gt;document store&lt;/strong&gt;, we store all data in so called &lt;strong&gt;documents&lt;/strong&gt; (either in &lt;strong&gt;JSON&lt;/strong&gt;, &lt;strong&gt;XML&lt;/strong&gt; or &lt;strong&gt;BSON&lt;/strong&gt; format).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NoSQL document&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;orders&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"orderDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-08-22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customerId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Philipp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lastName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gysel"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"street"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Main ln"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bern"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"itemId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NoSQL Distilled"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code snippet uses 1 collection to store all data (as opposed to 4 tables in SQL). Each document in the collection &lt;code&gt;orders&lt;/code&gt; contains the delivery address and all items. Moreover, the customer data is also present in each &lt;code&gt;order&lt;/code&gt;. Note that we leverage a powerful feature here: different orders will have &lt;strong&gt;varying lengths&lt;/strong&gt;, since the &lt;code&gt;items&lt;/code&gt; element is an array of arbitrary size.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to Store and Manipulate Data
&lt;/h1&gt;

&lt;p&gt;In SQL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Arrays&lt;/strong&gt;: We can’t store arrays. Thus, we need one table row per order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normalization&lt;/strong&gt;: Data is normalized. There’s no data duplication. In case the customer wants to change his/her name in the online store, we just need to update the customer name in one place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In NoSQL document store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arrays are supported&lt;/strong&gt;: We can store all items of a given order together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data duplication&lt;/strong&gt;: Each order has the customer data. Now if a customer changes name, we have to perform this change in each &lt;code&gt;order&lt;/code&gt; of this customer, unfortunately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregation&lt;/strong&gt;: In document databases and NoSQL in general, we use aggregates, which contain a mix of data. We typically draw the aggregate boundaries according to how the application accesses the data. In our case, &lt;code&gt;orders&lt;/code&gt; contains more than just the order itself, which makes sense since the application has to read all data anyways.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not optimized for transactions&lt;/strong&gt;: Newer NoSQL versions do offer support for transactions, but they are not primarily designed for distributed ACID behavior. For most use cases though, this is not a problem, especially when all logically connected data lives in the same aggregate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4evetwwt0bayadqj8oo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4evetwwt0bayadqj8oo.PNG" alt="MongoDB" width="360" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  MongoDB
&lt;/h1&gt;

&lt;p&gt;In order to make things more tangible, let’s look at a concrete implementation! In the next few sections we cover the basics of MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Queries
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; is a document store which persists a key-value map, where each value is a JSON document of varying schema. As a case in point, a collection can contain the following two documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Philipp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"lastName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gysel"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"lastName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Smith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;a href="https://docs.mongodb.com/manual/mongo/" rel="noopener noreferrer"&gt;MongoDB Shell&lt;/a&gt;, we could query for a customer with first name “Philipp” as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.customers.find&lt;span class="o"&gt;({&lt;/span&gt;firstName:&lt;span class="s2"&gt;"Philipp"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... which would return us the first customer in JSON format.&lt;/p&gt;

&lt;p&gt;MongoDB offers a variety of query features for CRUD operations, projection, sorting etc. For more on queries, watch out for my next post in this series.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Naming Convention
&lt;/h2&gt;

&lt;p&gt;With MongoDB, there are no rows and columns, instead, we deal with documents and JSON elements:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Oracle&lt;/th&gt;
&lt;th&gt;MongoDB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;table&lt;/td&gt;
&lt;td&gt;collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;row&lt;/td&gt;
&lt;td&gt;document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rowid&lt;/td&gt;
&lt;td&gt;_id&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The primary key of a MongoDB document is always called &lt;code&gt;_id&lt;/code&gt; and naturally you can do queries by primary key.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB - No Schema
&lt;/h2&gt;

&lt;p&gt;MongoDB has no predefined schema. If you look again at the documents above, you can see that “John” has an &lt;code&gt;age&lt;/code&gt; element, which is missing from “Philipp”. Moreover, you can even change the schema of an existing document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.customers.updateOne&lt;span class="o"&gt;({&lt;/span&gt;_id:1&lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$set&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;city:&lt;span class="s2"&gt;"Bern"&lt;/span&gt;&lt;span class="o"&gt;}})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... this will add a city field to the existing document.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Replica Sets
&lt;/h2&gt;

&lt;p&gt;For &lt;strong&gt;read scalability&lt;/strong&gt;, MongoDB supports &lt;a href="https://docs.mongodb.com/manual/replication/" rel="noopener noreferrer"&gt;replica sets&lt;/a&gt;. A replica set contains one &lt;strong&gt;master and multiple slaves&lt;/strong&gt;; each node contains &lt;strong&gt;all data&lt;/strong&gt;. MongoDB allows to add new nodes to a running database when more data traffic needs to be supported. By default, all requests from the application go to the master node.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu1ahv4xu46o5d8sxguhj.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu1ahv4xu46o5d8sxguhj.PNG" alt="Replica Set" width="703" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, the application performs a write operation to the database, which is sent to the master and then passed on to all slave nodes.&lt;/p&gt;

&lt;p&gt;Read scalability is achieved through the fact that each slave contains all data. All you need to do is specify that reads from slaves are ok:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Mongo mongo &lt;span class="o"&gt;=&lt;/span&gt; new Mongo&lt;span class="o"&gt;(&lt;/span&gt;“localhost:270127”&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
Mongo.slaveOk&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given 3 slaves, you now have 4 times higher read throughput!&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Sharding
&lt;/h2&gt;

&lt;p&gt;Read scalability: check✔️. What about &lt;strong&gt;write scalability&lt;/strong&gt;❓ Replica sets won’t help us here, since all writes need to go through the master. That’s where &lt;a href="https://docs.mongodb.com/manual/sharding/" rel="noopener noreferrer"&gt;sharding&lt;/a&gt; comes in: With sharding, we split our data into partitions, and each partition is stored in a different shard. By using some simple rule like applying Modulo on the primary key of a document, each document is assigned to a shard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmhze0rqgyh4monwr2mg9.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmhze0rqgyh4monwr2mg9.PNG" alt="Sharding" width="704" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the &lt;strong&gt;writes get distributed over different nodes&lt;/strong&gt;. This can be especially helpful for write heavy applications like log capturing (e.g. &lt;a href="https://newrelic.com/" rel="noopener noreferrer"&gt;NewRelic&lt;/a&gt;). Also, MongoDB makes sharding easy from an application perspective and &lt;strong&gt;performs all complicated work automatically in the background&lt;/strong&gt;, like balancing shards or figuring out which document lives on which shard.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Consistency
&lt;/h2&gt;

&lt;p&gt;As soon as a MongoDB cluster uses replication, special care needs to be taken for consistency. Hypothetically, an application can persist a document, then query for it, but the DB will throw a "not found" error. The reason lies in the topology of the cluster: In a master-slave configuration, a write doesn’t reach each slave immediately, and it might take a sub-second before all slaves receive the update. While SQL offers immediate consistency, MongoDB guarantees &lt;strong&gt;only eventual consistency&lt;/strong&gt; – one is guaranteed to have all updates on all nodes in the end.&lt;/p&gt;

&lt;p&gt;For better control, MongoDB allows to specify a &lt;code&gt;writeConcern&lt;/code&gt; for each insert and update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.companies.insert&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;{&lt;/span&gt;_id: 1, firstName: &lt;span class="s2"&gt;"Philipp"&lt;/span&gt;, lastName: &lt;span class="s2"&gt;"Gysel"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,
   &lt;span class="o"&gt;{&lt;/span&gt;writeConcern: &lt;span class="o"&gt;{&lt;/span&gt;w: &lt;span class="s2"&gt;"majority"&lt;/span&gt;, wtimeout: 5000&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;Here, we mandate that an insert is propagated to the majority of nodes and the DB call is blocked until this happens or the timeout of 5 seconds is reached. Beware though: consistency comes at a price (latency), so think carefully about your specific use cases and how consistent your data needs to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Transactions
&lt;/h2&gt;

&lt;p&gt;Since MongoDB 4.0, multi-document &lt;a href="https://docs.mongodb.com/master/core/transactions/" rel="noopener noreferrer"&gt;transactions are supported&lt;/a&gt;. Thanks to this feature, documents living in different collections can be updated in an atomic fashion. Beware though, as the official &lt;a href="https://docs.mongodb.com/master/core/transactions/#transactions-and-atomicity" rel="noopener noreferrer"&gt;MongoDB documentation&lt;/a&gt; states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a rule of thumb, you should try to &lt;strong&gt;pack all interconnected data into one document&lt;/strong&gt;, if possible, so that you don’t need to worry about transaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB: Suitable Business Cases
&lt;/h2&gt;

&lt;p&gt;MongoDB isn’t a hammer to be used for every nail. Make sure you analyze the business and non-functional requirements of your application, and then search for a matching database solution. While MongoDB has many advantages (scalability, simple query language, plus it’s open source), there are also disadvantages like slow transactions compared to SQL.&lt;/p&gt;

&lt;p&gt;So here are some use cases well suited for MongoDB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logging applications&lt;/strong&gt;: Apps which track huge logs are well suited for MongoDB. Immediate consistency is not necessary, as a new log doesn’t have to be available right away. However, performance is really important, especially when many applications with verbose logs are involved. Big write volumes can be nicely handled through sharding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blogs / social media&lt;/strong&gt;: For a Twitter-like app, each entry has a different format. Some contain text, some images, some videos, but everything is optional. This matches well to documents which can contain arbitrary elements. Also, if the app wants to support new types of blogs in the future – no problem, no database changes are required, you can simply add a new field to new documents. What's more, immediate consistency isn’t important, it’s fine to see a particular entry with a delay of 1 second.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope this helped you learn more about MongoDB. Needless to say, that the best way to learn a technology is by actually using it😉.&lt;/p&gt;

&lt;p&gt;Add a ❤️ if you liked the MongoDB tutorial. Leave a comment if you have any questions / feedback.&lt;/p&gt;

&lt;p&gt;For more on MongoDB, checkout my &lt;a href="https://dev.to/pmgysel/mongodb-crud-queries-from-java-and-shell-1gmo"&gt;next post in this series&lt;/a&gt; which covers MongoDB &lt;strong&gt;queries&lt;/strong&gt; from &lt;strong&gt;MongoDB Shell&lt;/strong&gt; and &lt;strong&gt;Java&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>mongodb</category>
      <category>nosql</category>
    </item>
    <item>
      <title>NoSQL: Introduction and Concepts</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 24 Aug 2020 12:22:37 +0000</pubDate>
      <link>https://dev.to/pmgysel/nosql-introduction-and-concepts-15a7</link>
      <guid>https://dev.to/pmgysel/nosql-introduction-and-concepts-15a7</guid>
      <description>&lt;p&gt;So you know SQL and want to get started with NoSQL? This starter tutorial will be perfect for you 😊.&lt;/p&gt;

&lt;p&gt;What we'll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comparison&lt;/strong&gt;: The strengths of SQL and NoSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 NoSQL families&lt;/strong&gt;: What NoSQL types exist?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selling points for NoSQL&lt;/strong&gt;: Dive deeper into NoSQL advantages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl1vpdmmncubcn3atyd5o.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl1vpdmmncubcn3atyd5o.jpeg" alt="Oeschinensee" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  SQL vs. NoSQL
&lt;/h1&gt;

&lt;p&gt;Most developers know SQL, but NoSQL has been in its shadow for a long time. In the past decade though, more and more business cases emerged that can't be handled easily by SQL solutions. Let’s go ahead and compare the two database concepts:&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of NoSQL
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strength&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F24z8cykd7l9wubmoww8f.jpg" alt="Alt Text" width="38" height="38"&gt; &lt;strong&gt;Scalability&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;NoSQL solutions are at home in the cloud; thus scalability and big data applications are nicely supported.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F85h5pndij5yhfn499rhn.jpg" alt="Alt Text" width="47" height="39"&gt; &lt;strong&gt;Flexibility&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;NoSQL can deal with changing schemas without any explicit update scripts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjvxmnxbomk101zo30uk3.png" alt="Alt Text" width="38" height="38"&gt; &lt;strong&gt;Cost&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Many NoSQL databases are open source, there are no expensive licensing terms. What’s more: NoSQL runs well on commodity machines which again saves costs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjh4z6pqj0crysm0kag00.png" alt="Alt Text" width="30" height="31"&gt; &lt;strong&gt;Replication&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Most NoSQL solutions have built-in support for sharding and replication sets. This allows to split huge amounts of data across many servers and at the same time replicating the data, thus creating higher availability.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Advantages of SQL
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strength&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbrgpxdvconyrlr036bw3.png" alt="Alt Text" width="35" height="38"&gt; &lt;strong&gt;Transactions&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Querying and updating data across multiple tables in an atomic fashion is better supported in SQL.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F82ymidpht5z4h2hsbtw9.png" alt="Alt Text" width="59" height="59"&gt; &lt;strong&gt;Consistency&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;In SQL, updates are immediately visible to all clients. NoSQL uses eventual consistency – meaning the data will be uniform, but it might take half a second until all nodes hold an update.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fijj422ey5hs6db3y4szx.png" alt="Alt Text" width="39" height="38"&gt; &lt;strong&gt;Support and maturity&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Most SQL databases have been around for a while and are thus very stable. Moreover, if you choose an enterprise solution like Oracle DB, you get professional support.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4pawke978abn3ae6byx2.png" alt="Alt Text" width="38" height="38"&gt; &lt;strong&gt;Data normalization&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;In SQL, we store all data items just once – no repetitions necessary. This allows for simple updates. On the other hand, updates in NoSQL can require writes to multiple aggregates.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  NoSQL families
&lt;/h1&gt;

&lt;p&gt;One of the confusing things about non-relational databases is the fact that many varying database concepts belong to this family. All those families share one property though: data is NOT arranged into tables with fixed column sizes. For example, in Key-Value and Document Stores, each row can have a different length and format.&lt;br&gt;
Here are the 4 families:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8kwa9y6zq11empj7ovzo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8kwa9y6zq11empj7ovzo.PNG" alt="NoSQL families" width="800" height="172"&gt;&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;Database&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Key-Value Store&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://aws.amazon.com/dynamodb/" rel="noopener noreferrer"&gt;Dynamo&lt;/a&gt;, &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;A key-value map where the value is of arbitrary data type like String, Array or JSON.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Document Store&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt;, &lt;a href="https://www.couchbase.com/" rel="noopener noreferrer"&gt;Couchbase&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Each data entry is a document (e.g. as JSON) of varying schema. It's possible to query by JSON elements.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Column-Family Store&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://cassandra.apache.org/" rel="noopener noreferrer"&gt;Cassandra&lt;/a&gt;, &lt;a href="https://hbase.apache.org/" rel="noopener noreferrer"&gt;HBase&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Store data in column families. Great for data compression and aggregate queries (e.g. SUM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Graph Store&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://neo4j.com/" rel="noopener noreferrer"&gt;Neo4J&lt;/a&gt;, &lt;a href="https://giraph.apache.org/" rel="noopener noreferrer"&gt;Giraph&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Do computations on graphs, where the majority of data comes from edges rather than nodes.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you want to get to know NoSQL better, a great starting point is the learn and use a concrete store. For me, when I started to learn about non-relational databases, I simply started with MongoDB and tried out some queries / inserts etc. This helped me tremendously to grasp the concept of NoSQL.&lt;/p&gt;

&lt;h1&gt;
  
  
  Selling points for NoSQL
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The web era
&lt;/h2&gt;

&lt;p&gt;NoSQL emerged around 2000 when companies like Google and Amazon felt they needed an alternative to traditional SQL databases. The primary driver for NoSQL was the &lt;strong&gt;tremendous growth&lt;/strong&gt; of data volume as well as the &lt;strong&gt;frequent changes&lt;/strong&gt; in the data schema. Thus highly influential papers like &lt;a href="https://research.google/pubs/pub27898/" rel="noopener noreferrer"&gt;BigTable&lt;/a&gt; and &lt;a href="https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf" rel="noopener noreferrer"&gt;Dynamo&lt;/a&gt; were released which showed unprecedented ways for storing and managing big data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scalability
&lt;/h2&gt;

&lt;p&gt;While most SQL databases run on one server (with lots of RAM), NoSQL was designed from the start to run on &lt;strong&gt;clusters&lt;/strong&gt;. Thanks to this capability, a data pool can easily be increased if need be, by simply &lt;strong&gt;adding more nodes&lt;/strong&gt;. When you think about a company like Google, Amazon, Netflix or Facebook, you can easily imagine that their data wouldn’t even fit on 100 hard drives. Anyways, there’s an increasing number of businesses where &lt;strong&gt;huge data volumes&lt;/strong&gt; are common, like for example &lt;a href="https://newrelic.com/" rel="noopener noreferrer"&gt;NewRelic&lt;/a&gt; which stores log data from your applications and allows you to easily query and display that data. If you’ve already seen a large business application running in verbose logging mode, you know how hard it can be to browse through the log, so a Logging solution like the one from NewRelic can be really helpful. &lt;/p&gt;

&lt;h2&gt;
  
  
  Flexibility
&lt;/h2&gt;

&lt;p&gt;Another huge selling point for NoSQL are &lt;strong&gt;flexible schemas&lt;/strong&gt; – in fact, you don’t need any schema, you can start storing data right away. Now obviously, the application dealing with your database has to understand how to make sense of the bits and bytes in your data store. So implicitly, there will be some schema, it's simply not in your database. Nevertheless, having the ability to &lt;strong&gt;quickly change the structure of new data records&lt;/strong&gt; has tremendous advantages. For SQL, you’d first have to change your table schema – but what do you do with existing records? You might even have to create a data migration script and you obviously need an SQL script altering existing tables. In the non-relational world, all you do is change the logic in your application – and that’s it.&lt;/p&gt;

&lt;p&gt;As a case in point, lets consider a retail store, which stores product info in a NoSQL database. Once a new piece of information gets introduced – like the eco-friendliness of a given product – then you can simply add this information to newly introduced products, but you can leave old products as is. All you have to do is make sure your application can handle both data formats – products with and without eco-friendly-scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Availability
&lt;/h2&gt;

&lt;p&gt;With NoSQL, we use &lt;strong&gt;replication&lt;/strong&gt; of data to ensure high availability. While replication comes in different forms (master-slave, peer-to-peer), the result is the same: One node can become unavailable, but querying data will still work, as &lt;strong&gt;other nodes take over the traffic&lt;/strong&gt; in question. There are many ways how a data server can become unavailable – hard disk failure, temporary problems with the internet or a power outage – and while most of those happen only once a year or less frequently, there are a number of business cases where such downtimes are intolerable. Note though that SQL solutions can also offer high availability – with concepts like backup databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Low Cost
&lt;/h2&gt;

&lt;p&gt;In the NoSQL world, there are many &lt;strong&gt;open source solutions&lt;/strong&gt;, which one can simply install on his or her own cluster (MongoDB, Cassandra, CouchDB, Hypertable, Neo4J). So, when you choose a NoSQL open source solution, you are not at the mercy of a company’s &lt;strong&gt;licensing terms&lt;/strong&gt; which might change unfavorably over time. What’s more, non-relational solutions are the ideal candidate for &lt;strong&gt;commodity servers&lt;/strong&gt;. One can achieve really good throughput and availability without buying expensive high-end servers. For SQL, the game is different, here people often scale vertically, meaning an existing server is replaced by one with more RAM and faster CPU cores. This typically infers higher costs than scaling horizontally.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Bonus points if you're still reading this😊 So we've covered the most important general concepts of NoSQL.&lt;/p&gt;

&lt;p&gt;Note that this post has only scratched the surface of NoSQL. If you are like me an prefer more concrete examples – well I’m glad you asked, I’ll be posting a tutorial on Document Stores and MongoDB shortly!&lt;/p&gt;

&lt;p&gt;Also, if you're new to NoSQL and enjoy learning from books, I can highly recommend &lt;a href="https://martinfowler.com/books/nosql.html" rel="noopener noreferrer"&gt;NoSQL Distilled&lt;/a&gt; by Sadalage and Fowler.&lt;/p&gt;

&lt;p&gt;Finally, please remember to like ❤️ this article if you found it useful!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>nosql</category>
      <category>architecture</category>
    </item>
    <item>
      <title>From a Docker Image to a Deployment on OpenShift</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 03 Aug 2020 13:35:15 +0000</pubDate>
      <link>https://dev.to/pmgysel/from-a-docker-image-to-a-deployment-on-openshift-1oj1</link>
      <guid>https://dev.to/pmgysel/from-a-docker-image-to-a-deployment-on-openshift-1oj1</guid>
      <description>&lt;p&gt;In this tutorial, I’ll show you a working example for deploying a docker container on OpenShift V4. You can find all Kubernetes resources from this tutorial on my &lt;a href="https://github.com/pmgysel/cloud-stack_openshift-kubernetes-ressources" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;. If you only have some basic knowledge of Docker and Kubernetes and don’t know OpenShift yet – don’t worry, this tutorial will be perfect for you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fecgr14ylpakotcqgfnmu.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fecgr14ylpakotcqgfnmu.JPG" alt="Niderhorn" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Quick History
&lt;/h1&gt;

&lt;h2&gt;
  
  
  From Native Applications to Docker Containers to Kubernetes
&lt;/h2&gt;

&lt;p&gt;In the olden days, software companies deployed their applications on “bare metal”, meaning one physical computer hosted one application. Over time, things improved thanks to virtual machines, which allowed multiple isolated applications to run on the same physical server. In the last couple of years, a more light-weight virtualization solution became popular – docker containers. Once companies started to heavily use docker containers, their deployment landscape became pretty messy, and so orchestration tools like Kubernetes came to the rescue. Kubernetes allows to plan, perform, and manage the deployment of applications in the form of Docker containers and to make deployments reproduceable and easy to customize.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxfophynpn4v3bwmdbwm1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxfophynpn4v3bwmdbwm1.jpg" alt="Container mess" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From “Bare-metal” to “PaaS”
&lt;/h2&gt;

&lt;p&gt;Parallel to the development of new tools, the hosting landscape also changed significantly. While most companies were hosting their applications on machines in their basement a decade or two ago, more and more software development companies started to investigate letting third party companies host their applications. This greatly helped to separate the concerns of application development vs. application deployment and monitoring. Today there are many great cloud providers which take care of several important challenges like hardware scaling, geo redundancy, monitoring of running clusters and configuring security related components. Companies which offer a &lt;a href="https://en.wikipedia.org/wiki/Platform_as_a_service" rel="noopener noreferrer"&gt;Platform as a Service&lt;/a&gt; include AWS, Google Cloud, IBM Cloud, Microsoft Azure, and many more.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why OpenShift?
&lt;/h1&gt;

&lt;p&gt;OpenShift is the PaaS solution we’ll be discussing in this blog. It is developed by &lt;a href="https://www.redhat.com" rel="noopener noreferrer"&gt;Red Hat&lt;/a&gt; and builds on top of Docker and Kubernetes. OpenShift can be run on any cloud infrastructure, and many popular providers have an offering, including the aforementioned providers AWS, Google Cloud, IBM Cloud, and Microsoft Azure.&lt;/p&gt;

&lt;p&gt;So, what’s the advantage of using OpenShift over a Kubernetes cluster? Well OpenShift offers several additional features while also supporting all Kubernetes resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple to use&lt;/strong&gt;: Thanks to many preconfigured parameters and a nice GUI, OpenShift is fairly simple to learn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure by default&lt;/strong&gt;: OpenShift apps are secure by default. Security experts from Red Hat have put a lot of time and effort into making the platform resilient against attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Additional tools&lt;/strong&gt;: OpenShift offers additional tools compared to a simple Kubernetes cluster: Source-to-Image build, Kibana monitoring, OpenShift registry, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note though that some people might prefer pure Kubernetes cluster infrastructures, for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid vendor look-in&lt;/strong&gt;: OpenShift supports all Kubernetes objects, so by using only standard Kubernetes resources for the deployments, a future switch to another cloud provider is possible without extra effort. Unfortunately, there are some minor differences between OpenShift and Kubernetes, for example OpenShift’s Route resource (which doesn’t exist in Kubernetes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: There are many providers out there for both OpenShift and Kubernetes, so comparing the costs is a tricky endeavor. Generally speaking, you get more from an OpenShift platform, which is why this solution tends to cost slightly more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, OpenShift is a great solution that is getting adapted by many companies all over the world, so my guess is that it is a solution that will stay for quite some time. Without any further ado, let’s jump into the working example!&lt;/p&gt;

&lt;h1&gt;
  
  
  DIY OpenShift Example
&lt;/h1&gt;

&lt;p&gt;Alright, now it’s time to run your first app on OpenShift V4. All you need is an OpenShift account and the Kubernetes resources from the &lt;a href="https://github.com/pmgysel/cloud-stack_openshift-kubernetes-ressources" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Free OpenShift Account
&lt;/h2&gt;

&lt;p&gt;For experimental purposes, OpenShift offers a solution termed “OpenShift online” which can be used for free for 2 months. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F88rnbrnmyfw6wy0jadim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F88rnbrnmyfw6wy0jadim.png" alt="OpenShift online" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create Red Hat account: &lt;a href="https://www.redhat.com/" rel="noopener noreferrer"&gt;https://www.redhat.com/&lt;/a&gt; ‑&amp;gt; Login ‑&amp;gt; Register now&lt;/li&gt;
&lt;li&gt;Confirm email&lt;/li&gt;
&lt;li&gt;Start OpenShift online trial: &lt;a href="https://www.openshift.com/products/online/" rel="noopener noreferrer"&gt;https://www.openshift.com/products/online/&lt;/a&gt; ‑&amp;gt; Choose Starter plan and follow the instructions&lt;/li&gt;
&lt;li&gt;Login to OpenShift online web console: &lt;a href="https://manage.openshift.com/sign_in" rel="noopener noreferrer"&gt;https://manage.openshift.com/sign_in&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Create your first project: in “Administrator” view, go to Home ‑&amp;gt; Projects ‑&amp;gt; click Create Project&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy App on OpenShift (via web console)
&lt;/h2&gt;

&lt;p&gt;To deploy your first app, you’ll need two items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Docker image&lt;/li&gt;
&lt;li&gt;The Kubernetes resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for the Docker image: I have packaged a simple Java app into a Docker image and published it on &lt;a href="https://hub.docker.com/repository/docker/pmgysel/spring-boot-app" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;. The docker image is directly reference in the Kubernetes resources, so all you need to do is download the Kubernetes resources from my &lt;a href="https://github.com/pmgysel/cloud-stack_openshift-kubernetes-ressources" rel="noopener noreferrer"&gt;Gihub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s start with the deployment. Head over to the web console where you’ve already created an OpenShift project, then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In “Developer” view, go to “+Add” and select “YAML”&lt;/li&gt;
&lt;li&gt;Copy and paste all Kubernetes resources: &lt;code&gt;deployment.yaml&lt;/code&gt;, &lt;code&gt;service.yaml&lt;/code&gt; and &lt;code&gt;route.yaml&lt;/code&gt; (you’ll find the files on &lt;a href="https://github.com/pmgysel/cloud-stack_openshift-kubernetes-ressources" rel="noopener noreferrer"&gt;Github&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;That’s it! Your app is getting deployed on OpenShift. To check the status, go to “Administrator” view ‑&amp;gt; Workloads ‑&amp;gt; Pods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo7212jbk5f04ibd0n2ji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo7212jbk5f04ibd0n2ji.png" alt="Running pod" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see a Pod called “spring-boot-app-*” starting up. As soon as it is up and running, let’s test it like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In “Administrator” view, go to Networking ‑&amp;gt; Routes&lt;/li&gt;
&lt;li&gt;For “spring-boot-app-route”, select the “Location”: this is a public URL to access your running app.&lt;/li&gt;
&lt;li&gt;Append “/api/ping” to the URL – and you should see an answer from your app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0mcjyv25h2t1fvgeii7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0mcjyv25h2t1fvgeii7c.png" alt="Show pong" width="770" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That’s it folks 😊 You’ve got an application running on OpenShift!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy App on OpenShift (via CLI)
&lt;/h2&gt;

&lt;p&gt;In a real development project, you’ll want to automate as much work as possible. People typically use a CI/CD pipeline like Jenkins to compile new app versions, test them, build the docker image and deploy the app in the cloud. For this purpose, OpenShift offers the command line tool &lt;code&gt;oc&lt;/code&gt; – which allows to show the status of your running apps, alter deployment configurations and start new deployments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, you probably want to remove all existing resources on OpenShift. The simplest way to do so is just to remove the active OpenShift project and create a new one.&lt;/li&gt;
&lt;li&gt;Install the &lt;code&gt;oc&lt;/code&gt; CLI by following the instructions under “?” ‑&amp;gt; “Command Line Tools”&lt;/li&gt;
&lt;li&gt;Login to OpenShift via oc CLI by following the instructions “Copy Login Command” on the previous page.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;oc login &lt;span class="nt"&gt;--token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;… &lt;span class="nt"&gt;--server&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Make sure you’re in the correct OpenShift project
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;oc projects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Fetch the Kubernetes resources from Github
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/pmgysel/cloud-stack_openshift-kubernetes-ressources.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;cloud-stack_openshift-kubernetes-ressources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Upload Kubernetes resources
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;oc apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
&lt;span class="nv"&gt;$ &lt;/span&gt;oc apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml
&lt;span class="nv"&gt;$ &lt;/span&gt;oc apply &lt;span class="nt"&gt;-f&lt;/span&gt; route.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;That’s it folks 😊 You just performed your first OpenShift deployment via command line!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Our Kubernetes Resources
&lt;/h1&gt;

&lt;p&gt;You have created 3 Kubernetes resources on the OpenShift platform. Let’s quickly get an overview of how these 3 resources work together. This is a fairly simple primer on Kubernetes, so feel free to skip this part if you already have advanced knowledge in this technology.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxc4jvj8p23cs9wqc1bv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxc4jvj8p23cs9wqc1bv5.png" alt="Kubernetes resources" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;deployment.yaml&lt;/em&gt;: The Kubernetes Deployment specifies how your containers should be deployed, including the number of instances, the port to be exposed and the amount of RAM per Pod.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;service.yaml&lt;/em&gt;: A Kubernetes Service acts as entry point to running pods. You don’t need to worry about the exact number of running pods, how to distribute the load, how to detect ready pods and so on. The Service will do all the work for you.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;route.yaml&lt;/em&gt;: All Services and Pods are only accessible from within the OpenShift cluster. To publish your service to the outside world, you can use an OpenShift Route. Just a small hiccup here: Routes are an OpenShift only feature and don’t exist in Kubernetes. In pure Kubernetes, there’s an analog resource termed “Ingress”.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Bonus points if you’re still reading this 😊 So in this post, we learned about the advantages of OpenShift and ran a simple app on the OpenShift platform. I hope this was informative for you!&lt;/p&gt;

&lt;p&gt;Some more resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenShift has an official &lt;a href="https://www.openshift.com/learn/courses/getting-started/?hsLang=en-us" rel="noopener noreferrer"&gt;OpenShift tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Kubernetes resources: &lt;a href="https://docs.openshift.com/online/pro/dev_guide/deployments/how_deployments_work.html" rel="noopener noreferrer"&gt;Deployments&lt;/a&gt;, &lt;a href="https://docs.openshift.com/online/pro/architecture/core_concepts/pods_and_services.html#services" rel="noopener noreferrer"&gt;Services&lt;/a&gt;, and &lt;a href="https://docs.openshift.com/online/pro/dev_guide/routes.html" rel="noopener noreferrer"&gt;Routes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenShift’s &lt;code&gt;oc&lt;/code&gt; CLI is an extension to Kubernete’s kubectl. The OpenShift website has a &lt;a href="https://docs.openshift.com/online/pro/cli_reference/basic_cli_operations.html" rel="noopener noreferrer"&gt;docu on oc&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember to like ❤️ this blog if it was helpful to you and see you next time!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cloud</category>
      <category>openshift</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Learn Spring Boot by Annotations</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Mon, 11 May 2020 10:14:20 +0000</pubDate>
      <link>https://dev.to/pmgysel/learn-spring-boot-by-annotations-1h0i</link>
      <guid>https://dev.to/pmgysel/learn-spring-boot-by-annotations-1h0i</guid>
      <description>&lt;p&gt;This blog will teach you the &lt;strong&gt;basics of Spring Boot&lt;/strong&gt; by looking at the available &lt;strong&gt;annotations&lt;/strong&gt;. A lot of the magic in Spring Apps happens via annotations such as &lt;code&gt;@Bean&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt;, and &lt;code&gt;@Component&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjz27h9adqt0rbbzwpefh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjz27h9adqt0rbbzwpefh.jpg" alt="Blue Mountains" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why We Care about Spring Annotations
&lt;/h1&gt;

&lt;p&gt;Spring has some powerful concepts like dependency injection (DI) which is made possible thanks to Spring-managed components. Here, all Classes annotated with &lt;code&gt;@Component&lt;/code&gt; are candidates for DI and can be used by other Classes without explicit instantiation. Spring offers a feature called &lt;a href="https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html" rel="noopener noreferrer"&gt;Inversion of Control Container&lt;/a&gt; which will do all necessary injections in the background, all magic happens without any work from the developer😊 This is a great example for learning Spring by studying annotations: The Java code of a given Class may look completely normal, but when we consider this metadata, much richer functionality is possible (like DI). There are many of those annotations that significantly add functionality unique to Spring.&lt;/p&gt;

&lt;p&gt;I dare to argue that a &lt;strong&gt;great way of learning Spring is by understanding the most common annotations&lt;/strong&gt;. In the rest of this article, we will look at different annotations (from Spring as well as javax.persistence), describe their purpose, and show some code samples. I also created a Java Spring Boot app with all the described annotations included, so if you wanna look at a fully working example, checkout my &lt;a href="https://github.com/pmgysel/spring-boot-annotations" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Spring Annotations Overview
&lt;/h1&gt;

&lt;p&gt;First let’s get an overview of what I consider the most important Spring annotations. Let me state that my selection is aimed at people interested in &lt;strong&gt;RESTful webservices&lt;/strong&gt;. For other people, the optimal selection might vary slightly. Anyways, apart from Spring annotations, we’ll also cover metadata tags from the Javax Persistence API. The reason for this: we nearly always use a database in our backend, and this is a feature supported by Javax, not Spring, so I decided to include it here.&lt;/p&gt;

&lt;p&gt;Here's a list of annotations we'll cover:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffd8q3ywld0g0k8g18ui0.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffd8q3ywld0g0k8g18ui0.JPG" alt="List of annotations" width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the table above, there’s quite some annotations to cover in this blog, so I decided to put them into functional groups. Let’s get started with syntactic metadata used in the Main class:&lt;/p&gt;

&lt;h1&gt;
  
  
  Main Class Annotation
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@SpringBootApplication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thankfully, in a Spring app, our Main Method doesn’t have to do much: we don’t need to code up any logic to assemble our service components and boot it up. Instead, all we need is to annotate the Main class with @SpringBootApplication. This will mainly trigger two things: First, Spring Boot will apply the default configuration such as socket read timeout. Secondly, Spring will search for all Spring-managed components, e.g. Classes annotated with @RestController.&lt;/p&gt;

&lt;p&gt;Here’s how our Main class would look like:&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="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpringBootAnnotationsApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringBootAnnotationsApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&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;A fully working example can be found in my Github repo in SpringBootAnnotationsApplication.java.&lt;/p&gt;

&lt;h1&gt;
  
  
  REST Endpoint Annotations
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@RestController&lt;/li&gt;
&lt;li&gt;@RequestMapping&lt;/li&gt;
&lt;li&gt;@PathVariable&lt;/li&gt;
&lt;li&gt;@RequestBody&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Say our web service should be able to answer to several REST requests. To implement this, we just need a &lt;strong&gt;Class annotated with @RestController&lt;/strong&gt; which contains &lt;strong&gt;methods annotated with @RequestMapping&lt;/strong&gt;. Each such method represents one REST endpoint.&lt;/p&gt;

&lt;p&gt;When a REST request arrives, Spring will automatically search for the corresponding method, deserialize the incoming request, put all incoming data into our method parameters, and we’re ready to perform our own business logic. In the end, our result (a Java object) will get serialized by Spring and returned over HTTP. All we need to worry about is having the right footprint for our method, which should include the following: URI, URI path parameters, URI query parameter, HTTP request body, and HTTP answer body.&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="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PATCH&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/account/{accountId}"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AccountRJ&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;activateAccount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nd"&gt;@PathVariable&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;"accountId"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;startBalance&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// implement method ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s an example for a corresponding REST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PATCH https://www.../api/account/5
Request Body: "10"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our code snipped, the &lt;code&gt;accountId&lt;/code&gt; would be 5 and &lt;code&gt;startBalance&lt;/code&gt; would be 10. The REST answer should be an object of type &lt;code&gt;AccountRJ&lt;/code&gt;. To be more specific, the method return value should be of type &lt;code&gt;ResponseEntity&amp;lt;T&amp;gt;&lt;/code&gt;. This is a Spring class containing all HTTP reply data such as status code, body, header, etc.&lt;/p&gt;

&lt;p&gt;A fully working example can be found in my Github repo in WeatherRestController.java.&lt;/p&gt;

&lt;h1&gt;
  
  
  Periodic Task Annotations
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@Scheduled&lt;/li&gt;
&lt;li&gt;@EnableScheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some web services need to do regular work in the background, such as archiving old data, aggregating data to create statistics etc. Spring makes the implementation of periodic tasks as easy as this:&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="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableScheduling&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Scheduled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cron&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"* * * * * ?"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doTask&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello world"&lt;/span&gt;&lt;span class="o"&gt;);&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;As you can see, all we need is a Class annotated with &lt;code&gt;@EnableScheduling&lt;/code&gt; and a method annotated with &lt;code&gt;@Scheduled(cron=...)&lt;/code&gt;. This method will run in the background according to our &lt;a href="https://www.baeldung.com/cron-expressions" rel="noopener noreferrer"&gt;cron expression&lt;/a&gt;, e.g. every 10 minutes, or every hour.&lt;/p&gt;

&lt;p&gt;A fully working example can be found in my Github repo in WeatherStatsTask.java.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bean Annotation
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@Configuration&lt;/li&gt;
&lt;li&gt;&lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get your app up and running quickly, Spring Boot has lots of sensible default configurations like the REST configuration (e.g. read timeout, connect timeout). We can &lt;strong&gt;overwrite configuration defaults&lt;/strong&gt; by defining our own &lt;strong&gt;Beans&lt;/strong&gt;.&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="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RestConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Bean&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RestTemplate&lt;/span&gt; &lt;span class="nf"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;RestTemplateBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;)&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;builder&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PT5s"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setReadTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PT10s"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&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;As displayed above, our Beans are put in a &lt;code&gt;@Configuration&lt;/code&gt;-class and the method is annotated with &lt;code&gt;@Bean&lt;/code&gt;. The return type is essential here: whenever Spring needs to work with a &lt;code&gt;RestTemplate&lt;/code&gt;, it will configure it according to our specification.&lt;/p&gt;

&lt;p&gt;A fully working example can be found in my Github repo in JpaConfig.java.&lt;/p&gt;

&lt;h1&gt;
  
  
  Quick Note on Dependency Injection
&lt;/h1&gt;

&lt;p&gt;Let's quickly look at the concept of dependency injection, as this is essential to understand Spring-managed components.&lt;/p&gt;

&lt;p&gt;Spring offers an &lt;a href="https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html" rel="noopener noreferrer"&gt;Inversion of Control&lt;/a&gt; (IoC) Container: Instead of manually initializing all members of an object, Spring will &lt;strong&gt;inject all necessary dependencies&lt;/strong&gt;. In the graphic below, you can see a Class requiring an object of another Class:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmqbrgxjt4171ek06q0rz.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmqbrgxjt4171ek06q0rz.JPG" alt="Parent-Child dependency" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Class &lt;code&gt;Parent&lt;/code&gt; contains a &lt;code&gt;Child&lt;/code&gt; object:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Parent&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Parent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;;&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;We can now annotate the dependency with &lt;code&gt;@Component&lt;/code&gt; as follows:&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="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when Spring IoC must create an object of type Parent, it will automatically create an object of Child, then pass the object as argument to the Parent constructor, thus creating an object where all dependencies are initialized.&lt;/p&gt;

&lt;p&gt;Note that the actual dependency chain in a complex application can have several hierarchy levels. Spring IoC will also work for complicated cases where one Class will require another one which again will require a third one and so on. Moreover, Spring IoC even works for Interface-Dependencies: when a Class requires an object of the type of an interface, Spring will search for a Class implementing that interface and inject it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Annotations for Spring Managed Components
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@Component&lt;/li&gt;
&lt;li&gt;@Service&lt;/li&gt;
&lt;li&gt;@Repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you understand the concept of dependency injection, let’s focus on the three different annotations that specify Spring-managed components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Component&lt;/code&gt;: This Class is registered in the Spring-ApplicationContext and becomes a candidate for dependency injection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Service&lt;/code&gt;: has the same meaning as @Component, but is used for the &lt;strong&gt;service layer&lt;/strong&gt; of an app (with business logic).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Repository&lt;/code&gt;: same as @Component, but for Classes performing &lt;strong&gt;database access&lt;/strong&gt;. The standard database exceptions will automatically be caught by Spring and dealt with appropriately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that all of these annotations are to be applied at class-level.&lt;/p&gt;

&lt;p&gt;A fully working example can be found in my Github repo in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@Components -&amp;gt; AnnotationsAppProperties.java&lt;/li&gt;
&lt;li&gt;@Service -&amp;gt; WeatherService.java&lt;/li&gt;
&lt;li&gt;@Repository -&amp;gt; WeatherRepository.java&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Persistence Annotations
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a class="mentioned-user" href="https://dev.to/entity"&gt;@entity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;@ Id&lt;/li&gt;
&lt;li&gt;@GeneratedValue&lt;/li&gt;
&lt;li&gt;@EnableJpaRepositories&lt;/li&gt;
&lt;li&gt;@EnableTransactionManagement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similar to the previous sections, annotations come in handy for data persistence: all we need is the right annotations! For the following example, let’s just focus on an SQL use case, and let’s use &lt;a href="https://spring.io/projects/spring-data-jpa" rel="noopener noreferrer"&gt;Spring Data Jpa&lt;/a&gt;. To do the &lt;a href="https://en.wikipedia.org/wiki/Object-relational_mapping" rel="noopener noreferrer"&gt;ORM mapping&lt;/a&gt;, we need an &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/entity"&gt;@entity&lt;/a&gt; class&lt;/strong&gt; as follows:&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="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherPO&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;GeneratorionType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;temperature&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;In the above code, the WeatherPO class holds all data elements which we want to represent from our relational database. The first member is also annotated with &lt;code&gt;@Id&lt;/code&gt; which indicates that this is the primary key. Moreover, we define a strategy to generate new primary keys, again with an annotation!&lt;/p&gt;

&lt;p&gt;Now we are ready to define a JpaRepository with which we can fetch WeatherPO objects from the database:&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="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;WeatherRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WeatherPO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Spring sees the &lt;code&gt;@Repository&lt;/code&gt; annotation, it will automatically create an implementing class to access the DB. We can use the Repository via dependency injection:&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="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;WeatherRepository&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;WeatherService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WeatherRepository&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;;&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;WeatherPO&lt;/span&gt; &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&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;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&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;For a complete list of all JpaRepository functions, like &lt;code&gt;getOne()&lt;/code&gt; used in the code above, checkout out the official documentation &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So far, we’ve covered all Java code necessary to access a database. To make everything work, we additionally need the right Maven dependency: Spring’s &lt;code&gt;spring-boot-starter-data-jpa&lt;/code&gt;. There exists a myriad of SQL databases, if we choose to use the simple H2 database, we need one more Maven dependency: &lt;code&gt;com.h2database.h2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Optionally, we can configure our database (username, password, URL, etc). Note that the H2 database will work out of the box, but for others like an Oracle DB, you would need this additional configuration. Namely, you can force the search of repositories with &lt;code&gt;@EnableJpaRepositories&lt;/code&gt; and you can create your own database related beans with the &lt;code&gt;@EnableTransactionManagement&lt;/code&gt; annotation.&lt;/p&gt;

&lt;p&gt;A fully working example can be found in my Github repo in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/entity"&gt;@entity&lt;/a&gt;, @ Id, @GeneratedValue -&amp;gt; WeatherPO.java&lt;/li&gt;
&lt;li&gt;@Repository -&amp;gt; WeatherRepository.java&lt;/li&gt;
&lt;li&gt;@EnableJpaRepositories, @EnableTransactionManagement -&amp;gt; JpaConfig.java&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Miscellaneous Annotations
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@Autowired&lt;/li&gt;
&lt;li&gt;@ConfigurationProperties&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;@ConfigurationProperties&lt;/code&gt; can be used to automatically fetch configuration values from a &lt;code&gt;.properties&lt;/code&gt; or &lt;code&gt;.yaml&lt;/code&gt; file and put them into our Java class with the same data structure. This allows us to set config values in a configuration file, which can be easily altered later.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@Autowired&lt;/code&gt; forces dependency injection. We need to &lt;strong&gt;start the dependency-injection-mechanism&lt;/strong&gt; at the root of the dependency chain. When we ask Spring to initialize the top-level object, this will trigger the initialization and injection of all objects in the dependency chain. The @Autowired annotation can be used for this purpose and put before the top-level object.&lt;/p&gt;

&lt;p&gt;A fully working example can be found in my Github repo in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@ConfigurationProperties -&amp;gt; AnnotationsAppProperties.java&lt;/li&gt;
&lt;li&gt;@Autowired -&amp;gt; WeatherIntegrationTest.java&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Annotations for Testing
&lt;/h1&gt;

&lt;p&gt;Covered in this section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@SpringBootTest&lt;/li&gt;
&lt;li&gt;@AutoConfigureMockMvc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spring offers annotations just for testing purposes, a great feature to make your integration tests simpler! Since this post is already a bit longer than originally intended, I’ll stop here and refer you to the fully working example in WeatherIntegrationTest.java.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Congrats, you made it to the finish of this (rather lengthy) post😊 I hope this post has helped you to understand the most important annotations of Spring. If you want to know more details, I encourage you to have a look at my &lt;a href="https://github.com/pmgysel/spring-boot-annotations" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; with a fully working Spring Boot service using all annotations from this post.&lt;/p&gt;

&lt;p&gt;Also, if you have a Spring annotation which you consider essential and it’s not covered here, please leave a comment and I will try to extend this article or creating a new one which includes your annotation.&lt;/p&gt;

&lt;p&gt;Finally, please remember to heart❤️ this article if you found it useful!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>springboot</category>
      <category>java</category>
      <category>rest</category>
    </item>
    <item>
      <title>Simple working example of REST Web Service with Spring Boot</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Fri, 01 May 2020 09:19:01 +0000</pubDate>
      <link>https://dev.to/pmgysel/simple-working-example-of-rest-web-service-with-spring-boot-4plo</link>
      <guid>https://dev.to/pmgysel/simple-working-example-of-rest-web-service-with-spring-boot-4plo</guid>
      <description>&lt;p&gt;In this we will look at a very basic &lt;strong&gt;web service&lt;/strong&gt; which can respond to &lt;strong&gt;HTTP requests&lt;/strong&gt;. This blog is perfect for people who want to get started using &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpsl5iuuw4taxzpbougld.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpsl5iuuw4taxzpbougld.jpg" alt="Palm Beach" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Spring Boot?
&lt;/h1&gt;

&lt;p&gt;So why should you as Java developer care about Spring Boot? Well there are many good reasons! 😊 First of all Spring is &lt;strong&gt;open source&lt;/strong&gt;, meaning it is continuously maintained and tested by community and it is free or charge. Second, according to &lt;a href="https://hotframeworks.com/languages/java" rel="noopener noreferrer"&gt;Hotframeworks&lt;/a&gt;, it is the &lt;strong&gt;most widely used&lt;/strong&gt; Java web framework of 2019. Third, there’s an excellent way to get your Spring application &lt;strong&gt;up and running quickly&lt;/strong&gt;, which is where Spring Boot comes into play: Thanks to Spring Boot, you don’t need to worry about a lot of the boiler plate code and configuration. Spring Boot automatically sets a lot of config defaults for you, but you can always overwrite those if needed. For that purpose, Spring Boot is opinionated, meaning the people in the Spring team chose some configs for you, but those are well accepted by the community.&lt;/p&gt;

&lt;p&gt;Btw, why should we care about web frameworks at all? Well there are many items which are used over and over in typical web services, such as answering to HTTP request, spanning new threads for each incoming request, security mechanisms like HTTPS and OAUTH2 and so forth. We do not want to reinvent the wheel every time we create a new web service, and for that purpose we can use &lt;strong&gt;web frameworks&lt;/strong&gt; with all those common mechanisms provided. Additional features from web frameworks include data base access, scheduling of tasks, inversion of control etc. All these nice features are included in Spring Boot and thus you have more time for other stuff like drinking a good cappuccino☕&lt;/p&gt;

&lt;p&gt;As a final introductory remark, let me mention that Spring is not only compatible with Java, but also with &lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt;, a language very popular for &lt;a href="https://developer.android.com/kotlin" rel="noopener noreferrer"&gt;Android apps&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;We will now create a hello-world web service. All necessary code is given here, and the final solution is also available on my &lt;a href="https://github.com/pmgysel/spring-boot-intro.git" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Requisites to follow all the steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;li&gt;Java JDK 8 or higher&lt;/li&gt;
&lt;li&gt;Command line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this blog, we will do all the work from the command line. Alternatively, you can use an IDE like IntelliJ. In fact, I will soon release a post on IntelliJ and cover introductory topics like code completion, searching for a given code snippet in your project, compilation, debugging etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using the Spring initializr
&lt;/h1&gt;

&lt;p&gt;We use &lt;strong&gt;Maven&lt;/strong&gt; as build tool, and Spring Boot offers a great way to create your POM file: Head over to &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;https://start.spring.io/&lt;/a&gt; and enter all the details of our app like below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg43qm8ej18m75p3nf0ja.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg43qm8ej18m75p3nf0ja.JPG" alt="Spring Boot initializr" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use a newer version of Spring Boot and Java – of course - if you prefer to. Anyways, remember to add “Spring Web” as a starter dependency – we will use it for our REST endpoints. Once you have filled in all details, use the “GENERATE” button. This will download a ZIP file with the initial Java project structure, and most importantly, the initial &lt;strong&gt;pom.xml&lt;/strong&gt; file. &lt;/p&gt;

&lt;p&gt;Let us have a closer look at the generated POM file. At the top of the POM, you can see we inherit from &lt;code&gt;spring-boot-starter-parent&lt;/code&gt;, which contains all necessities for a Spring-Boot app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-parent&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.2.6.RELEASE&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;relativePath/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- lookup parent from repository --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Further down in the POM, under &lt;code&gt;dependencies&lt;/code&gt;, you can see we will use &lt;code&gt;spring-boot-starter-web&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-web&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find a nice description of this dependency on &lt;a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web" rel="noopener noreferrer"&gt;mvnrepository.com&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anyways, so far, we have only looked at one important file: the pom.xml file. Next let us focus on the Main Class, which you can find under &lt;code&gt;src/main/java/com/example/springbootexample/SpringBootExampleApplication.java&lt;/code&gt;:&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="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpringBootExampleApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringBootExampleApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&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;What is interesting here is just the annotation at the top: &lt;a href="https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/using-boot-using-springbootapplication-annotation.html" rel="noopener noreferrer"&gt;@SpringBootApplication&lt;/a&gt;. Among several things, this annotation makes sure our Spring Boot app gets configured with the default Spring Boot properties (like timeouts for HTTP requests and many, many other things).&lt;/p&gt;

&lt;h1&gt;
  
  
  Hello-World REST endpoint
&lt;/h1&gt;

&lt;p&gt;Since we want to create a REST endpoint later on, we need our Main class to search for Servlets, and therefore we need to add one more annotation to our Main class: &lt;code&gt;@ServletComponentScan&lt;/code&gt; (again, if today is your lazy day and you don’t want to do any coding, you can look at the completed code in my &lt;a href="https://github.com/pmgysel/spring-boot-intro.git" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Next, let us create a REST endpoint. For this purpose, we create a new Java class and call it &lt;code&gt;PingRestController.java&lt;/code&gt; (you can use the same folder as for the Main class).&lt;/p&gt;

&lt;p&gt;The content of &lt;code&gt;PingRestController.java&lt;/code&gt; should look like so:&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.springbootexample&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMethod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PingRestController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/ping"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getPing&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pong"&lt;/span&gt;&lt;span class="o"&gt;);&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;The annotation &lt;code&gt;@RestController&lt;/code&gt; signifies that this class contains REST endpoints. Each REST endpoint is a method annotated with &lt;code&gt;@RequestMapping&lt;/code&gt;. In this particular case, we have only one such method: &lt;code&gt;getPing&lt;/code&gt;. This method is executed every time the corresponding REST call arrives at our server. Let us look more in detail at the @RequestMapping annotation: We specify a &lt;code&gt;method&lt;/code&gt; and a &lt;code&gt;path&lt;/code&gt; variable. These two variables specify that we want to capture HTTP GET request to the URI “/api/ping”. Also, note the return type of our getPing method: A &lt;code&gt;ResponseEntity&lt;/code&gt; wraps the HTTP answer, and the HTTP body should be just a String. Thus, the response to the HTTP call will always looks as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Headers: Status: 200, ContentType: text/plain;charset=UTF-8
Body: "pong"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the modified Main class and the PingRestController class, we have all pieces ready to run our service. In the terminal, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean &lt;span class="nb"&gt;install
&lt;/span&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/spring-boot-example-0.0.1-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in your favorite web browser, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localhost:8080/api/ping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the “pong” response!&lt;/p&gt;

&lt;p&gt;What happens in the background is that your browser fires a HTTP GET request to localhost, which is handled by your Spring Boot app and responded to with the String “pong”.&lt;/p&gt;

&lt;h1&gt;
  
  
  Integration Test
&lt;/h1&gt;

&lt;p&gt;A great way to make sure our REST endpoint really works, is by writing an integration test. This test will run every time we build our application. Why do we use integration tests? First, because we developers want to &lt;strong&gt;automate&lt;/strong&gt; everything and do not like testing manually. Second, because this adds &lt;strong&gt;stability&lt;/strong&gt; to future development: As our web service will be extended, this test will still run with every build, and we can be sure this feature still works.&lt;/p&gt;

&lt;p&gt;What is an integration test? Contrary to unit tests which only look at one class, an integration test is for our app as a whole, where all components get integrated together. We typically mock third party systems like data bases, so we can test independent of (sometimes unreliable) surrounding systems. In our case, we want to really boot up our web service, but if we had a data base, then we would just simulate it.&lt;/p&gt;

&lt;p&gt;We implement our integration test in &lt;code&gt;src/test/java/com/example/springbootexample/PingIntegrationTest.java&lt;/code&gt;:&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.springbootexample&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.extension.ExtendWith&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.context.SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.test.context.junit.jupiter.SpringExtension&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.test.web.servlet.MockMvc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;servlet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MockMvcRequestBuilders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ExtendWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringExtension&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="nd"&gt;@AutoConfigureMockMvc&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PingIntegrationTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;MockMvc&lt;/span&gt; &lt;span class="n"&gt;mvc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Test&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testHelloWorldEndpoint&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mvc&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/ping"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andReturn&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getResponse&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getContentAsString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&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;As you can see, testing a REST endpoint takes slightly more code. For now, let us just focus on the interesting bits, and I will leave it to you to understand every single line of code. So here are the important points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@SpringBootTest&lt;/code&gt;: Start the web server locally and have it ready to answer to test REST calls&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;private MockMvc mvc&lt;/code&gt;: A MockMvc object allows us to fire test HTTP calls to our web server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Test&lt;/code&gt;: Just as with Junit-Tests, each test is implemented in a method annotated with @&lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mvc.perform(get(“api/ping”))&lt;/code&gt;: Here we trigger an HTTP GET request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run the test with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nt"&gt;-Dtest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PingIntegrationTest &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aaaaand... the integration test fails🙈 What happened? Well no need to worry, there is just a tiny error in the above test case. I will leave it up to you to find the error cause and fix it!&lt;/p&gt;

&lt;h1&gt;
  
  
  Spring Configuration
&lt;/h1&gt;

&lt;p&gt;Spring Boot automatically configures many properties of your service. For example, when we pinged our own service, we had to use port 8080. Now we did not define this anywhere… this is just a Spring Boot default. All those default properties can be found in the &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html" rel="noopener noreferrer"&gt;official docu here&lt;/a&gt;. To change this default behavior, all we need to do is create an &lt;code&gt;application.properties&lt;/code&gt; file and overwrite the appropriate value. So, go ahead and modify &lt;code&gt;src/main/resources/application.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8082&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you recompile and restart the service, the REST endpoint will be available on port 8082.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We have covered all code necessary to create a simple REST service. Using Spring Boot, we just needed a total of 23 lines of Java code to create a working REST endpoint! Moreover, there was zero XML configuration needed. Pretty cool!&lt;/p&gt;

&lt;p&gt;I hope this post has helped you to get started with Spring Boot, please remember to heart❤️ it and leave a comment below! 😊&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>java</category>
      <category>springboot</category>
      <category>rest</category>
    </item>
    <item>
      <title>Introduction to Convolutional Neural Networks</title>
      <dc:creator>Philipp Gysel</dc:creator>
      <pubDate>Tue, 21 Apr 2020 13:55:49 +0000</pubDate>
      <link>https://dev.to/pmgysel/introduction-to-convolutional-neural-networks-4358</link>
      <guid>https://dev.to/pmgysel/introduction-to-convolutional-neural-networks-4358</guid>
      <description>&lt;p&gt;In this introductory post on Convolutional Neural Networks, we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some &lt;strong&gt;applications&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The most important &lt;strong&gt;layer types&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While talking about the different layers, we won’t focus on the math but rather on the benefit of each layer as well as the simplified forward path.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F74bz9xg0b0bdmqv8o86y.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F74bz9xg0b0bdmqv8o86y.jpg" alt="Blue Mountains" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction to Convolutional Neural Networks (CNN)
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Machine Learning&lt;/strong&gt; offers many different models for supervised learning, and CNNs are one such &lt;strong&gt;model type&lt;/strong&gt;. CNNs are part of the artificial neural network family, with the important addition that they contain &lt;strong&gt;convolutional layers&lt;/strong&gt;. CNNs have many applications, such as image recognition and natural language processing. Let’s also mention that CNNs are inspired by the visual cortex of animals: neurons in the network only respond to the stimuli of a restricted region from the previous layer.&lt;/p&gt;

&lt;p&gt;Why should you care about CNNs? Well a lot of the most challenging AI problems are actually solved with CNNs!😊&lt;/p&gt;

&lt;h1&gt;
  
  
  Applications
&lt;/h1&gt;

&lt;p&gt;Let’s look at three innovative applications that work thanks to CNNs!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Object detection:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arxiv.org/pdf/1704.04861.pdf" rel="noopener noreferrer"&gt;MobileNets&lt;/a&gt;, developed by Google Research, can be used for many tasks, among them object detection. The advantage of MobileNets: this neural network family is very resource efficient, which can be crucial for applications running on smartphones or autonomous cars.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa5xrerlqriqmsg6beh2w.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa5xrerlqriqmsg6beh2w.PNG" alt="Traffic objects" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Face recognition:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://openaccess.thecvf.com/content_cvpr_2015/papers/Li_A_Convolutional_Neural_2015_CVPR_paper.pdf" rel="noopener noreferrer"&gt;Stevens Institute of Technology&lt;/a&gt; used CNNs for face detection, one possible application: focus smartphone camera on the people, not the background.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdmn4k0fnxjhk6zfqlao0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdmn4k0fnxjhk6zfqlao0.PNG" alt="Face recognition" width="510" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Board game Go:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepmind.com/research/case-studies/alphago-the-story-so-far" rel="noopener noreferrer"&gt;DeepMind&lt;/a&gt; used a combination of deep neural network and tree search to beat the best human player at the game of Go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv5waubipjf0rgp7y335w.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv5waubipjf0rgp7y335w.PNG" alt="Game Go" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The layers
&lt;/h1&gt;

&lt;p&gt;Convolutional neural networks typically contain many layers – some models up to 100 layers and more! Each layer is supposed to extract features – that is, interesting characteristics – from the input. Since CNNs often consist of so &lt;strong&gt;many layers&lt;/strong&gt;, they are part of the &lt;strong&gt;deep learning&lt;/strong&gt; models.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fymgfkhtkyn5gly1e7a9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fymgfkhtkyn5gly1e7a9x.png" alt="GoogleNet" width="800" height="179"&gt;&lt;/a&gt;&lt;br&gt;
Image credit: &lt;a href="https://arxiv.org/pdf/1409.4842.pdf" rel="noopener noreferrer"&gt;Google Research&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above, you can see the picture of a deep CNN called GoogleNet. As the name suggests, it was designed by Google. On the very left of the picture, the input (that is, an image in RGB format) is fed into the CNN. The first layers extract very &lt;strong&gt;simple features&lt;/strong&gt; like lines, dots and edges in the image. The next layers extract more &lt;strong&gt;advanced features&lt;/strong&gt; like objects and shapes. At the very right of the picture above, the network will extract high level features which enable to the network to distinguish between 1000 image categories.&lt;/p&gt;

&lt;p&gt;You might ask: So which layers exist and when should I use them? Well I’m glad you asked: This blog will answer exactly this question! 😊 First let’s get an overlook of the most important layer types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer type&lt;/th&gt;
&lt;th&gt;Benefit&lt;/th&gt;
&lt;th&gt;Has learnable parameters?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Convolution&lt;/td&gt;
&lt;td&gt;Extract feature from small region of input&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully connected&lt;/td&gt;
&lt;td&gt;Extract feature from whole input&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReLU&lt;/td&gt;
&lt;td&gt;Recognize non-linear properties&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pooling&lt;/td&gt;
&lt;td&gt;Resilient against small distortion in input&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch Normalization&lt;/td&gt;
&lt;td&gt;Keep neuron values in range&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Softmax&lt;/td&gt;
&lt;td&gt;Get class probabilities&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loss&lt;/td&gt;
&lt;td&gt;Calculate the prediction error&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now let’s go through all layer types:&lt;/p&gt;

&lt;h1&gt;
  
  
  Convolutional layer
&lt;/h1&gt;

&lt;p&gt;Convolutional layers are typically where most of the computation happens in a deep CNN: this layer type extracts features using a &lt;code&gt;K x K&lt;/code&gt; convolution filters. An example is given below, where the green input is convolved with the yellow filter and thus the red output is generated. In this example, the filter dimension &lt;code&gt;K&lt;/code&gt; equals 3. The output shows high values in spatial locations where the input looks similar to the filter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpxrxaroz67xk1lqjjtv9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpxrxaroz67xk1lqjjtv9.gif" alt="Convolution" width="526" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image credit: &lt;a href="http://ufldl.stanford.edu/tutorial/supervised/FeatureExtractionUsingConvolution/" rel="noopener noreferrer"&gt;Stanford Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, &lt;strong&gt;we extract the same feature at different spatial locations&lt;/strong&gt;. This means the output only depends on a small region of the input.&lt;/p&gt;

&lt;p&gt;In reality, things are slightly more complicated than in the image above: the input to a convolutional layer consists of multiple feature maps, and the output too. So, for &lt;code&gt;N&lt;/code&gt; input feature maps and &lt;code&gt;M&lt;/code&gt; output feature maps, we need filters in the total size of &lt;code&gt;N * M * K * K&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Convolutional layers are typically the bottle neck in terms of arithmetic operations. In most deep learning frameworks, convolution is implemented via data rearranging and matrix multiplication. Also, deep learning training is very resource intense, but offers a lot of room for parallelism. For this purpose, people often use Graphics Processing Units for training, and matrix multiplications are heavily optimized on modern GPUs.&lt;/p&gt;

&lt;p&gt;For a great way to learn more about convolution, you can check &lt;a href="https://cs231n.github.io/convolutional-networks/#conv" rel="noopener noreferrer"&gt;this&lt;/a&gt; course offered by Stanford University. They also cover more details on CNNs in general.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fully Connected Layer
&lt;/h1&gt;

&lt;p&gt;Alright, let’s move on to the next layer type, namely the fully connected layer. &lt;strong&gt;This layer extracts features over the whole input&lt;/strong&gt;, meaning each output node depends on all input nodes. Mathematically, the output vector &lt;code&gt;y&lt;/code&gt; is the result of the weighted input vector &lt;code&gt;x&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;y = W * x&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The weight matrix &lt;code&gt;W&lt;/code&gt; is of dimension &lt;code&gt;|x|*|y|&lt;/code&gt;, which brings us to the drawback of this layer type: The size of the parameters tends to be very large, which is why most modern network architectures avoid fully connected layers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Activation Function: ReLU
&lt;/h1&gt;

&lt;p&gt;Convolutional neural networks can capture complex properties, which wouldn’t be recognized by a simple linear regression. This is largely thanks to activation functions inside a neural network: They introduce a &lt;strong&gt;non-linearity&lt;/strong&gt; into the forward path of the network. Activation functions are typically appended to the convolutional layers and they are applied to each output node independently.&lt;/p&gt;

&lt;p&gt;Traditionally, people used different activation functions like Sigmoid, Tanh and ReLU. The last one has proven to be the most effective for deep learning. The picture below shows all three activation functions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx3xdvfjga65wek96zkzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx3xdvfjga65wek96zkzg.png" alt="Activation Function" width="560" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The activation function ReLU (Rectified Linear Unit) keeps all positive values untouched, but negative values get set to zero:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;y = max(0, x)&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Pooling Layer
&lt;/h1&gt;

&lt;p&gt;Pooling layers reduce the dimension by combining several neurons to one. There are two pooling types: &lt;strong&gt;average pooling&lt;/strong&gt; and &lt;strong&gt;max pooling&lt;/strong&gt;. Many networks use max pooling: here, the output node is equal to the maximum of the input region.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4o1hjokebfjns8lhh4pw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4o1hjokebfjns8lhh4pw.gif" alt="Alt Text" width="888" height="512"&gt;&lt;/a&gt;&lt;br&gt;
Image credit: &lt;a href="http://ufldl.stanford.edu/tutorial/supervised/Pooling/" rel="noopener noreferrer"&gt;Stanford Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Batch Normalization
&lt;/h1&gt;

&lt;p&gt;For different reasons which we’ll discuss in a second, we want our activations to stay in a &lt;strong&gt;reasonable number range&lt;/strong&gt; during training. However, the above presented ReLU activation function is unbounded. To make up for this, we typically use normalization layers at regular intervals within the network. There are two important normalization layer types: &lt;strong&gt;LRN&lt;/strong&gt; (local response normalization) and &lt;strong&gt;BN&lt;/strong&gt; (batch normalization). While older networks used LRN, newer ones often use BN. BN was originally proposed by &lt;a href="https://arxiv.org/pdf/1502.03167.pdf" rel="noopener noreferrer"&gt;Google Research&lt;/a&gt; and it helps in many ways: the training is easier to set up and goes faster, and the end accuracy is better. What BN basically does, is it rescales and re-centers the data.&lt;/p&gt;

&lt;p&gt;So why is it important to keep our data in a reasonable range? There are two main reasons: First we need to represent our data using some number format (typically with 32-bit or 64-bit floating point), and we simply can’t represent huge numbers accurately. Second, we want high values in our feature maps to represent strong feature existence. But values down the layer chain would possibly become huge, thus we can’t easily estimate whether a given feature is actually present or not.&lt;/p&gt;

&lt;p&gt;Once the network is trained and then used for inference, the BN layer can be simplified to a linear transformation:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;y = γ * x + β&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Softmax
&lt;/h1&gt;

&lt;p&gt;The output of a classification network is a vector of probabilities. To achieve this, we use a Softmax layer, which normalizes the output nodes such that the sum of all nodes is 1. The formula of Softmax is as follows:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;y = exp(x) / sum(exp(x))&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Loss
&lt;/h1&gt;

&lt;p&gt;The loss layer is used during training only. It compares the network output with the ground truth and computes the “error” of our prediction. The resulting loss is then backpropagated through the network to adjust all learnable parameters. Various &lt;a href="https://www.tensorflow.org/api_docs/python/tf/keras/losses" rel="noopener noreferrer"&gt;loss functions&lt;/a&gt; exist, and the choice of loss function will often influence the final result significantly.&lt;/p&gt;

&lt;p&gt;For multi-class prediction networks, we typically use &lt;strong&gt;Sparse Cross Entropy&lt;/strong&gt; as loss function, which is equal to the negative log probability of the true class. If our network is sure of the correct class, the loss is zero, and if the network is totally wrong, the loss is infinitely big.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this post, we first covered the benefits of neural networks: for tasks like object detection, they deliver state-of-the-art results. The second part of the blog was dedicated to the different layer types which are commonly used in CNNs. If you wish to dive deeper and gain more hands-on experience with CNNs, I can suggest this &lt;a href="https://www.tensorflow.org/tutorials/images/cnn" rel="noopener noreferrer"&gt;TensorFlow CNN Tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks so much for reading this blog, I hope it has helped you to get started with CNNs.😊&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>neuralnetworks</category>
      <category>deeplearning</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
