<?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: Thinking out code</title>
    <description>The latest articles on DEV Community by Thinking out code (@to_code).</description>
    <link>https://dev.to/to_code</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%2F161233%2Fce45de4d-6004-42e2-8f0d-ee1743a1fa20.jpg</url>
      <title>DEV Community: Thinking out code</title>
      <link>https://dev.to/to_code</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/to_code"/>
    <language>en</language>
    <item>
      <title>Speed up your search app with Redis</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Thu, 18 Aug 2022 14:16:49 +0000</pubDate>
      <link>https://dev.to/to_code/speed-up-your-search-app-with-redis-58nl</link>
      <guid>https://dev.to/to_code/speed-up-your-search-app-with-redis-58nl</guid>
      <description>&lt;p&gt;Searching apps, browsers, results found, etc; a huge percentage of apps have something related to finding detailed info in the database, in some cases with many requests per minute. This feature came from finding a word to entire rows of information.&lt;/p&gt;

&lt;p&gt;Let’s pretend that we have a hypothetical user, called Bob, he has the requirement for a Star Wars application that allows him, to find info about his favorites character from star wars movies, searching by a complete word, Bob needs an application that has an effective time of response and consumes from different sources of data.&lt;/p&gt;

&lt;p&gt;We’re talking about a considerable amount of content, including people, planets, starships, and any interesting topic about that movie. Let’s say we are the team behind that development. First of all, let’s clarify the original premise with the flow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vw4fsm6b25g1c26s86w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vw4fsm6b25g1c26s86w.jpg" alt="Basic flow app" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basic flow app&lt;/p&gt;

&lt;p&gt;As shown in the diagram below, there is one case with 3 possible scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bob searches for a word, the word is found on the API source, and the result list is returned&lt;/li&gt;
&lt;li&gt;Bob searches for a word, the word isn’t found on the API source but is found on the database source, and the result list is returned.&lt;/li&gt;
&lt;li&gt;Bob searches for a word, but the word isn’t found nor database source or API source, no content response is returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bob has his desired application, at least in theory, with a global search around all possible content from his favorite movie with two different data sources.&lt;br&gt;
Let’s bring some code to live, to test this design, I’ll show step by step every component.&lt;/p&gt;
&lt;h3&gt;
  
  
  Hands-on code
&lt;/h3&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="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/finder"&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;class&lt;/span&gt; &lt;span class="nc"&gt;SearchRestController&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;SearchService&lt;/span&gt; &lt;span class="n"&gt;searchService&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="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="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;searching&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;)&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;start&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;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getListBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&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;"Searching for "&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;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;start&lt;/span&gt;&lt;span class="o"&gt;)&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="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&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;This is a simple controller with one method declared, &lt;code&gt;searching&lt;/code&gt;, with &lt;code&gt;GetMapping&lt;/code&gt; request, that receives a word through &lt;code&gt;params&lt;/code&gt; from request, calls to the SearchService method, and responds with the list of results founds.&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;SearchService&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;ApiClient&lt;/span&gt; &lt;span class="n"&gt;apiClient&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;StarWarsRepository&lt;/span&gt; &lt;span class="n"&gt;starWarsRepository&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;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getListBy&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;word&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;apiClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;or&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;findAllByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&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;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAllByName&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;word&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;starWarsRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAllByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&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;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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;empty&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;itemDTOS&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;items&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;item&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;itemDTOS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;convertValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ItemDTO&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="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;itemDTOS&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;It receives a word from the controller and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Call the API client.&lt;br&gt;
&lt;/p&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;ApiClient&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;RestTemplate&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://swapi.dev/api/people"&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findBy&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;word&lt;/span&gt;&lt;span class="o"&gt;)&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ResultsDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;responseEntity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getForEntity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;API_URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;concat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"?search="&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;concat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;ResultsDTO&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;getResults&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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;empty&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;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;getResults&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;p&gt;It executes a request to the &lt;a href="https://swapi.dev/" rel="noopener noreferrer"&gt;StarWars Api&lt;/a&gt; with the search.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If no result has returned, it executes a call to the database repository.&lt;br&gt;
&lt;/p&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;StarWarsRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CrudRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Item&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;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAllByName&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;word&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;p&gt;It searches for similar terms in the table called star_word. In this case, it will be using a simple h2 database due to the concept test, you could implement it with another type of SQL driver. To fill this database you have to execute the next script. You could adapt it as you need it.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;name1&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;name2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;name3&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;name4&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;name5&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;121&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;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The structure of the principal object would be:&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;Item&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;String&lt;/span&gt; &lt;span class="n"&gt;name&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;String&lt;/span&gt; &lt;span class="n"&gt;height&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;Nothing crazy, just basic fields. Helped by Lombok annotations.&lt;/p&gt;

&lt;p&gt;Our pom file has declared the next dependencies:&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-data-redis&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.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;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;com.h2database&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;h2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&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.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-data-jpa&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.projectlombok&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;lombok&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;1.18.24&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="nt"&gt;&amp;lt;/scope&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;redis.clients&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;jedis&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;3.9.0&lt;span class="nt"&gt;&amp;lt;/version&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;ul&gt;
&lt;li&gt;Jedis: a Java client for Redis.&lt;/li&gt;
&lt;li&gt;Spring-boot-starter-data-redis: Provides easy configuration and access to Redis from Spring Apps, offering low-level and high-level abstractions for interactions with the database without architecture worries.&lt;/li&gt;
&lt;li&gt;h2 In-memory database.&lt;/li&gt;
&lt;li&gt;Lombok: Oriented to decorator pattern to avoid boilerplate code.&lt;/li&gt;
&lt;li&gt;Spring-boot-starter-data-jpa: Implements a data access layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having those configurations and custom classes, now the application had covered the case of the basic design. Let’s see how would be the performance in terms of time(ms) of the search process, having it “up and running”, in the next 2 possible scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;API&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/?word&lt;span class="o"&gt;=&lt;/span&gt;luke

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Luke Skywalker"&lt;/span&gt;,
    &lt;span class="s2"&gt;"height"&lt;/span&gt;: &lt;span class="s2"&gt;"172"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

Searching &lt;span class="k"&gt;for &lt;/span&gt;1237 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Database&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/?word&lt;span class="o"&gt;=&lt;/span&gt;name1

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"name1"&lt;/span&gt;,
    &lt;span class="s2"&gt;"height"&lt;/span&gt;: &lt;span class="s2"&gt;"121"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

Searching &lt;span class="k"&gt;for &lt;/span&gt;1289 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After executing those cases, take a look at the next table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;API Datasource(ms)&lt;/th&gt;
&lt;th&gt;Database source(ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Results found(time response)&lt;/td&gt;
&lt;td&gt;1237&lt;/td&gt;
&lt;td&gt;1289&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As is shown, the database source takes a little more time than the API source. The response time is not a big thing right now but what could happen when the database makes it bigger? or there are not only two sources of data(API, database), but a lot more? Our app could make better searches?&lt;/p&gt;

&lt;p&gt;The answer is yes, but it needs to take into count what corner cases it has right now. In the next implementation, we’ll see one of them.&lt;/p&gt;
&lt;h3&gt;
  
  
  The problem of search the same thing over and over again
&lt;/h3&gt;

&lt;p&gt;What about the case of one o more Bob users, searching by the same word, with many requests but the same word to search? Is it worth the effort of making a searching process for every similar term?&lt;/p&gt;

&lt;p&gt;Taking this scenario as an example, let's think about how could improve the performance, in that case, to avoid ping to several API or data sources when a term has previous searching tries, and ping to a source in common that stores this similar searches with a lesser time response, something like that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsbd0nxcwy57ann9m7sqa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsbd0nxcwy57ann9m7sqa.jpg" alt="Search design with a third source feature." width="800" height="1315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search design with a third source feature.&lt;/p&gt;

&lt;p&gt;The third data source act like cache storage, understanding as cache as a temporary store.&lt;/p&gt;
&lt;h3&gt;
  
  
  A possible new improvement…
&lt;/h3&gt;

&lt;p&gt;Same one case than the beginning but adding 2 additional steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bob searches for a word, and the word was found on an API source, &lt;strong&gt;the result is stored in a third source&lt;/strong&gt;, and it is returned.&lt;/li&gt;
&lt;li&gt;Bob searches for a word, the word wasn’t found on the API source but is found on the database source, &lt;strong&gt;the result is stored in a third source&lt;/strong&gt;, and it is returned.&lt;/li&gt;
&lt;li&gt;Bob searches for a word, the word was found on a third source, and the result list was returned.&lt;/li&gt;
&lt;li&gt;Bob searches for a word, but the word wasn’t found nor database source nor API source, or third source, no content response is returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are no additional steps when data was searched before because it was stored in the first request, being available for after requests, avoiding repetitive searches, and improving the app performance.&lt;/p&gt;

&lt;p&gt;It looks simple, but what would be the characteristics that must have this third data source?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low latency.&lt;/li&gt;
&lt;li&gt;Capable of saving and returning data quickly.&lt;/li&gt;
&lt;li&gt;Searching by word.&lt;/li&gt;
&lt;li&gt;Native integration with our tech stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An option that probably fits with these specs, would be Spring cache, which offers different options for dealing with this type of design, allowing storing and getting data for recent results with useful configuration related and a minimal time of response.&lt;/p&gt;
&lt;h3&gt;
  
  
  Making it real with Spring and Redis cache integration
&lt;/h3&gt;

&lt;p&gt;Spring cache is a configuration that uses proxies pattern properties to interrupt request data flow, adding a third component with Redis, acting as cache storage, due to the nature of Redis, easy integration, and fast response time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Redis also :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can perform more than 11000 sets per second and more than 8000 gets per second.&lt;/li&gt;
&lt;li&gt;Due to the principle of no schemas, in this kind of database(key-value), it doesn’t need a strong definition of the objects to store, could be starting from a simple string value to a POJO.&lt;/li&gt;
&lt;li&gt;Has a property to expire values stored, making it temporarily store data.&lt;/li&gt;
&lt;li&gt;Easy indexes configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Updating our previous design, we have the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5cax02bnw1dpaywyvtz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5cax02bnw1dpaywyvtz.jpg" alt="Redis, representing our cache storage" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redis, representing our cache storage&lt;/p&gt;

&lt;p&gt;Now, we have the whole picture, with Redis in it as our third data source.&lt;/p&gt;
&lt;h3&gt;
  
  
  Let’s update our code
&lt;/h3&gt;

&lt;p&gt;Adding EnableCaching annotation to the main 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;@SpringBootApplication&lt;/span&gt;
&lt;span class="nd"&gt;@EnableCaching&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;GrapefruitApplication&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="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;GrapefruitApplication&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;This annotation is responsible of register related components to cache management like the CacheInterceptor  and other proxies that allows @Cacheable works. Spring has the next annotations available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@CacheEvict&lt;/code&gt; evict a mapping based in a key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@CachePut&lt;/code&gt; causes the method to be invoked and its result to be stored in the associated cache related to the &lt;code&gt;condition()&lt;/code&gt; and &lt;code&gt;unless()&lt;/code&gt; expressions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Caching&lt;/code&gt; grouping cache annotations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Cacheable&lt;/code&gt; indicate that the result of invoking a method or all method in a class can be cached.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  How works &lt;code&gt;@Cacheable&lt;/code&gt; in terms of Redis?
&lt;/h3&gt;

&lt;p&gt;It executes a get-by key to the Redis database, if it doesn’t return a result, it executes a put command to store the newly found result after executing the method invocation. Redis allows the storing of null results by key but this property could be set by the previous configuration.&lt;/p&gt;

&lt;p&gt;Let’s see how to look at the service method after updating it.&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="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"itemCache"&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="s"&gt;"{#word}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unless&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#result == null"&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getListBy&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;word&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;apiClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;or&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;findAllByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&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 I said before, there is a &lt;code&gt;key&lt;/code&gt; that represents the index of objects stored in Redis, the &lt;code&gt;value&lt;/code&gt; property represents the name of cache storage in Redis, and the &lt;code&gt;unless&lt;/code&gt; the property is for preventing null values.&lt;br&gt;
In the same idea, there are &lt;code&gt;RedisCacheManagerBuilderCustomizer&lt;/code&gt; and &lt;code&gt;RedisCacheConfiguration&lt;/code&gt; beans, which allow set expiring time for cache values, serialization strategy, etc.&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;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RedisCacheConfiguration&lt;/span&gt; &lt;span class="nf"&gt;cacheConfiguration&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;RedisCacheConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;defaultCacheConfig&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entryTtl&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;ofMinutes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;disableCachingNullValues&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializeValuesWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;RedisSerializationContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SerializationPair&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSerializer&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;GenericJackson2JsonRedisSerializer&lt;/span&gt;&lt;span class="o"&gt;()));&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;RedisCacheManagerBuilderCustomizer&lt;/span&gt; &lt;span class="nf"&gt;redisCacheManagerBuilderCustomizer&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="o"&gt;(&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;-&amp;gt;&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;withCacheConfiguration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"itemCache"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cacheConfiguration&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;Setting up this with the Redis configuration file(application.yaml).&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;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:h2:mem:starwars&lt;/span&gt;
    &lt;span class="na"&gt;driverClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;org.h2.Driver&lt;/span&gt;
  &lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;defer-datasource-initialization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourHost&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourPort&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourUsername&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourPassword&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You could use a local environment for Redis or the &lt;a href="https://app.redislabs.com/" rel="noopener noreferrer"&gt;Redis Lab&lt;/a&gt; environment with the free plan that allows 30MB of storage with high availability and also is easy to set up. In this &lt;a href="https://dev.to/to_code/breaking-a-request-software-design-and-falling-in-a-redis-ing-perspective-1f76"&gt;link&lt;/a&gt;, there are some references on how to connect with the Redis cloud environment that you could find useful.&lt;/p&gt;

&lt;p&gt;Having our application updated, with all the configurations before, it only takes some test to see how works this new adding feature:&lt;/p&gt;

&lt;p&gt;Let’s try with a luke word search:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/?word&lt;span class="o"&gt;=&lt;/span&gt;luke

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Luke Skywalker"&lt;/span&gt;,
    &lt;span class="s2"&gt;"height"&lt;/span&gt;: &lt;span class="s2"&gt;"172"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

Searching &lt;span class="k"&gt;for &lt;/span&gt;1237 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s try again with the same searching:&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="n"&gt;curl&lt;/span&gt; &lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:8080/?word=luke&lt;/span&gt;

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Luke Skywalker"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"height"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"172"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Searching&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  175 ms! More than 70% of improvement.
&lt;/h3&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/embed/l2Je0rrp6FM5Md6Tu" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--aRsIw2yc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media2.giphy.com/media/l2Je0rrp6FM5Md6Tu/200.gif%3Fcid%3Ddda24d50lagnnyf10utpjx3pt1hemaqbzh8nbb73vqliwm65%26ep%3Dv1_internal_gif_by_id%26rid%3D200.gif%26ct%3Dg" height="200" class="m-0" width="267"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/embed/l2Je0rrp6FM5Md6Tu" rel="noopener noreferrer" class="c-link"&gt;
          Happy Lisa Simpson GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Animated GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Look what we have here! the response time is lower than its preview results by more than 70 percent, and of course, the last request was executed in a previews step, so the request is redirected through our cache interceptor, which stored the previous data list result.&lt;/p&gt;

&lt;p&gt;Updating the previous comparator table, there is the following:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;API Datasource(ms)&lt;/th&gt;
&lt;th&gt;Database source(ms)&lt;/th&gt;
&lt;th&gt;Redis source (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Results found&lt;/td&gt;
&lt;td&gt;1237&lt;/td&gt;
&lt;td&gt;1289&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If we make a comparison in terms of big o notation efficiency, for a case with previously requested searches, we have an O(1) result, making an improvement in terms of time and steps because there are no additional steps when a search has been requested before.&lt;/p&gt;

&lt;p&gt;Think about how this could improve content search, dictionary apps, browsers, and wikis explorer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Oh yeah! This looks really good but what about the cons?
&lt;/h3&gt;

&lt;p&gt;Well, yes, there is a disadvantage that I would like to mention; this feature cannot be applied in the case where our data sources are constantly changing, because the cache store doesn’t have the last version of them, only the last snapshot when were requested by the user. If we talking about banking accounts and their related balance, this could be a problem. Another case that could be a problem is when you are checking a tracking application about delivery service, this cannot show the recent state of your shopping.&lt;/p&gt;

&lt;p&gt;Or when you are searching for items in a catalog of an e-commerce site, you need that item stocks to be updated for not to buy stuff without inventory. An improvement that could fit with this type of app, is recent searches, suggesting to the user based on its first letters written where the key of cache object would bet those starting letters and the object related to the items list.&lt;br&gt;
Surely there are a few more disadvantages coming from the cache store, but like most of the tools that are currently used, this is not a golden hammer to fix any problem but a tool for a particular case.&lt;/p&gt;
&lt;h3&gt;
  
  
  So, resuming this in a nutshell
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A common search engine that could be found in many apps.&lt;/li&gt;
&lt;li&gt;Identify a way to make it faster.&lt;/li&gt;
&lt;li&gt;Find a third factor, a data source, that could help to achieve it.&lt;/li&gt;
&lt;li&gt;Use Redis mixed with a known framework like Spring.&lt;/li&gt;
&lt;li&gt;Whoala! Run and see results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the app 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://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/JesusIgnacio" rel="noopener noreferrer"&gt;
        JesusIgnacio
      &lt;/a&gt; / &lt;a href="https://github.com/JesusIgnacio/grapefruit" rel="noopener noreferrer"&gt;
        grapefruit
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Redis with Spring cache for fast search results
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Note: Yes, I called it Grapefruit , nothing to do with the app objective but I found refreshing to call my repos as fruits.&lt;/p&gt;

&lt;p&gt;This is all by now, I hope you could enjoy this article as I enjoy writing it, and thank you for your time in reading it.&lt;br&gt;
If you have any questions, please let me know.&lt;br&gt;
Best to you!&lt;/p&gt;
&lt;h3&gt;
  
  
  This post is in collaboration with Redis.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.com/try-free/" rel="noopener noreferrer"&gt;Try Redis Cloud for free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.redis.com/" rel="noopener noreferrer"&gt;Redis Developer Hub - tools, guides, and tutorials about Redis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/stack/insight/" rel="noopener noreferrer"&gt;RedisInsight Desktop GUI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vyxdC1qK4NE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>redis</category>
      <category>redislabs</category>
      <category>spring</category>
      <category>searching</category>
    </item>
    <item>
      <title>Breaking a request software design and falling in a Redis-ing perspective.</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Fri, 24 Jun 2022 21:14:30 +0000</pubDate>
      <link>https://dev.to/to_code/breaking-a-request-software-design-and-falling-in-a-redis-ing-perspective-1f76</link>
      <guid>https://dev.to/to_code/breaking-a-request-software-design-and-falling-in-a-redis-ing-perspective-1f76</guid>
      <description>&lt;h3&gt;
  
  
  Once upon an app…
&lt;/h3&gt;

&lt;p&gt;Nowadays, systems data flow must be efficient and needs to do more with simplicity. Common ways of building modern apps are missing that point, oriented to dependent layers and cohesion between components. In this article, we'll discover an app with those failures in its data flow and split it into smaller pieces to resolve using the advantages of Event-Driven Architecture by the magic of Redis-ing it with Redis.&lt;/p&gt;

&lt;p&gt;Supposing the scenario of making a login module, to filter access to our main application pointing to three objectives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security authorization 📝&lt;/li&gt;
&lt;li&gt;Session storage📝&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which will be the entities related and their behavior?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6lvnhqdblre99z06cu5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6lvnhqdblre99z06cu5.jpg" alt="Ideas Fliying Board(2).jpg" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How would be the data flow?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Login

&lt;ul&gt;
&lt;li&gt;User send its user/password.&lt;/li&gt;
&lt;li&gt;The security module  valid credentials.

&lt;ul&gt;
&lt;li&gt;affirmative case

&lt;ul&gt;
&lt;li&gt;Authorization granted to home page.&lt;/li&gt;
&lt;li&gt;The session storage create a session related to the user.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;negative case

&lt;ul&gt;
&lt;li&gt;Unauthorized.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Logout

&lt;ul&gt;
&lt;li&gt;User request&lt;/li&gt;
&lt;li&gt;Session deleted&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Flow would like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2kse9szbwgg8bi18vbu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2kse9szbwgg8bi18vbu.jpg" alt="Ideas Fliying Board(4).jpg" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Session stored ✅&lt;/li&gt;
&lt;li&gt;Credentials validated ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, apparently have cover all , this is ready for production!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf70a8oke1g4la788z0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf70a8oke1g4la788z0p.png" alt="Homer" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Oh wait!
&lt;/h3&gt;

&lt;p&gt;I could forget something. A first perspective looks like a normal login flow but there are a few questions to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Could I integrate concurrent user sessions and limit them?&lt;/li&gt;
&lt;li&gt;What about expired sessions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I mean, this current solution could work, but what about those scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the expired session is a must, where do I mark the expired date to remove expired sessions? Which method has this responsibility? The app? A database trigger? An elf that lives inside the app working extra hours to check all the sessions and remove it?&lt;/li&gt;
&lt;li&gt;What about the limit of sessions? If the app has restarted, how would it know how many session has every user? Which of them are the older ones?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fortunately, in this article exist a solution for every of mentioned problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event-Driven Design to put things in order
&lt;/h3&gt;

&lt;p&gt;EAD is a paradigm about decoupling modules and layers pointing to making independence between them. Left behind the request-driven design, now the events will be the core of the structure, making them event dependents.&lt;/p&gt;

&lt;p&gt;What would be out core events?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A session was created.&lt;/li&gt;
&lt;li&gt;A session was expired.&lt;/li&gt;
&lt;li&gt;A session was deleted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Besides the events, EAD must specify which will be the event consumer, the producer, and the channel, to interact with them.&lt;/p&gt;

&lt;p&gt;Let’s identify what will be our flow&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff10jc0rxx6a0iajrhus4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff10jc0rxx6a0iajrhus4.jpg" alt="Ideas Fliying Board(5).jpg" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown above, the app will be informed about session events, being the event consumer and the event producer, being subscribed to the event channel, so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A session expired? The app has informed.&lt;/li&gt;
&lt;li&gt;A session created? The app has informed.&lt;/li&gt;
&lt;li&gt;A session deleted? The app has informed.&lt;/li&gt;
&lt;li&gt;How many sessions exist per user? Even if the app was restarted. The app will know it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our design resolves our raised problems, but how to bring it to reality?&lt;/p&gt;

&lt;h3&gt;
  
  
  A Redis-ing perspective
&lt;/h3&gt;

&lt;p&gt;Redis technologies bring a lot of tools to confront data flow problems effectively and simply, from storing a key-value object to providing custom configurations in the related process of it based on its structure, indexing, and lifecycle. &lt;/p&gt;

&lt;p&gt;Will use one of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Redis Pub/Sub&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redis could work as an event channel, being the event source in our design, making use of PUBLISH and SUBSCRIBE commands. Those could be executed through the Redis console as follows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SUBSCRIBE &lt;span class="o"&gt;{&lt;/span&gt;channel1&lt;span class="o"&gt;}&lt;/span&gt; ...&lt;span class="o"&gt;{&lt;/span&gt;channelN&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The subscribe command executes an active listening to a specific channel, then Redis will inform all channel subscribers when a message has been published.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PUBLISH &lt;span class="o"&gt;{&lt;/span&gt;channel1&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;message&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;While the publish command, put a new message in an specific channel.&lt;/p&gt;

&lt;p&gt;This tool is the implementation of Publish/Subscribe message paradigm.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Let’s bring the code!
&lt;/h3&gt;

&lt;p&gt;Now, we’ll build a simple app web trough &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring initializr&lt;/a&gt; with these dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spring Web&lt;/strong&gt;
To make our project a web application, for this instance, we create a simple home page structure, to be the home app representation, called index.html. It must be stored in the /templates/static folder. The HTML looks like that:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1, shrink-to-fit=no"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://getbootstrap.com/docs/4.0/examples/signin/signin.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex flex-column h-100"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-shrink-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This is Home!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/logout"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Take me out, please.&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Spring Security&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A security framework you can complex as you need it. It could look cumbersome when you’re starting using it, but with constant practicing and an understanding of the filter logic, You’ll have a great tool to work with spring environments with the pass of the time.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@EnableWebSecurity&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;SecurityConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;S&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;FindByIndexNameSessionRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;S&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sessionRepository&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;SecurityFilterChain&lt;/span&gt; &lt;span class="nf"&gt;securityFilterChain&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpSecurity&lt;/span&gt; &lt;span class="n"&gt;http&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="n"&gt;http&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizeRequests&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anyRequest&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;authenticated&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;and&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formLogin&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;and&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sessionManagement&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;maximumSessions&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sessionRegistry&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionRegistry&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;expiredUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/login"&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;http&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="nd"&gt;@Bean&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;SpringSessionBackedSessionRegistry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;S&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sessionRegistry&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="nc"&gt;SpringSessionBackedSessionRegistry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionRepository&lt;/span&gt;&lt;span class="o"&gt;);&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;UserDetailsService&lt;/span&gt; &lt;span class="nf"&gt;userDetailsService&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;UserDetails&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withDefaultPasswordEncoder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&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="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InMemoryUserDetailsManager&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;p&gt;As shown, I declared a simple class with EnableWebSecurity annotation. Inside it, a block with the specification of allowing any authenticated request; detail a default form login for users.&lt;br&gt;
It configures a custom session management, to integrate the Redis library by session registry, being responsible of count sessions per user and establishing an expired time for each one.&lt;br&gt;
If a user exceeds the session max limit session, the older session will be deleted and the current will be created. When a Redis session has expired, the user will be redirected to the login page.&lt;br&gt;
Finally, a bean to mockup user access data called userDetailsService.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Spring Data Redis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A library to integrate spring sessions with Redis with the EnableRedisHttpSession annotation which specifies max inactive seconds by session and a custom Redis namespace to store our session values in the Redis database.&lt;br&gt;
The JedisConnectionFactory bean serves as a connector library between Redis and the spring framework.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;EnableRedisHttpSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxInactiveIntervalInSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;redisNamespace&lt;/span&gt; &lt;span class="o"&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="kr"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RedisConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Bean&lt;/span&gt;
        &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;JedisConnectionFactory&lt;/span&gt; &lt;span class="nf"&gt;connectionFactory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;RedisStandaloneConfiguration&lt;/span&gt; &lt;span class="nx"&gt;configuration&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;RedisStandaloneConfiguration&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHostName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yourHost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yourPassword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yourUsername&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yourPort&lt;/span&gt;&lt;span class="p"&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="nc"&gt;JedisConnectionFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configuration&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;p&gt;Our dependencies pom must look like:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;...
&lt;span class="nt"&gt;&amp;lt;dependencies&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.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-security&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.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;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.session&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-session-data-redis&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.7.0&lt;span class="nt"&gt;&amp;lt;/version&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;redis.clients&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;jedis&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;3.9.0&lt;span class="nt"&gt;&amp;lt;/version&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;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In this instance, we could execute the app combined with a local Redis server, but to approach the Redis cloud environment, we’ll integrate with it.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;A reliable cloud environment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;First of all, we go to &lt;a href="https://app.redislabs.com/" rel="noopener noreferrer"&gt;redislab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fre0wq2qgjdwlbravjqti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fre0wq2qgjdwlbravjqti.png" alt="Cloud1" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the register step and login into the environment you’ll access to a page like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff43ahwi7z31ukwtbgf8b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff43ahwi7z31ukwtbgf8b.png" alt="Cloud2" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the example database created as default with a memory available for testing. After this, click it example-database link&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq66sguqpsnubr5jr363f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq66sguqpsnubr5jr363f.png" alt="Cloud3" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see general configs database as endpoint , username and password, to configure your JedisClient.&lt;/p&gt;

&lt;p&gt;Spring Data Redis has a validation when the app is starting to validate if database configuration is accessible, so if your properties are correct, it wouldn't be errors related.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now , the original flows looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flqmep7spea8enwzhd4o0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flqmep7spea8enwzhd4o0.jpg" alt="Final Flow" width="800" height="766"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 2 scenarios I invited you to test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login in a new session , after have 3 existing sessions, to see how the oldest session is deleted and a new one is created.&lt;/li&gt;
&lt;li&gt;Let N seconds of none interaction with your home page application, to see how works Redis expiring sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code project could be found on &lt;a href="https://github.com/JesusIgnacio/watermelon" rel="noopener noreferrer"&gt;watermelon_repo&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This is all by now, I hope you could enjoy this article as I enjoy writing in. If you have any questions, please let me know.&lt;/p&gt;

&lt;p&gt;Best to you!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.com/try-free/" rel="noopener noreferrer"&gt;Try Redis Cloud for free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.redis.com/" rel="noopener noreferrer"&gt;Redis Developer Hub - tools, guides, and tutorials about Redis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/stack/insight/" rel="noopener noreferrer"&gt;RedisInsight Desktop GUI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vyxdC1qK4NE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This post is in collaboration with Redis.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>eventdriven</category>
      <category>nosql</category>
      <category>redislabs</category>
    </item>
    <item>
      <title>Finding Luke through the command line by consuming an API</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Fri, 08 Apr 2022 11:55:25 +0000</pubDate>
      <link>https://dev.to/to_code/finding-luke-through-the-command-line-by-consuming-an-api-odp</link>
      <guid>https://dev.to/to_code/finding-luke-through-the-command-line-by-consuming-an-api-odp</guid>
      <description>&lt;p&gt;In the last chapter of this series, I need to find a Starwars word related, in the response of an API, a rarely need, yes.&lt;/p&gt;

&lt;p&gt;I have to find the word &lt;strong&gt;Luke&lt;/strong&gt; in a known Starwars API, called &lt;a href="https://swapi.dev/" rel="noopener noreferrer"&gt;Swapi&lt;/a&gt;, without IDEs, or frameworks but I’ll use the last chapter's pieces of knowledge&lt;/p&gt;

&lt;p&gt;Having the next 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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SearchingInStarWarsFor&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;if&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="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;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;StarWarsWordFinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;searchingFor&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="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="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This StarWarsWordFinder has next specifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute a request(GET) to the Swapi(people scope).&lt;/li&gt;
&lt;li&gt;It searches if the API body response would contain my searched word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To achieve both objectives, I only need the JDK library that contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/package-summary.html" rel="noopener noreferrer"&gt;java.net&lt;/a&gt; package that contains:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URI.html" rel="noopener noreferrer"&gt;URI&lt;/a&gt; → to adressing the request.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/package-summary.html" rel="noopener noreferrer"&gt;http&lt;/a&gt; sub-package with:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html" rel="noopener noreferrer"&gt;HttpClient&lt;/a&gt; → to send request and retrieve it response.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpRequest.html" rel="noopener noreferrer"&gt;HttpRequest&lt;/a&gt; → to build a request.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.html" rel="noopener noreferrer"&gt;HttpResponse&lt;/a&gt; → response object.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Getting a similar code like 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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.URI&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;java.net.http.HttpClient&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;java.net.http.HttpRequest&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;java.net.http.HttpResponse&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;class&lt;/span&gt; &lt;span class="nc"&gt;StarWarsWordFinder&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;STARWARS_URL_PEOPLE_API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://swapi.dev/api/people"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;foundTimes&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="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;searchingFor&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;word&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newHttpClient&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;httpRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpRequest&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;URI&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="no"&gt;STARWARS_URL_PEOPLE_API&lt;/span&gt;&lt;span class="o"&gt;))&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="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="n"&gt;httpClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpRequest&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BodyHandlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofString&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;HttpResponse:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenAccept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;searchingIn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&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="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s was found %s times"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;foundTimes&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&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;searchingIn&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;results&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;arg&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;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;foundTimes&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;I compile this source to generate a Library as explained in Creating a Java Library chapter, and I run the following terminal command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; .&lt;span class="se"&gt;\s&lt;/span&gt;tarWarsWordFinder.jar .&lt;span class="se"&gt;\S&lt;/span&gt;earchingInStarWarsFor.java Luke
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Luke was found 1 &lt;span class="nb"&gt;times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s try with Yoda:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; .&lt;span class="se"&gt;\s&lt;/span&gt;tarWarsWordFinder.jar .&lt;span class="se"&gt;\S&lt;/span&gt;earchingInStarWarsFor.java Yoda         
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Yoda was found 0 &lt;span class="nb"&gt;times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh! “&lt;em&gt;Forget someone seems the API...”🤣&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s try with Vader:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; .&lt;span class="se"&gt;\s&lt;/span&gt;tarWarsWordFinder.jar .&lt;span class="se"&gt;\S&lt;/span&gt;earchingInStarWarsFor.java Vader         
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Vader was found 1 &lt;span class="nb"&gt;times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;“I’m your API Daddy...&lt;/em&gt;” Ok, enough of older StarWars jokes!&lt;/p&gt;

&lt;p&gt;Let's try something else, backing to the code of the library. I could add an external library, to convert API string json response to an object, making it a little more specific in terms of only people's name scope.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/google/gson" rel="noopener noreferrer"&gt;Gson&lt;/a&gt; library could parse the string response to a JSON.&lt;/p&gt;

&lt;p&gt;Let’s see the source of StarWarsWordFinder code after adding Gson’s fromJson() 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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&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;java.net.URI&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;java.net.http.HttpClient&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;java.net.http.HttpRequest&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;java.net.http.HttpResponse&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;java.util.List&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;class&lt;/span&gt; &lt;span class="nc"&gt;StarWarsWordFinderWithGson&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;//same as last version class&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;searchingIn&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;results&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;arg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&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;Gson&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;StarWarsPeople&lt;/span&gt; &lt;span class="n"&gt;starWarsPeople&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StarWarsPeople&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="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StarWarsPerson&lt;/span&gt; &lt;span class="nl"&gt;starWarsPerson:&lt;/span&gt; &lt;span class="n"&gt;starWarsPeople&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResults&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;starWarsPerson&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="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;foundTimes&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StarWarsPeople&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StarWarsPerson&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;results&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StarWarsPerson&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getResults&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;results&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StarWarsPerson&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;String&lt;/span&gt; &lt;span class="n"&gt;name&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;getName&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;name&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;It was necessary to create two additional classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;StarWarsPeople&lt;/li&gt;
&lt;li&gt;StarWarsPerson&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To map the string results to the valid structure.&lt;/p&gt;

&lt;p&gt;So, running the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;javac &lt;span class="nt"&gt;-cp&lt;/span&gt; .&lt;span class="se"&gt;\g&lt;/span&gt;son-2.9.0.jar  &lt;span class="nt"&gt;-d&lt;/span&gt; build .&lt;span class="se"&gt;\S&lt;/span&gt;tarWarsWordFinderWithGson.java &lt;span class="c"&gt;#to get .class files&lt;/span&gt;
jar &lt;span class="nt"&gt;--create&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; starWarsWordFinder.jar .&lt;span class="se"&gt;\S&lt;/span&gt;tarWarsWordFinderWithGson.class &lt;span class="s1"&gt;'.\StarWarsWordFinderWithGson$StarWarsPeople.class'&lt;/span&gt; 
&lt;span class="s1"&gt;'.\StarWarsWordFinderWithGson$StarWarsPerson.class'&lt;/span&gt; &lt;span class="c"&gt;#to create the jar file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I get the new version of my library StarWarsWordFinderWithGson then I can run the main class, adding 2 jars, the gson and the starWarsWordFinder libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"starWarsWordFinder.jar;gson-2.9.0.jar"&lt;/span&gt; .&lt;span class="se"&gt;\S&lt;/span&gt;earchingInStarWarsWithGson.java Luke
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Luke was found 1 &lt;span class="nb"&gt;times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, resuming this in a nutshell&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A word needs to be found.&lt;/li&gt;
&lt;li&gt;Identify tools inside JDK library to achivet it.&lt;/li&gt;
&lt;li&gt;Build a java library with it.&lt;/li&gt;
&lt;li&gt;Instance and call it inside our main program.&lt;/li&gt;
&lt;li&gt;Compile it and running it&lt;/li&gt;
&lt;li&gt;Make some starwars boring joke...ok. no.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the end of handmade series , I covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thinkingoutcode.hashnode.dev/the-simple-and-satisfiying-art-of-executing-a-java-file-from-the-command-line" rel="noopener noreferrer"&gt;Run a Java program with related jar.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://thinkingoutcode.hashnode.dev/creating-a-java-library-a-place-where-any-problem-can-be-resolved" rel="noopener noreferrer"&gt;Create a jar&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://thinkingoutcode.hashnode.dev/build-a-rest-service-from-the-command-line-as-simple-as-every-request-has-a-response" rel="noopener noreferrer"&gt;Build a service using a known framework&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Consume an API, create a jar and use it to build a word finder java program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you enjoyed it like I enjoyed writing it. There are a lot more coming soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech stack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 11.&lt;/li&gt;
&lt;li&gt;Windows 10.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Repo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JesusIgnacio/starwars-word-finder" rel="noopener noreferrer"&gt;https://github.com/JesusIgnacio/starwars-word-finder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>luke</category>
      <category>starwars</category>
      <category>gson</category>
    </item>
    <item>
      <title>Build a rest service from the command line, as simple as “every request has a response.”</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Mon, 28 Mar 2022 12:20:48 +0000</pubDate>
      <link>https://dev.to/to_code/build-a-rest-service-from-the-command-line-as-simple-as-every-request-has-a-response-40j5</link>
      <guid>https://dev.to/to_code/build-a-rest-service-from-the-command-line-as-simple-as-every-request-has-a-response-40j5</guid>
      <description>&lt;p&gt;Following with &lt;strong&gt;Handmade Series with Java&lt;/strong&gt;, this is the 3rd chapter. I’ll make a rest service, as always, step by step, without IDEs.&lt;/p&gt;

&lt;p&gt;I'll use the  &lt;a href="https://sparkjava.com/" rel="noopener noreferrer"&gt;Spark&lt;/a&gt; library to getting a “pong” to every “ping” request.&lt;/p&gt;

&lt;p&gt;I declare a simple class called PingPongGame with &lt;strong&gt;main&lt;/strong&gt; method inside.&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;PingPongGame&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="c1"&gt;//nothing inside yet&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;Inside of the main method, call a static method named &lt;a href="https://sparkjava.com/documentation#routes" rel="noopener noreferrer"&gt;get&lt;/a&gt; , provided by Spark library, that contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A url path &lt;code&gt;/ping&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; verb http.&lt;/li&gt;
&lt;li&gt;Receiving a &lt;code&gt;req&lt;/code&gt; and &lt;code&gt;res&lt;/code&gt; object from request.&lt;/li&gt;
&lt;li&gt;Which finally return a response, a simple string “pong”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I add the current import from Spark library &lt;code&gt;spark.Spark.get&lt;/code&gt;, getting the code above:&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;static&lt;/span&gt; &lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Spark&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PingPongGame&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="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/ping"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;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;Before executing it, download the spark library, from the maven repository.&lt;/p&gt;

&lt;p&gt;After downloading it, place it inside PingPongGame class folder, it runs the next instruction through the command line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; .&lt;span class="se"&gt;\s&lt;/span&gt;park-core-2.9.3.jar .&lt;span class="se"&gt;\P&lt;/span&gt;ingPongGame.java
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Exception &lt;span class="k"&gt;in &lt;/span&gt;thread &lt;span class="s2"&gt;"main"&lt;/span&gt; java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
        at spark.Service.&amp;lt;clinit&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;Service.java:58&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Spark&lt;span class="nv"&gt;$SingletonHolder&lt;/span&gt;.&amp;lt;clinit&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;Spark.java:54&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Spark.getInstance&lt;span class="o"&gt;(&lt;/span&gt;Spark.java:58&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Spark.&amp;lt;clinit&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;Spark.java:64&lt;span class="o"&gt;)&lt;/span&gt;
        at HelloWorld.main&lt;span class="o"&gt;(&lt;/span&gt;HelloWorld.java:5&lt;span class="o"&gt;)&lt;/span&gt;
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass&lt;span class="o"&gt;(&lt;/span&gt;BuiltinClassLoader.java:581&lt;span class="o"&gt;)&lt;/span&gt;
        at java.base/jdk.internal.loader.ClassLoaders&lt;span class="nv"&gt;$AppClassLoader&lt;/span&gt;.loadClass&lt;span class="o"&gt;(&lt;/span&gt;ClassLoaders.java:178&lt;span class="o"&gt;)&lt;/span&gt;
        at java.base/java.lang.ClassLoader.loadClass&lt;span class="o"&gt;(&lt;/span&gt;ClassLoader.java:521&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Service.&amp;lt;clinit&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;Service.java:58&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Spark&lt;span class="nv"&gt;$SingletonHolder&lt;/span&gt;.&amp;lt;clinit&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;Spark.java:54&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Spark.getInstance&lt;span class="o"&gt;(&lt;/span&gt;Spark.java:58&lt;span class="o"&gt;)&lt;/span&gt;
        at spark.Spark.&amp;lt;clinit&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;Spark.java:64&lt;span class="o"&gt;)&lt;/span&gt;
        at HelloWorld.main&lt;span class="o"&gt;(&lt;/span&gt;HelloWorld.java:5&lt;span class="o"&gt;)&lt;/span&gt;
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0&lt;span class="o"&gt;(&lt;/span&gt;Native Method&lt;span class="o"&gt;)&lt;/span&gt;
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke&lt;span class="o"&gt;(&lt;/span&gt;NativeMethodAccessorImpl.java:62&lt;span class="o"&gt;)&lt;/span&gt;
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke&lt;span class="o"&gt;(&lt;/span&gt;DelegatingMethodAccessorImpl.java:43&lt;span class="o"&gt;)&lt;/span&gt;
        at java.base/java.lang.reflect.Method.invoke&lt;span class="o"&gt;(&lt;/span&gt;Method.java:566&lt;span class="o"&gt;)&lt;/span&gt;
        at jdk.compiler/com.sun.tools.javac.launcher.Main.execute&lt;span class="o"&gt;(&lt;/span&gt;Main.java:404&lt;span class="o"&gt;)&lt;/span&gt;
        at jdk.compiler/com.sun.tools.javac.launcher.Main.run&lt;span class="o"&gt;(&lt;/span&gt;Main.java:179&lt;span class="o"&gt;)&lt;/span&gt;
        at jdk.compiler/com.sun.tools.javac.launcher.Main.main&lt;span class="o"&gt;(&lt;/span&gt;Main.java:119&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cause Spark library by itself can’t run this instance, it depends on others libraries. The required jar libraries list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;slf4j-api&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spark-core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;javax.servlet-api&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jetty-server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jetty-util&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jetty-http&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jetty-io&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log4j-slf4j-impl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log4j-api&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log4j-core&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After downloading them, run the long command line above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"spark-core-2.9.3.jar;slf4j-api-1.7.25.jar;
javax.servlet-api-3.1.0.jar;jetty-server-9.4.31.v20200723.jar;
jetty-util-9.4.31.v20200723.jar;jetty-http-9.4.31.v20200723.jar;
jetty-io-9.4.31.v20200723.jar;log4j-slf4j-impl-2.17.2.jar;
log4j-api-2.17.2.jar;log4j-core-2.17.2.jar"&lt;/span&gt; .&lt;span class="se"&gt;\P&lt;/span&gt;ingPongGame.java
&lt;span class="c"&gt;#It prints nothing because the process has started to run, leaving the terminal in a waiting state.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, at this point, I need to verify if the rest service is “up &amp;amp; running” by executing this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:4567/ping
&lt;span class="c"&gt;#it should prints&lt;/span&gt;
pong!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, simple and effective, perhaps not too simple cause of the amount of added libraries, but still isn't to worry taking in count it made without IDEs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s all!&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pong&lt;/strong&gt; to my &lt;strong&gt;ping&lt;/strong&gt; needed.&lt;/li&gt;
&lt;li&gt;Creating a standar rest services.&lt;/li&gt;
&lt;li&gt;Using a method of a knowing library.&lt;/li&gt;
&lt;li&gt;Add it and test it.&lt;/li&gt;
&lt;li&gt;Problem happened(missing libraries).&lt;/li&gt;
&lt;li&gt;Adding missing libraries.&lt;/li&gt;
&lt;li&gt;Problem fixed.&lt;/li&gt;
&lt;li&gt;I got my &lt;strong&gt;pong&lt;/strong&gt; trought rest service.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Command and options dictionary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;java&lt;/code&gt; run .class and .java files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-cp&lt;/code&gt;indicate compiled folders directory(classpath).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;curl&lt;/code&gt; command to execute transfer to or from a server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tech stack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 11.&lt;/li&gt;
&lt;li&gt;Windows 10.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://sparkjava.com/" rel="noopener noreferrer"&gt;Spark-java&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Repo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JesusIgnacio/every-ping-has-a-pong" rel="noopener noreferrer"&gt;https://github.com/JesusIgnacio/every-ping-has-a-pong&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus track&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spark-java is a “microframework” as springboot but only based on functional programming with a simple implementation, I invited you to take in count in your read list the next article, to a deeper understanding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogs.oracle.com/javamagazine/post/web-microservices-development-in-java-that-will-spark-joy" rel="noopener noreferrer"&gt;Web microservices development in Java that will Spark joy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>spark</category>
      <category>pingpong</category>
      <category>restservice</category>
    </item>
    <item>
      <title>Creating a java library, a place where any problem can be resolved.</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Mon, 21 Mar 2022 12:39:14 +0000</pubDate>
      <link>https://dev.to/to_code/creating-a-java-library-a-place-where-any-problem-can-be-resolved-dd6</link>
      <guid>https://dev.to/to_code/creating-a-java-library-a-place-where-any-problem-can-be-resolved-dd6</guid>
      <description>&lt;p&gt;Starting with the next class, called SummerDelivery, a delivery service planned to refresh a hot summer day...&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;SummerDelivery&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;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nl"&gt;order:&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;switch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"PEACH_TENTATION"&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;"Peach Tentation Order..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="c1"&gt;//Anyone knows how to prepared it?&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"FROZEN_APPLE"&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;"Frozen Apple Order..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="c1"&gt;//Anyone knows how to prepared it?&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;default&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;"Unexpected Order..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;break&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;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if we running the command to order a PEACH_TENTATION or a FROZEN_APPLE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜ java .&lt;span class="se"&gt;\S&lt;/span&gt;ummerDelivery.java PEACH_TENTATION FROZEN_APPLE
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Peach Tentation Order...
Frozen Apple Order...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program doesn’t know how to prepare one of its offered beverages, it needs a source with beverages preparation knowledge.&lt;/p&gt;

&lt;p&gt;So, having the source below, capable of resolving SummerDelivered needs, called TropicalJuice:&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;TropicalJuice&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Storage&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;PEACH_JUICE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Peach juice"&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;APPLE_JUICE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Apple juice"&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;LIMON_JUICE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Limon juice"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;     
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Fridge&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;ICE_CUBES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ice cubes"&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;CHERRY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Cherry"&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;LIMON_SHOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Limon shot"&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JuiceMan&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;preparePeachTentation&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="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mixing a 250ml of %s with a %s and a few crushed %s."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
                &lt;span class="nc"&gt;Storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PEACH_JUICE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fridge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LIMON_SHOT&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fridge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ICE_CUBES&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;prepareFrozzenApple&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="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mixing a 250ml of %s with 2 parts of crushed %s adding 100ml of %s."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
                &lt;span class="nc"&gt;Storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLE_JUICE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fridge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ICE_CUBES&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LIMON_JUICE&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;It's necessary to include it inside SummerDelivery class to attend juice orders.&lt;/p&gt;

&lt;p&gt;First of all, we compile TropicalJuice to a class file, executing the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜ javac &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; .&lt;span class="se"&gt;\T&lt;/span&gt;ropicalJuice.java
&lt;span class="c"&gt;#it generates TropicalJuice.class,TropicalJuice$Fridge.class,TropicalJuice$JuiceMan.class,TropicalJuice$Storage.class&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After, we package their .class files generated in a storage called tropical.jar, our java library, running the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜ jar &lt;span class="nt"&gt;--create&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; tropical.jar .&lt;span class="se"&gt;\T&lt;/span&gt;ropicalJuice.class &lt;span class="s1"&gt;'.\TropicalJuice$Fridge.class'&lt;/span&gt; &lt;span class="s1"&gt;'.\TropicalJuice$JuiceMan.class'&lt;/span&gt; &lt;span class="s1"&gt;'.\TropicalJuice$Storage.class'&lt;/span&gt;
&lt;span class="c"&gt;#it generates a jar called tropical.jar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the created tropical.jar, we add to SummerDeliver class the library new methods.&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;SummerDelivery&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;static&lt;/span&gt; &lt;span class="nc"&gt;TropicalJuice&lt;/span&gt; &lt;span class="n"&gt;tropicalJuice&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;TropicalJuice&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;static&lt;/span&gt; &lt;span class="nc"&gt;TropicalJuice&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;JuiceMan&lt;/span&gt; &lt;span class="n"&gt;juiceMan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tropicalJuice&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JuiceMan&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;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nl"&gt;order:&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;switch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"PEACH_TENTATION"&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;"Peach Tentation Order..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;juiceMan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;preparePeachTentation&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"FROZZEN_APPLE"&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;"Frozen Apple Order..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;juiceMan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareFrozzenApple&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;default&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;"Unexpected Order..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;break&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;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding the library in the first executed command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜ java &lt;span class="nt"&gt;-cp&lt;/span&gt; .&lt;span class="se"&gt;\t&lt;/span&gt;ropical.jar .&lt;span class="se"&gt;\S&lt;/span&gt;ummerDelivery.java FROZZEN_APPLE PEACH_TENTATION WATER
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Frozen Apple Order...
Mixing a 250ml of Apple juice with 2 parts of crushed Ice cubes adding 100ml of Limon juice.
Peach Tentation Order...
Mixing a 250ml of Peach juice with a Limon shot and a few crushed Ice cubes.
Unexpected Order...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep! Now SummerDelivery knows how to refresh this summer! But it still doesn’t know how to serve a Water glass. If you know how to resolve it, please feel free to add it and test it to practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s all!&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A problem happened.&lt;/li&gt;
&lt;li&gt;We create a solution to solve it.&lt;/li&gt;
&lt;li&gt;Package the solution as a library.&lt;/li&gt;
&lt;li&gt;Add it and test it.&lt;/li&gt;
&lt;li&gt;Problem fixed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Command and options dictionary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;java&lt;/code&gt; run .class and .java files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;javac&lt;/code&gt;compile .java files and creates .class files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt;indicate output folder.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-cp&lt;/code&gt;indicate compiled folders directory(classpath).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jar&lt;/code&gt; to execute actions related to java libraries.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;—create&lt;/code&gt; indicate jar action command.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;—file&lt;/code&gt; indicates a name file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 11.&lt;/li&gt;
&lt;li&gt;Windows 10.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/JesusIgnacio/summer-delivery" rel="noopener noreferrer"&gt;https://github.com/JesusIgnacio/summer-delivery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>develop</category>
      <category>jvm</category>
      <category>jar</category>
    </item>
    <item>
      <title>The simple and satisfiying art of executing a java file from the command line.</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Sat, 19 Feb 2022 12:52:02 +0000</pubDate>
      <link>https://dev.to/to_code/the-simple-and-satisfiying-art-of-executing-a-java-file-from-the-command-line-559a</link>
      <guid>https://dev.to/to_code/the-simple-and-satisfiying-art-of-executing-a-java-file-from-the-command-line-559a</guid>
      <description>&lt;p&gt;Having the next java source&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;Salad&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="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;"I'm the best salad in this neighberhood!"&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;Run the command below, inside the folder source with &lt;code&gt;java&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java Salad.java
&lt;span class="c"&gt;#it prints&lt;/span&gt;
I&lt;span class="s1"&gt;'m the best salad in this neighberhood!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s create another Java file in the same folder.&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;Watermelon&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;talk&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;"I'm the best fruit!"&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;and call its method &lt;code&gt;talk&lt;/code&gt; in &lt;strong&gt;Salad class&lt;/strong&gt; contained in &lt;strong&gt;Salad file&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Salad&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="nc"&gt;Watermelon&lt;/span&gt; &lt;span class="n"&gt;watermelon&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;Watermelon&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="n"&gt;watermelon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;talk&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;span class="c1"&gt;//here&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;"I'm the best salad in this neighberhood!"&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;Let’s run the previous command once again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java Salad.java
&lt;span class="c"&gt;#it prints&lt;/span&gt;
Salad.java:3: error: cannot find symbol
        public static Watermelon watermelon &lt;span class="o"&gt;=&lt;/span&gt; new Watermelon&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      ^
  symbol:   class Watermelon
  location: class Salad
.&lt;span class="se"&gt;\S&lt;/span&gt;alad.java:3: error: cannot find symbol
        public static Watermelon watermelon &lt;span class="o"&gt;=&lt;/span&gt; new Watermelon&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                                                  ^
  symbol:   class Watermelon
  location: class Salad
2 errors
error: compilation failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because our &lt;strong&gt;Salad class&lt;/strong&gt; doesn’t know any about the &lt;strong&gt;Watermelon class&lt;/strong&gt;, thought the &lt;strong&gt;Watermelon class&lt;/strong&gt; contained inside the &lt;strong&gt;Watermelon file&lt;/strong&gt; knows how to talk, so let’s add some watermelon to our salad.&lt;/p&gt;

&lt;p&gt;At first, is neccesary to process our &lt;strong&gt;Watermelon file&lt;/strong&gt;  into our &lt;strong&gt;processedFruits folder&lt;/strong&gt; with the &lt;code&gt;javac&lt;/code&gt; command and &lt;code&gt;-d&lt;/code&gt; option to indicate folder location name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;javac &lt;span class="nt"&gt;-d&lt;/span&gt; processedFruits Watermelon.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, let’s add our &lt;strong&gt;processedFruits folder&lt;/strong&gt; to the original run command adding the &lt;code&gt;-cp&lt;/code&gt; option to indicate where are compiled our java source of &lt;strong&gt;Watermelon file.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"processedFruits&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; Salad.java
#it prints
I'm the best fruit!
I'm the best salad in this neighberhood!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it, simple but effective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run a standalone java file.&lt;/li&gt;
&lt;li&gt;Run a standalone java file adding compiled sources as need it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Command and options dictionary:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;java&lt;/code&gt; run .class and .java files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;javac&lt;/code&gt;compile .java files and creates .class files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt;indicate output folder.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-cp&lt;/code&gt;indicate compiled folders directory(classpath).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tech stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Java 11.&lt;/li&gt;
&lt;li&gt;Windows 10.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Repo
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/JesusIgnacio/salad-java-program" rel="noopener noreferrer"&gt;https://github.com/JesusIgnacio/salad-java-program&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javaseries</category>
      <category>handmade</category>
      <category>java</category>
      <category>noides</category>
    </item>
    <item>
      <title>A coding maintainable life balance</title>
      <dc:creator>Thinking out code</dc:creator>
      <pubDate>Sat, 16 Jan 2021 18:38:13 +0000</pubDate>
      <link>https://dev.to/to_code/a-coding-maintainable-life-balance-45hh</link>
      <guid>https://dev.to/to_code/a-coding-maintainable-life-balance-45hh</guid>
      <description>&lt;p&gt;Programming is like solving a puzzle or building a structure, you would never be bored if you are a creative type of person who loves to get involved with the building process and the final result but sometimes it turned into a frustrated and exhausting process but never forget that programming has to be fun, free to be, inspiring and simple. Fun to build, free to choose a way to solve a problem, inspiring to do the best we can, and simple to implement.&lt;/p&gt;

&lt;p&gt;Despite some programmers saying that coding is always a frustrating, stressful activity, it doesn’t! All human activities have a part of that, n’ coding it’s not the exception but its a beautiful experience like make a great dish for a passionate chef or execute a surgery for a talented doctor and when it turns into a stressful activity, take a break, get a cup of something, make a draw, express yourself in other ways, listen to some music, play a game, take a short walk, n’ go back later it helps, sometimes pushing n’ again, isn’t the correct way, programming is, first of all, a creative process, get used to it to see it in that way.&lt;/p&gt;

&lt;p&gt;Nowadays is very common to wrap this beautiful activity with money/project deadlines, pay bills needs, but is necessary to give its time and space for our brain to processing and get the best results and most important a coding maintainable life balance.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>programmers</category>
      <category>inspiring</category>
    </item>
  </channel>
</rss>
