<?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: Germano Schneider</title>
    <description>The latest articles on DEV Community by Germano Schneider (@germanoschneider).</description>
    <link>https://dev.to/germanoschneider</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%2F640984%2Fd5c63fee-3bf5-41a2-99ba-4230c1b499b6.jpg</url>
      <title>DEV Community: Germano Schneider</title>
      <link>https://dev.to/germanoschneider</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/germanoschneider"/>
    <language>en</language>
    <item>
      <title>Reactive vs Servlet Stack</title>
      <dc:creator>Germano Schneider</dc:creator>
      <pubDate>Wed, 10 Apr 2024 12:05:34 +0000</pubDate>
      <link>https://dev.to/germanoschneider/reactive-vs-servlet-stack-21i6</link>
      <guid>https://dev.to/germanoschneider/reactive-vs-servlet-stack-21i6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Are you wondering what is the best stack to use when creating a new Spring Boot application? Well, if you  don't have an answer, I believe I can help you through this article. First, let's establish that the goal of a stack is not to replace another, but to serve it's own unique purpose.&lt;/p&gt;

&lt;p&gt;Let's take a look at the main differences between the Reactive and Servlet Stack as well as the ideal uses of each one.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a stack?
&lt;/h2&gt;

&lt;p&gt;In the context of a Spring application, a stack is a resource package that determines the specific architecture, framework, etc. that an application requires. The Spring Framework has two different stacks:&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%2Fdxn1ik62m4twrucb1dub.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%2Fdxn1ik62m4twrucb1dub.png" alt="Image description" width="745" height="564"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Servlet Stack
&lt;/h2&gt;

&lt;p&gt;This is a classic! It was created by Spring and is the most commonly used by developers around the world. It supports some Servlet Containers such as Tomcat, Jetty, and Undertown. For this stack, we develop our code with the Spring MVC Framework.&lt;/p&gt;

&lt;p&gt;Synchronous and asynchronous calls can be used, but with the blocking/IO architecture. For every request, the user must wait for a response before proceeding. This model works over a thread pool, which is always incremented when there is a huge API call traffic. Consequently, you will have high hardware consumption when there is a large number of requests.&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%2Fbpu5r0lgwuog2mtdm8z5.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%2Fbpu5r0lgwuog2mtdm8z5.png" alt="Image description" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Reactive Stack
&lt;/h2&gt;

&lt;p&gt;After some years, the Spring Framework 5 released the Reactive Stack. The objective of this stack was to allow the Spring applications to have a higher performance during huge traffic data and large concurrency. But how does it do this? The Reactive Stack possesses new features such as non-blocking/IO architecture, Servlet Container 3.1, Netty Server, Spring WebFlux Framework, etc. It operates on a 'less is more' principle, as it can attend to large concurrency utilizing fewer hardware resources.&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%2Fu73qj6ne50u8flwwkrgv.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%2Fu73qj6ne50u8flwwkrgv.png" alt="Image description" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What stack should I choose for my Spring application?
&lt;/h2&gt;

&lt;p&gt;The anwser depends on your needs. When designing your application, you must ask yourself (or your team) some questions, such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How many requests am I waiting for?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do I have a team prepared to work with this?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is my budget?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finding new professionals with extensive experience in reactive programming can sometimes be challenging. As a result, some companies may opt for alternative strategies or technologies that incur lower operational costs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reactive vs Servlet Stack
&lt;/h2&gt;

&lt;p&gt;Let's reiterate that the purpose of these stacks is not to eliminate the other but to attend to specific needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Learning Path&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Servlet Stack caters to what developers are accustomed to developing presently, which is imperative code. It is easy to write, read and debug. In constrast, the Reactive Stack uses funcional programming, which requires a deeper understanding and the implementation of a more complex code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Execution Model&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two different execution models: The Reactive Stack applies an Event Loop, similar to NodeJS. It has the capacity to handle many requests from the client with only a few threads. All requests are processed in an event queue. When a new request is received, the thread is released and a callback is always registered. For the Servlet stack, however, we implement the Thread per Request Model to handle requests. This model works over a thread pool, blocking each incoming request on the Servlet API. Once the thread’s number runs out, we must wait until one of them is released. There is a significant amount of hardware resource consumption with this model. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Non-Blocking/IO vs Blocking/IO&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Blocking/IO is an architecture type utilized on the Servlet API. Although we are able to execute asynchronous operations with Spring MVC, it is limited when a request arrives at the Servlet API because the server will block all completed remote calls. The Reactive Stack brought the Servlet API 3.1 and the Netty Server, which both support Non-Blocking/IO processes, removing the need for the final user to wait for a response.   &lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This was a short theoretical article written with the intention of emphasizing the importance of distinguishing between both Spring Stacks. Be mindful of data traffic volume as well as concurrency within the application when creating a new Spring application. This is crucial when reducing the cost and number of resources consumed.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Spring Conferences: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=CUDq2f3m15U"&gt;https://www.youtube.com/watch?v=CUDq2f3m15U&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=_Orluu4VhmY"&gt;https://www.youtube.com/watch?v=_Orluu4VhmY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=fiR7MWoTYjs"&gt;https://www.youtube.com/watch?v=fiR7MWoTYjs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=ODzY5uJfzDI"&gt;https://www.youtube.com/watch?v=ODzY5uJfzDI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Official Documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-framework/reference/web.html"&gt;https://docs.spring.io/spring-framework/reference/web.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-framework/reference/web-reactive.html"&gt;https://docs.spring.io/spring-framework/reference/web-reactive.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>spring</category>
      <category>reactive</category>
      <category>servlet</category>
    </item>
    <item>
      <title>SSE - How to implement it with Spring Boot</title>
      <dc:creator>Germano Schneider</dc:creator>
      <pubDate>Mon, 04 Mar 2024 21:47:41 +0000</pubDate>
      <link>https://dev.to/germanoschneider/sse-how-to-implement-it-with-spring-boot-14i1</link>
      <guid>https://dev.to/germanoschneider/sse-how-to-implement-it-with-spring-boot-14i1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever heard about SSE (Server-Sent-Events) before? It is a one-way messaging technology that works over the HTTP protocol and you can send messages from the server to the client. So, every time there is available data, the client will receive and update it in real-time. &lt;/p&gt;




&lt;h2&gt;
  
  
  How it works:
&lt;/h2&gt;

&lt;p&gt;SSE has unidirectional communication, only the server sends events to the client, the events are captured by the EventSource API from JavaScript, which the browser uses to listen to events (we'll discuss this in detail later in the article). Using SSE, it's not possible to send binary data, only messages. We can find some SSE use cases in weather, sports, stock exchange applications, and so on.&lt;/p&gt;




&lt;h2&gt;
  
  
  Is SSE the only option?
&lt;/h2&gt;

&lt;p&gt;There is more than one option instead of SSE, but neither is better or worse than the other, it depends on your needs. Besides SSE, you can find some alternatives like WebSocket and event data pooling, but if you only need to get some received data from the server, maybe SSE could be the best choice. Let me explain to you the differences between both:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WebSocket&lt;/strong&gt;&lt;br&gt;
A little bit different from SSE, the WebSocket is a protocol that has bidirectional communication between the client and server. Besides messages, it's also possible to send binaries in the payload. Some WebSocket use cases are chat applications and multiplayer games, which both require full-duplex communication.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event Data Pooling&lt;/strong&gt;&lt;br&gt;
Unlike SSE and WebSocket, the client should request data to the server, it usually takes more hardware resources because a lot of requests can be made until the server responds.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How is SSE implemented using Spring Boot?
&lt;/h2&gt;

&lt;p&gt;Considering the article's focus is SSE, we will implement a practice example about how to use it in a Java Application, with the Spring Boot Framework.&lt;/p&gt;

&lt;p&gt;We will use the Servlet Stack (MVC) because it's simple to understand and most developers are used to developing with imperative code. But, you can also implement it using the Reactive Stack (WebFlux). &lt;/p&gt;

&lt;p&gt;Now, let's go straight to our use case.&lt;/p&gt;




&lt;h2&gt;
  
  
  Food Delivery
&lt;/h2&gt;

&lt;p&gt;Let's try to understand how it works through a food delivery system. What we want to do is show the order progress to the user, the available statuses are: &lt;strong&gt;Order Placed&lt;/strong&gt;, &lt;strong&gt;In the Kitchen&lt;/strong&gt;, &lt;strong&gt;On the Way&lt;/strong&gt;, and &lt;strong&gt;Delivered&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Considering it's only a prototype to illustrate an SSE use case, the system will take care of all order steps automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating an SSE entry point
&lt;/h2&gt;

&lt;p&gt;First of all, we need to declare an endpoint in our controller that returns a SseEmitter interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private final Collection&amp;lt;SseEmitter&amp;gt; emitters = new CopyOnWriteArrayList&amp;lt;&amp;gt;();

@GetMapping(path = "/order-status", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
SseEmitter orderStatus() {

   SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);

   emitter.onCompletion(() -&amp;gt; emitters.remove(emitter));
   emitter.onTimeout(() -&amp;gt; emitters.remove(emitter));
   emitter.onError(throwable -&amp;gt; {
      emitters.remove(emitter);
      emitter.completeWithError(throwable);
   });

   emitters.add(emitter);

   return emitter;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the interface signature, we put the media type as a &lt;strong&gt;TEXT_EVENT_STREAM_VALUE&lt;/strong&gt; to send real-time events to the client. Our method body is composed of a new SseEmitter added to a concurrent list to make broadcast sending possible. We also declare some events callback whenever a completion, error, or timeout happens.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Declaring who needs to know about the order
&lt;/h2&gt;

&lt;p&gt;Once we have connected users in our endpoint, how can we determine that an order has arrived and needs to be prepared? Well, considering we want to send events to the client when the order changes status, why not apply an observable pattern and notify all listeners after each change? &lt;/p&gt;

&lt;p&gt;Let's create a listener and register all observables representing each order status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class OrderFoodListener {

    private final EventService eventService;

    private final Collection&amp;lt;Observer&amp;gt; observers;

    public OrderFoodListener(EventService eventService) {
        this.eventService = eventService;
        this.observers = List.of(
                new OrderObservable(eventService),
                new KitchenObservable(eventService),
                new OnTheWayObservable(eventService),
                new DeliveredObservable(eventService)
        );
    }

   public void notifyAll(OrderFood orderFood) {
        observers.forEach(foodObserver -&amp;gt; foodObserver.update(orderFood));
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain to you what is happening here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event Service Interface&lt;/strong&gt;: It's a dependency inversion interface of the way we go to send the events (concrete class should be declared in our infrastructure layer) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observers Collection&lt;/strong&gt;: All observers that we want to notify when an order comes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notify Method&lt;/strong&gt;: The notifyAll method will be called to notify all observers about a new order. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Notifying the the customer's order
&lt;/h2&gt;

&lt;p&gt;As we can see in our previous coding block, there are four &lt;br&gt;
  observables subscribed, each one with its own business rules.&lt;/p&gt;

&lt;p&gt;Let me show you how we are going to notify the customer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An order is coming&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (orderFood.getStatus() == ORDER_PLACED) {

   sendEvent(orderFood, "order");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The order observable checks if the initial status is an order placed, if so it sends an event with the "order" event name. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's going to the kitchen&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (orderFood.getStatus() == FoodStatus.ORDER_PLACED) {

   orderFood.setStatus(FoodStatus.IN_THE_KITCHEN);
   sendEvent(orderFood, "kitchen");
   waitForProcess();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After our order is placed, it goes to the kitchen, so here we need to check if the previous status is still the order placed, then we change it and send a "kitchen" event with the updated status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OBS.&lt;/strong&gt; The &lt;strong&gt;waitForProcess()&lt;/strong&gt; method is a thread sleep declaration to simulate a kitchen duration process&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now it's up to the delivery person&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (orderFood.getStatus() == IN_THE_KITCHEN) {

   orderFood.setStatus(ON_THE_WAY);
   sendEvent(orderFood, "on-the-way");
   waitForProcess();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before the order goes out, we need to check if it was in the kitchen, if so the user will be updated with the on-the-way status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finally, the order has arrived&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (orderFood.getStatus() == FoodStatus.ON_THE_WAY) {
    orderFood.setStatus(FoodStatus.DELIVERED);
    sendEvent(orderFood, "delivered");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's time to celebrate and notify the user that it has arrived.&lt;/p&gt;




&lt;h2&gt;
  
  
  Receiving events on the client side
&lt;/h2&gt;

&lt;p&gt;On the client side, the user will be waiting for order updates. So, let's implement it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var eventSource = new EventSource("/order-status");

eventSource.addEventListener("order", (event) =&amp;gt; renderEvent(event));

eventSource.addEventListener("kitchen", (event) =&amp;gt; renderEvent(event));

eventSource.addEventListener("on-the-way", (event) =&amp;gt; renderEvent(event));

eventSource.addEventListener("delivered", (event) =&amp;gt; renderEvent(event));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created a simple static HTML file and put some JavaScript to listen to all events from the server and print them on the screen. &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%2Fellez8ad1mylprx9tn9s.gif" 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%2Fellez8ad1mylprx9tn9s.gif" alt="order status updating" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope that in this article you were able to understand the main SSE concepts and know their differences between similar technologies. Additionally, we saw a practice example of how to implement it using the Spring Boot framework.&lt;/p&gt;

&lt;p&gt;If you have any questions, please feel free to leave your comments below and I will try to help you.&lt;/p&gt;

&lt;p&gt;I encourage you to check my GitHub repository and take a look at the whole code used in this article: &lt;a href="https://github.com/GermanoSchneider/food-delivery-sse-app"&gt;https://github.com/GermanoSchneider/food-delivery-sse-app&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Thank you, hope that I can see you next time.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=nxakp15CACY&amp;amp;t=2334s"&gt;https://www.youtube.com/watch?v=nxakp15CACY&amp;amp;t=2334s&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=nxakp15CACY&amp;amp;t=2334s"&gt;https://www.youtube.com/watch?v=nxakp15CACY&amp;amp;t=2334s&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sse</category>
      <category>springboot</category>
      <category>realtime</category>
    </item>
    <item>
      <title>Chunk vs Tasklet, which one should I use?</title>
      <dc:creator>Germano Schneider</dc:creator>
      <pubDate>Wed, 07 Feb 2024 22:20:53 +0000</pubDate>
      <link>https://dev.to/germanoschneider/chunklet-vs-tasklet-which-one-should-i-use-43k3</link>
      <guid>https://dev.to/germanoschneider/chunklet-vs-tasklet-which-one-should-i-use-43k3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Commonly we search for good alternatives when the content is high application data consumption. In Java development, we can use Spring Batch as a light and resilient option to execute daily schedulers to process a huge amount of data. In addition, it's possible to do it in small, medium, or even big batches to optimize the application memory consumption. &lt;/p&gt;

&lt;p&gt;Part of the Spring Batch ecosystem is about step executions included in a job. So, there are two definition types for it, they are called &lt;strong&gt;Chunk&lt;/strong&gt; and &lt;strong&gt;Tasklet&lt;/strong&gt;. I will explain both in detail to you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chunk
&lt;/h2&gt;

&lt;p&gt;Try to figure out a scenario where your application needs to read a thousand registers from a table that returns integer numbers, then you need to sort all data in ascending order. For example, if the returned number is &lt;strong&gt;54321&lt;/strong&gt;, it should be sorted to &lt;strong&gt;12345&lt;/strong&gt;. Finally, the processed data should be updated in the database. &lt;/p&gt;

&lt;p&gt;Given this scenario, we can create a job that will execute ten separate batches, each executing a hundred registers each time. This way, the application will manage and process the data with little memory consumption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
Step sortNumbersInNaturalOrderStep(JobRepository jobRepository, PlatformTransactionManager platformTransactionManager) {

    return new StepBuilder("sortNumbersInNaturalOrderStep", jobRepository)
     .&amp;lt;Map&amp;lt;Integer, Integer&amp;gt;, Map&amp;lt;Integer, Integer&amp;gt;&amp;gt;chunk(10, platformTransactionManager)
     .reader(cursorItemReader())
     .processor(new SortNumberProcessor())
     .writer(new NumberWriter(dataSource))
     .build();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have a step called &lt;strong&gt;sortNumbersInNaturalOrderStep&lt;/strong&gt;, it has a chunk that will receive and process a map of integers, where the key is the ID, and the value will be the processed number. In addition, we are setting the item’s quantity (10) to be processed in each batch and also a transaction manager. &lt;/p&gt;

&lt;p&gt;When we work with the chunk concept, we should attribute a reader, processor, and writer. To make it clearer, I will explain how each one works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Reader&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A reader should read the data from some specific source, it can be a JSON file or even a database. In our example we are setting a reader implementation from an abstraction offered by Spring Batch, it’s called &lt;strong&gt;JdbcCursorItemReader&lt;/strong&gt;. It reads the data from a specific JDBC data source, which should be informed. In this example, we are getting all data from the numbers table in an H2-embedded database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
JdbcCursorItemReader&amp;lt;Map&amp;lt;Integer, Integer&amp;gt;&amp;gt; cursorItemReader() {

    JdbcCursorItemReader&amp;lt;Map&amp;lt;Integer, Integer&amp;gt;&amp;gt; reader = new JdbcCursorItemReader&amp;lt;&amp;gt;();

    reader.setSql("SELECT * FROM numbers");
    reader.setDataSource(dataSource);
    reader.setRowMapper(new DatabaseRowMapper());

    return reader;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are doing a SELECT statement in the database to find all the data. Note that we also set a &lt;strong&gt;DatabaseRowMapper&lt;/strong&gt;, this is to map the received value from the database and transform it into a map of integers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public Map&amp;lt;Integer, Integer&amp;gt; mapRow(ResultSet rs, int rowNum) throws SQLException {

      Map&amp;lt;Integer, Integer&amp;gt; map = new HashMap&amp;lt;&amp;gt;();

      map.put(rs.getInt("id"), rs.getInt("number"));

      return map;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mapRow interface returns a map with the ID and number from the numbers table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Processor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an optional configuration, we could only read the data and then write it, without having to inform a processor. But, for this example, we are setting a processor to sort each number that we received from the reader step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public Map&amp;lt;Integer, Integer&amp;gt; process(Map&amp;lt;Integer, Integer&amp;gt; item) throws Exception {

      final Map&amp;lt;Integer, Integer&amp;gt; newMap = new HashMap&amp;lt;&amp;gt;();

      for (Map.Entry&amp;lt;Integer, Integer&amp;gt; mapValue : item.entrySet()) {

         Integer key = mapValue.getKey();
         Integer value = mapValue.getValue();

         List&amp;lt;String&amp;gt; numbers = new ArrayList&amp;lt;&amp;gt;(stream(value.toString()
                    .split(""))
                    .toList());

         numbers.sort(Comparator.naturalOrder());

         Integer newValue = parseInt(join("", numbers));

         newMap.put(key, newValue);
     }

     return newMap;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we are doing here is getting each map, capturing the ID and number, and then sorting it to return a newly updated map with the all ordered numbers.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Writer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the data is processed, it goes to the writer layer which will be responsible for updating the number on the database according to the given ID. The items are bonded in a list and then we iterate and update the captured value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public void write(Chunk&amp;lt;? extends Map&amp;lt;Integer, Integer&amp;gt;&amp;gt; chunk) throws Exception {

        for (Map&amp;lt;Integer, Integer&amp;gt; value : chunk.getItems()) {

           for (Map.Entry&amp;lt;Integer, Integer&amp;gt; mapValue : value.entrySet())
              jdbcTemplate.update("UPDATE numbers SET number = (?) WHERE id = (?)", mapValue.getValue(), mapValue.getKey());
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Tasklet
&lt;/h2&gt;

&lt;p&gt;Unlike the chunk’s concept, the tasklet step assumes the responsibility to execute a unique task individually. There’s no necessity to process the data in multiple batches. We can use, for example, a tasklet execution if we need to remove duplicated registers from the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

      String sql = "DELETE FROM numbers t1 WHERE t1.id &amp;gt; (SELECT MIN(t2.id) FROM numbers t2 WHERE t1.number = t2.number)";

      jdbcTemplate.execute(sql);

      return RepeatStatus.FINISHED;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, we put a DELETE statement to remove all duplicated data from the database. So, the only thing that we need to do is invoke this step after the previous one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It's not so difficult, is it? The purpose here was to share a little bit about the main concepts between Chunk and Tasklet. Please note that the task’s execution should be managed by you, the Spring Batch framework usually works with some common schedulers, like the Spring Scheduler, Control-M, and so on.   &lt;/p&gt;

&lt;p&gt;Do you still have questions or concerns about Chunk and Tasklet? Please, look at the official Spring Batch documentation to complement your knowledge about it, or leave your comment here, and I will try to help you.&lt;/p&gt;

&lt;p&gt;To see the whole code used in this article, please take a look at my GitHub: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/GermanoSchneider/spring-batch-overview"&gt;https://github.com/GermanoSchneider/spring-batch-overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you, see you next time.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.spring.io/spring-batch/reference/index.html"&gt;https://docs.spring.io/spring-batch/reference/index.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>springbatch</category>
      <category>springboot</category>
    </item>
  </channel>
</rss>
