<?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: Mircea Sirghi</title>
    <description>The latest articles on DEV Community by Mircea Sirghi (@hackus).</description>
    <link>https://dev.to/hackus</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%2F1128771%2Fa0ac6ce7-9db5-4e7b-a49d-15c3d1b00691.jpg</url>
      <title>DEV Community: Mircea Sirghi</title>
      <link>https://dev.to/hackus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hackus"/>
    <language>en</language>
    <item>
      <title>BFF</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Sat, 08 Feb 2025 16:30:56 +0000</pubDate>
      <link>https://dev.to/hackus/bff-4lo0</link>
      <guid>https://dev.to/hackus/bff-4lo0</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Heard recently about BFF. I have used it before, however, I like when people, become enthusiastic about a technology. It is so interesting almost funny, it also drives the incentive to discover it more.&lt;/p&gt;

&lt;p&gt;I have refreshed myself on the topic, read a couple of articles and spotted a pattern. This article is about the dissonance I am feeling, after I used BFF, with what is being written about it, and what can be truly beneficial about it, in my opinion.  &lt;/p&gt;

&lt;h2&gt;
  
  
  A little bit about the name
&lt;/h2&gt;

&lt;p&gt;"Backend For Frontend" - if you call it this way you follow the usage coined by Phil Calçado &lt;a href="//#PhilCalcado.com"&gt;PhilCalcado.com&lt;/a&gt; - BEFFE, however, it was shrunk to BFF by Nick Fisher. I think Phil Calçado is the first who described this pattern, though.  &lt;/p&gt;

&lt;p&gt;"Backend For Frontends" - if you call it this way you follow the usage promoted by Sam Newman &lt;a href="//#SamNewman.io"&gt;SamNewman.io&lt;/a&gt; who adds some additional flavors to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Description
&lt;/h2&gt;

&lt;p&gt;As &lt;a href="//#PhilCalcado.com"&gt;PhilCalcado.com&lt;/a&gt; describes, it is a pattern that facilitates communication between FE with only one BE. For example segregated between Web and Mobile, you have one Mobile FE communicating with Mobile BFF, similarly for Web. &lt;/p&gt;

&lt;p&gt;However, how it is used in reality or at least how I have seen it used, is that each domain be that, invoice, order, bill, contracts, etc. has it's own BFF. This is closer to how Sam Newman describes it &lt;a href="//#SamNewman.io"&gt;SamNewman.io&lt;/a&gt;, however, at an even more granular level. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feimterv191joi70t7nj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feimterv191joi70t7nj7.png" alt="Image description" width="377" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So it may solve the problem for the FE, as FE doesn't need to call various services, however, it just shifted towards BE.&lt;/p&gt;

&lt;p&gt;Now, what it means to add a single field in a form? I will show two cases, the preferable one, and the worst case one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preferable flow to add one field
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmqxdsn93xuy4efckydzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmqxdsn93xuy4efckydzg.png" alt="Image description" width="565" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 3 PRs needed to add a single field. Just for visualizing it, each PR consists of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open PR&lt;/li&gt;
&lt;li&gt;Receive approvals&lt;/li&gt;
&lt;li&gt;Merge it&lt;/li&gt;
&lt;li&gt;Deploy it on DEV&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Worst case flow to add one field
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7042k5diw717l02gilu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7042k5diw717l02gilu.png" alt="Image description" width="758" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bxm8f4ts4r6s99h8t1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bxm8f4ts4r6s99h8t1y.png" alt="Image description" width="500" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Phil Calçado's &lt;a href="//#PhilCalcado.com"&gt;PhilCalcado.com&lt;/a&gt; diagrams show they were making similar calls from BFFs, ending up defining a new layer to handle them, the so called "Application Service". I think they came to this solution because they didn't allow communication between Services in the first place, so they ended up building an additional layer. I would rather allow services call each other. Sam Newman also proposes the architecture where Services can call each other as an alternative. &lt;/p&gt;

&lt;p&gt;Sam Newman proposes BFF for third party integrations also. I think the reason is that API can evolve internally quicker, and a BFF layer can help keeping a backward compatible communication. &lt;/p&gt;

&lt;h2&gt;
  
  
  How it is being promoted
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq7onkwn1testrh39tlg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq7onkwn1testrh39tlg.png" alt="Image description" width="377" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BFFs can call any service, if required. I guess it also means that if the delivery is streamlined per domain you are still constrained to keep the backward compatibility at the service level because other BFFs, not from your domain, may call your service. Isn't it somehow evident or I am missing something ? I see this as an overhead, these systems hardly evolve, or evolve slowly(through API versioning), consequence to interdependencies.&lt;/p&gt;

&lt;p&gt;However if you change the approach and allow services to communicate at the same time ban BFFs to call other services except from it's own domain then the meaning of BFF is diminished. You can directly send the response in the format FE expects without an intermediate layer to agregate info. ¯\&lt;em&gt;_(ツ)&lt;/em&gt;_/¯&lt;/p&gt;

&lt;p&gt;Maybe I am wrong, but I have started to think that the incentive for this patterns is driven by the rule of disallowing Services to communicate between them and, most probably, to avoid single point of failure provided by using a gateway layered architecture. &lt;/p&gt;

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

&lt;p&gt;Putting everything together I realized the dissonance between how I have seen it used with how it is proposed to be used by authors, and how articles on this subject propose it. It took me a while to dissipate feelings about it and start objectively analyzing. &lt;/p&gt;

&lt;p&gt;The way Phil Calçado describes it, makes a lot of sense to me, as they evolved their approach to a BFF layered one. And they coined it over an app with Mobile and Web interfaces. It dissonates with how I have seen this architecture applied per domain, where each team hold ownership over their BFF, and due to the lack of service gateway/discovery we had to maintain hard-coded urls per environment. I also found it cumbersome to implement changes on Service layer still having to cascade them to BFF layer. The amount of DTOs is big and redundant. Can be solved using libraries, but we weren't.&lt;/p&gt;

&lt;p&gt;It is amazing how SoundCloud allowed projects to evolve. It was a well-founded process, every step was a particular solution to an emerging problem. This leads to concluding that an application evolving to BFF becomes much more suitable than it being applied from the start, as it just disables the teams to tailor their approach to client needs. Basically they loose adaptability. Isn't it an important factor? &lt;/p&gt;

&lt;p&gt;Adding a new field means at least 3-4 PRs. There is a bunch of logs to consider to find a defect root cause. Each request consists of FE-&amp;gt;BFF-&amp;gt;Service-&amp;gt;BFF-&amp;gt;FE =&amp;gt; 4 request, 8 message marshaling/unmarshaling, 12 chances something is not working(DB excluded). Code duplication is a concern. An additional layer is an overhead to me.&lt;/p&gt;

&lt;p&gt;As opposed to gateway layered architecture BFF avoids single point of failure. Which has its benefits.&lt;/p&gt;

&lt;p&gt;Overall it is an interesting approach, and while writing this article I became less reticent to using it in a gradually evolving manner as Authors describe it.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://samnewman.io/patterns/architectural/bff/" rel="noopener noreferrer"&gt;SamNewman.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://philcalcado.com/2015/09/18/the_back_end_for_front_end_pattern_bff.html" rel="noopener noreferrer"&gt;PhilCalcado.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends&amp;lt;br&amp;gt;%0A" rel="noopener noreferrer"&gt;Learn.microsoft.com&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Javascript "multithreading"</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Sun, 02 Feb 2025 00:19:11 +0000</pubDate>
      <link>https://dev.to/hackus/javascript-multithreading-31g9</link>
      <guid>https://dev.to/hackus/javascript-multithreading-31g9</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Yes, limited, however, it can run code and render content in parallel. Contrary to widespread opinion that it can't. You see, Java is also single threaded if Threads are not used, isn't it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F329ghi6ccqqle51cjq2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F329ghi6ccqqle51cjq2d.png" alt="Image description" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think that devs who have been using single-threaded JS for the whole career become deeply offended when somebody inaccurately mentions multithreading. &lt;/p&gt;

&lt;p&gt;I have browsed a little bit on this subject and everybody who mentions JS is single-threaded omits to specify their source - &lt;strong&gt;always&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx758u56l6myirgbpoxkd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx758u56l6myirgbpoxkd.png" alt="Image description" width="500" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have tried to find this proof in Ecma-international standard, with no success. Maybe I am looking in the wrong place? However, here is the formulation from Mozilla developers: &lt;/p&gt;

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

&lt;p&gt;And mozilla source is recomended from Javascript-manual. So there are sources that discuss Threads in JS. And almost all sources mention Web Workers. This is what this article is about. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ag0n8s3rs4hxfd1ztux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ag0n8s3rs4hxfd1ztux.png" alt="Image description" width="500" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Workers
&lt;/h2&gt;

&lt;p&gt;It took me a while to understand how Web Workers work. How they interact with main thread, and how main thread interacts with Web Workers. I need to confess, I am not a JS developer, however I create JS scripts occasionally. &lt;/p&gt;

&lt;p&gt;So what is a web worker? It is just a Worker instance in JS that loads a  script and runs it. Additionally it has an API that allows communication between main and worker threads. &lt;/p&gt;

&lt;p&gt;To demonstrate how they work, I imagined the following scenario, I want to display content on a web page that is generated from different Workers in parallel, so that it is clear from the content which Worker generated it. &lt;/p&gt;

&lt;p&gt;Basically I want to have a button "Start worker" and whenever I press it a new Worker is created and added to the Pool(map) of existing workers. When I press "Stop workers" all workers are closed and content is cleared. &lt;/p&gt;

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

&lt;p&gt;Each time "Start worker" button is pressed a new Worker is created by loading &lt;code&gt;worker.js&lt;/code&gt; and receiving a startup message composed of &lt;code&gt;["Worker name", "Start"]&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;All workers are closed by sending termination command to each worker &lt;code&gt;["Worker name", "Stop"]&lt;/code&gt;, "Worker name" is not yet used while closing, however it may be useful to stop a particular worker, &lt;strong&gt;in the future&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qrnjvvp026vvsbsi350.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qrnjvvp026vvsbsi350.png" alt="Image description" width="499" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Current browsers have a security CORS policy and don't allow for a script to be loaded from local machine, only from a Web Server. But I want this application to work without additional setup. Thus the solution I found was to load the worker.js file in an input field and from there to use it to instantiate Workers.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Demonstration
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;concurent/index.html&lt;/code&gt; in browser, load &lt;code&gt;concurent/worker.js&lt;/code&gt;, press "Start worker" button a couple of times and observe how content is being generated&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7sf3aai2viiwn9cqedp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7sf3aai2viiwn9cqedp.png" alt="Image description" width="754" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Even if Worker threads run in parallel, the listener is in main thread, which makes responses become queued. This invalidates the parallelism as the content is sequentially added. JS may have the capability for multithreading but limited to a concurent way when messages are passed from Workers to main thread. It is not possible to generate content in parallel. However, there is still a way to get parallelism...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9rphopm4637bjkwllcy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9rphopm4637bjkwllcy3.png" alt="Image description" width="250" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallel Javascript
&lt;/h2&gt;

&lt;p&gt;The only way to render content in parallel is through OffscreenCanvas. Pass the canvas handling to the worker thread and it will work in parallel with the main thread. A canvas can be attached to a worker only once. It is not possible to send the same canvas to multiple workers, though. &lt;/p&gt;

&lt;p&gt;I have also learned a better way to load &lt;code&gt;worker.js&lt;/code&gt; from here: &lt;a href="//#Web.dev"&gt;Web.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;parallel/index.html&lt;/code&gt; in browser, press "Start worker"/"Stop workers", observe how content is rendered in parallel.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wgb76svza8jbt19niah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wgb76svza8jbt19niah.png" alt="Image description" width="492" height="773"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final conclusion
&lt;/h2&gt;

&lt;p&gt;As I see it, it is not a limitation of JS, it is just how browsers currently render the DOM tree, it is not thread safe. Imagine some content being rendered at the same time with a worker changing or removing it. The obvious solution, or the easiest, so to speak, would be to make it thread safe by forcing synchronous acces. But this is how it currently works with a single thread. Even better, main thread never competes for getting access to the DOM tree. Here is a good resource to learn about it &lt;a href="//#Developer.mozilla.org"&gt;Developer.mozilla.org&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Repo
&lt;/h2&gt;

&lt;p&gt;Code is available in Github&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://262.ecma-international.org/6.0/" rel="noopener noreferrer"&gt;Ecma-international&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.info/manuals-specifications" rel="noopener noreferrer"&gt;Javascript-manual&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://startbootstrap.com/template/simple-sidebar" rel="noopener noreferrer"&gt;Startbootstrap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hackus/javascript-multithreading" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/articles/offscreen-canvas" rel="noopener noreferrer"&gt;Web.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work" rel="noopener noreferrer"&gt;Developer.mozilla.org&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Scala Full-Stack templates</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Tue, 14 Jan 2025 13:00:21 +0000</pubDate>
      <link>https://dev.to/hackus/scala-full-stack-templates-16ea</link>
      <guid>https://dev.to/hackus/scala-full-stack-templates-16ea</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;When I started to build Scala full stack projects I observed there are various frameworks and information is scattered all over the internet which is disconcerting. Especially annoying is that I could not find a book that would tackle this aspect sufficiently. &lt;/p&gt;

&lt;p&gt;There are lots of templates available however who can tell which is the difference between them in a concise manner ?&lt;/p&gt;

&lt;p&gt;In this article I am gathering main full stack examples I can find. &lt;/p&gt;

&lt;h2&gt;
  
  
  Scala full-stack with
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scala3&lt;/li&gt;
&lt;li&gt;Htt4s&lt;/li&gt;
&lt;li&gt;ScalaJs&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this template I used the repo outline proposed in this tutorial IdiomaticSoft as it is close to what I am using in Java full-stack. &lt;/p&gt;

&lt;p&gt;I have also used ScalaJs integration from RockTheJvm along with fixes for package versions. RockTheJvm tutorial also integrates with database/docker, therefore provides an extended insight into the approach. I want to keep templates concise so any integration is left outside the scope. &lt;/p&gt;

&lt;p&gt;After I created the template I realized that it is suitable to use Typescript instead of Javascript. Thus changing the client to whatever FE framework is available is suitable with least impact on the concept.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;Common - (Domain) shared code - DTOs&lt;br&gt;
Client - FE code&lt;br&gt;
Server - BE code&lt;/p&gt;

&lt;h4&gt;
  
  
  Common Module
&lt;/h4&gt;

&lt;p&gt;Contains DTOs shared between Client and Server.&lt;/p&gt;

&lt;h4&gt;
  
  
  Client
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Build vite.js project&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;ClientApp.scala&lt;/code&gt; which calls BE to get all products. It transforms the list of products into html content and fill it in &lt;code&gt;&amp;lt;... id="app"&amp;gt;&lt;/code&gt; from index.html&lt;/li&gt;
&lt;li&gt;Add the following field and script to &lt;code&gt;index.html&lt;/code&gt;, the rest of its content is not needed
&lt;code&gt;&amp;lt;div id="app"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;
&lt;code&gt;&amp;lt;script type="module" src="/app.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use styles.css from Startbootstrap
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app.js&lt;/code&gt; calls &lt;code&gt;scalajs:main.js&lt;/code&gt; which is compiled by ScalaJs inside &lt;code&gt;client\target\scala-3.6.2\client-fastopt\main.js&lt;/code&gt;, it contains the converted scala into javascript code from &lt;code&gt;App.scala&lt;/code&gt; and &lt;code&gt;common-&amp;gt;Product.scala&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;vite.config.js&lt;/code&gt; to configure server proxy, explained here Vite-Server-Proxy
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Server
&lt;/h4&gt;

&lt;p&gt;Use &lt;code&gt;http4s - EmberServerBuilder&lt;/code&gt; to start a server with a "controller". &lt;/p&gt;

&lt;h3&gt;
  
  
  CLI
&lt;/h3&gt;

&lt;p&gt;Command line is pretty well explained in IdiomaticSoft, RockTheJvm or in Readme&lt;/p&gt;

&lt;h3&gt;
  
  
  Github repo:
&lt;/h3&gt;

&lt;p&gt;Github - Scala3Http4sFullStack&lt;/p&gt;

&lt;h2&gt;
  
  
  Scala full-stack with
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scala3&lt;/li&gt;
&lt;li&gt;Zio&lt;/li&gt;
&lt;li&gt;ScalaJs&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;li&gt;Laminar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As previously, I have used the repo outline proposed in this tutorial IdiomaticSoft.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;Common - (Domain) shared code - DTOs&lt;br&gt;
Client - FE code&lt;br&gt;
Server - BE code&lt;/p&gt;

&lt;h4&gt;
  
  
  Common
&lt;/h4&gt;

&lt;p&gt;Create the DTO that is shared between Client and Server.&lt;/p&gt;

&lt;h4&gt;
  
  
  Client
&lt;/h4&gt;

&lt;p&gt;This time client is provided by Medium-ScalaFullstackWebApp, it is implemented in scala using Laminar. &lt;/p&gt;

&lt;p&gt;Necessary files&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index.html&lt;/li&gt;
&lt;li&gt;main.js&lt;/li&gt;
&lt;li&gt;package.json&lt;/li&gt;
&lt;li&gt;vite.config.js&lt;/li&gt;
&lt;li&gt;build.sbt&lt;/li&gt;
&lt;li&gt;plugins.sbt&lt;/li&gt;
&lt;li&gt;add src folder&lt;/li&gt;
&lt;li&gt;add scala code in src folder
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29s2tm7jjaknn7l6gk1w.png" alt="Image description" width="359" height="203"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Server
&lt;/h4&gt;

&lt;p&gt;Use the code from Medium-ScalaFullstackWebApp&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI
&lt;/h3&gt;

&lt;p&gt;Command line is pretty well explained in Medium-ScalaFullstackWebApp or in Readme&lt;/p&gt;

&lt;h3&gt;
  
  
  Github repo:
&lt;/h3&gt;

&lt;p&gt;Github - Scala3ZioFullStack&lt;/p&gt;

&lt;h2&gt;
  
  
  Observations
&lt;/h2&gt;

&lt;p&gt;In particular any of the referenced tutorials is either complex or contain too much unrelated info, or have some missing, unexplained elements. For me, it is important to have a clean setup that is also predictable, should result in building the same structure and produce the same outcome. It is easy to mess things up just by calling, apparently similar content, in different ways. For example, the most suitable way to have a clean -common- module is by creating it using this command &lt;code&gt;(crossProject(JSPlatform, JVMPlatform) in file("common"))&lt;/code&gt; other variations provide different result, I learned this stuff while reading RockTheJvm - Scala3Typelevel. From IdiomaticSoft I learned about &lt;code&gt;.aggregate(server)&lt;/code&gt; which provides a cleaner build result. Each tutorial comes with a benefit and a difference that worth to try while searching for a suitable template. &lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://idiomaticsoft.com/post/2023-12-12-fullstack/" rel="noopener noreferrer"&gt;IdiomaticSoft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rockthejvm.com/articles/building-a-full-stack-scala-3-application-with-the-typelevel-stack" rel="noopener noreferrer"&gt;RockTheJvm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rockthejvm.com/articles/building-a-full-stack-scala-3-application-with-the-typelevel-stack#backend-core-module" rel="noopener noreferrer"&gt;RockTheJvm - Scala3Typelevel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@samuelfm_amanoe/scala-fullstack-web-application-01a565a3c947" rel="noopener noreferrer"&gt;Medium-ScalaFullstackWebApp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://startbootstrap.com/template/simple-sidebar" rel="noopener noreferrer"&gt;Startbootstrap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vite.dev/config/server-options#server-proxy" rel="noopener noreferrer"&gt;Vite-Server-Proxy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hackus/Scala3Http4sFullStack" rel="noopener noreferrer"&gt;Github - Scala3Http4sFullStack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hackus/Scala3Http4sFullStack/blob/main/README.md" rel="noopener noreferrer"&gt;Github - Scala3Http4sFullStack - Readme&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hackus/Scala3ZioFullStack" rel="noopener noreferrer"&gt;Github - Scala3ZioFullStack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hackus/Scala3ZioFullStack/blob/main/README.md" rel="noopener noreferrer"&gt;Github - Scala3ZioFullStack - Readme&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Scala's Variance</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Thu, 12 Dec 2024 14:07:36 +0000</pubDate>
      <link>https://dev.to/hackus/scalas-variance-30og</link>
      <guid>https://dev.to/hackus/scalas-variance-30og</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;I think Scala variance chapter is misunderstood heavily even by skillful programmers. All the articles I have found so far explain more or less the same boilerplate they may have found on some common resource and everybody repeat themselves and don't cover enough aspects which makes everybody confuse this concept. &lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Contravariance
&lt;/h2&gt;

&lt;p&gt;This appears to be the hardest, however, it is not harder then Covariance, even more, it is easier that Covariance. IMHO Covariance is misunderstood as well, which makes Contravariance so difficult.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notation:&lt;/strong&gt; SomeClass[-A] - reads as SomeClass is contravariant in A &lt;/p&gt;

&lt;h3&gt;
  
  
  How is it used ?
&lt;/h3&gt;

&lt;p&gt;The widespread example is on Serializers. If one defines a Serializer on a [parent of A] it can further be assigned to a Serializer of [A]. This way, it is not necessary to -reinvent the wheel-. In my words, I define something for a [parent of A] and I can use it for [A]. So it works at the class level. &lt;/p&gt;

&lt;h3&gt;
  
  
  Still, what's the point ?
&lt;/h3&gt;

&lt;p&gt;It is like kibble that can be used to feed Dogs and Cats. Same food, different Animals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class Food {
  val foodType: String
}

abstract class Pet(val name: String)
class Dog(override val name: String) extends Pet(name)
class Cat(override val name: String) extends Pet(name)

class Kibble[-A](override val foodType: String) 
extends Food {
  def printData(values: List[A]): Unit = {
    for (item &amp;lt;- values) {
      item match
        case p: Pet =&amp;gt;
          println(p.getClass.getSimpleName + " "
            + p.name + " food type is "
            + foodType)
        case _ =&amp;gt;
    }
  }
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the following apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def main(args: Array[String]): Unit = {
  val listCat: List[Cat] = List(Cat("cat1"), Cat("cat2"))
  val listDog: List[Dog] = List(Dog("dog1"), Dog("dog2"))

  var kibble = Kibble[Pet]("pelletsOfMeat")

  var kibbleCat: Kibble[Cat] = kibble
  var kibbleDog: Kibble[Dog] = kibble

  kibbleCat.printData(listCat)
  kibbleDog.printData(listDog)

  kibble.printData(listCat)
  kibble.printData(listDog)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implications
&lt;/h3&gt;

&lt;p&gt;First implication:&lt;br&gt;
SomeClass of [A] can be assigned a value of a SomeClass of a [parent of A or A].  &lt;/p&gt;

&lt;p&gt;Second implication:&lt;br&gt;
One can create list Kibble[Cat] and Kibble[Dog] just from Kibble[Pet] without having to dig into specifics.&lt;/p&gt;

&lt;p&gt;Third implication:&lt;br&gt;
A function over Pet type can be passed a Cat type and it will run successfully. Also it will have a strong type checking.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding Covariance
&lt;/h2&gt;

&lt;p&gt;So, what is Covariance ? Well, it is not easier than Contravariance, and it's purpose is not opposed, it's different.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notation:&lt;/strong&gt; SomeClass[+A] - reads as SomeClass is covariant in A  &lt;/p&gt;
&lt;h3&gt;
  
  
  How is it used ?
&lt;/h3&gt;

&lt;p&gt;The widespread example is of a function that is consuming a parent and is passed a child and it still works. So it works at function level as opposed to Contravariance that works at class level. However, it works at class level as well. So, there are two variations of Covariance.&lt;/p&gt;
&lt;h3&gt;
  
  
  Variation 1, Class level
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class Food {
  val foodType: String
}

class Kibble[+A](override val foodType: String, val pets: List[A]) extends Food {
     def printData: Unit = {
       for (item &amp;lt;- pets) {
         item match
           case p: Pet =&amp;gt;
             println(p.getClass.getSimpleName + " "
               + p.name + " food type is "
               + foodType)
           case _ =&amp;gt;
    }
  }
} 

abstract class Pet(val name: String)
class Dog(override val name: String) extends Pet(name)
class Cat(override val name: String) extends Pet(name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The following apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def main(args: Array[String]): Unit = {
  val listCat: List[Cat] = List(Cat("cat1"), Cat("cat2"))
  val listDog: List[Dog] = List(Dog("dog1"), Dog("dog2"))

  var kibbleCat: Kibble[Cat] = Kibble[Cat]("pelletsOfMeat", listCat)
  var kibbleDog: Kibble[Dog] = Kibble[Dog]("pelletsOfMeat", listDog)

  var kibbleCat1: Kibble[Pet] = Kibble[Cat]("pelletsOfMeat", listCat)
  var kibbleDog1: Kibble[Pet] = Kibble[Dog]("pelletsOfMeat", listDog)

  kibbleCat.printData
  kibbleDog.printData

  kibbleCat1.printData
  kibbleDog1.printData
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Variation 2, function level
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def printDataVariation(kibble: Kibble[Pet]): Unit = {
  for (item &amp;lt;- kibble.pets) {
    item match
      case p: Pet =&amp;gt;
        println(p.getClass.getSimpleName + " "
          + p.name + " food type is "
          + kibble.foodType)
      case _ =&amp;gt;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def main(args: Array[String]): Unit = {
  val listCat: List[Cat] = List(Cat("cat1"), Cat("cat2"))
  val listDog: List[Dog] = List(Dog("dog1"), Dog("dog2"))

  var kibbleCat: Kibble[Cat] = Kibble[Cat]("pelletsOfMeat", listCat)
  var kibbleDog: Kibble[Dog] = Kibble[Dog]("pelletsOfMeat", listDog)

  printDataVariation(kibbleCat)
  printDataVariation(kibbleDog)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implications
&lt;/h3&gt;

&lt;p&gt;First implication:&lt;br&gt;
SomeClass of [A] can be assigned a value of a SomeClass of a [child of A or A]. &lt;/p&gt;

&lt;p&gt;Second implication:&lt;br&gt;
A function that works with Pet type will work with child of Pet type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Positions
&lt;/h2&gt;

&lt;p&gt;There is also one more thing to notice with regards to functions, contravariant position is the argument list and covariant position is the return type. This is explained in (Scala in Action, MANNING, Nilanjan Raychaudhuri). However, I want to explain it over again for the sake of remembering it. Following are two similarly looking errors that mean different things.&lt;/p&gt;

&lt;p&gt;1.&lt;br&gt;
&lt;code&gt;**Covariant** type A occurs in **contravariant position** in type List[A] of value values&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means that we have a Covariant type [+A] and create a function with a &lt;strong&gt;param of type&lt;/strong&gt; A. which heads to the conclusion that &lt;strong&gt;contravariant position&lt;/strong&gt; is synonym to function argument. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnvolzh14p9lm62h713n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnvolzh14p9lm62h713n.png" alt="Image description" width="721" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.&lt;br&gt;
&lt;code&gt;**Contravariant** type A occurs in **covariant position** in type A of value findPet&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means that we have a Contravariant type [-A] and create a function with a &lt;strong&gt;return type&lt;/strong&gt; A. Which heads to the conclusion that &lt;strong&gt;covariant position&lt;/strong&gt; is synonym to function return type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fastkq5rn9drt6x03hwdi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fastkq5rn9drt6x03hwdi.png" alt="Image description" width="590" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wording "contravariant position" or "covariant position" has a sort of cockiness to it as I don't see the reason to not use "argument type" or "return type" instead. The reason scala wants to change the established naming convention is surreal. I also consider this to have a noticeable impact to the way these definitions are perceived by the community.     &lt;/p&gt;

&lt;h2&gt;
  
  
  Invariance
&lt;/h2&gt;

&lt;p&gt;Will elaborate on Invariance later. At this point, it feels straight forward. Will work on it if I observe any interesting elements. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Scala's Diamond problem</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Sun, 08 Dec 2024 14:23:11 +0000</pubDate>
      <link>https://dev.to/hackus/scalas-diamond-problem-cga</link>
      <guid>https://dev.to/hackus/scalas-diamond-problem-cga</guid>
      <description>&lt;p&gt;&lt;strong&gt;Intro&lt;/strong&gt;&lt;br&gt;
Have recently learned about Scala's Diamond problem solution and found out most examples cover particular paths leaving some opened questions. &lt;/p&gt;

&lt;p&gt;In this article I reverse engineer the concept so that I can recall it next time I revise it, as this concept is pretty complex.&lt;/p&gt;

&lt;p&gt;First thing I learned is that the solution to diamond problem is called Scala Linearization. It is an algorithm that constructs the list of traits in the order of priority. Where the nearest to the object has the highest priority.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;A-&amp;gt;B-&amp;gt;C-&amp;gt;D &lt;/p&gt;

&lt;p&gt;Means B has the highest priority in the list, and A is the Object that has to call a method that can be defined and implemented in any of B, C, D.&lt;/p&gt;

&lt;p&gt;Thus understanding how to build the list is the key to understanding what would be the result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reverse engineering the algorithm&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Algorithm description in Wikipedia: "using a right-first depth-first search of extended 'traits', before eliminating all but the last occurrence of each module in the resulting list" &lt;a href="https://en.wikipedia.org/wiki/Multiple_inheritance#Mitigation" rel="noopener noreferrer"&gt;Wikipedia - multiple-inheritance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means there are three rules&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;right-first&lt;/li&gt;
&lt;li&gt;depth-first&lt;/li&gt;
&lt;li&gt;eliminate duplicates but the last&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Right first&lt;/strong&gt; is the most explained one of the three, a resource that I found insightful enough is this one: &lt;a href="https://medium.com/@shrutibce/diamond-problem-solution-in-scala-b9af7f54a32b" rel="noopener noreferrer"&gt;Medium - diamond-problem-solution-in-scala&lt;/a&gt; &lt;br&gt;
There is no need to elaborate on it as it is pretty straight forward, one starts reading paths from the right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Depth first&lt;/strong&gt; is seldom covered in articles, a very good article, that I found impresive, is this one: &lt;a href="https://kkyr.io/blog/linearization-in-scala/" rel="noopener noreferrer"&gt;Kyriakos - liniarization-in-scala&lt;/a&gt;&lt;br&gt;
It analysis how linearization works, and in my opinion misses just one thing, the case when the right branch is bigger then the left one as below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfl7qkxg69chdbu5ntmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfl7qkxg69chdbu5ntmd.png" alt="Image description" width="135" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if B and E override the same method, which one will be called ? &lt;/p&gt;

&lt;p&gt;Extending the examples in the &lt;strong&gt;Right first&lt;/strong&gt; article to demonstrate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;object DiamondProblem {

    trait A {
        def M(): Unit = println("Hi, This is M from trait A")
    }
    trait B extends A {
        override def M(): Unit = println("Hi, This is M from trait B")
    }
    trait E extends A {
        override def M(): Unit = println("Hi, This is M from trait E")
    }
    trait C extends E {
    }
    class D extends B with C {
    }

    def main(args: Array[String]): Unit = {
        var sut = D().M()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hi, This is M from trait E
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I guess it completes the demonstration for the depth first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eliminate duplicates but the last&lt;/strong&gt; - for me it was hard to understand until I literally applied it over the Wikipedia's path: &lt;/p&gt;

&lt;p&gt;D-&amp;gt;C-&amp;gt;A-&amp;gt;B-&amp;gt;A&lt;br&gt;
removing duplicate elements but last results in &lt;br&gt;
D-&amp;gt;C-&amp;gt;B-&amp;gt;A&lt;/p&gt;

&lt;p&gt;In case of depth-first we have D-&amp;gt;C-&amp;gt;E-&amp;gt;A-&amp;gt;B-&amp;gt;A, resulting in &lt;br&gt;
D-&amp;gt;C-&amp;gt;E-&amp;gt;B-&amp;gt;A. &lt;/p&gt;

&lt;p&gt;I think I understood the concept. Comment if you disagree.&lt;/p&gt;

</description>
      <category>scala</category>
      <category>diamondproblem</category>
    </item>
    <item>
      <title>Where is the Monad ?</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Thu, 14 Nov 2024 13:54:35 +0000</pubDate>
      <link>https://dev.to/hackus/where-is-the-monad-2a8i</link>
      <guid>https://dev.to/hackus/where-is-the-monad-2a8i</guid>
      <description>&lt;p&gt;While learning Scala, I came across the concept of Monads or rather, what I’d call a widespread misconception, as most articles and explanations are incomplete, misleading, and steeped in confusion.  &lt;/p&gt;

&lt;p&gt;I recall a discussion, long time ago, with a colleague who mentioned that Scala is more interesting than Java because it contains Monads. When asked about what is a Monad, no clear definition was provided but an example: "think about it as an Optional(Java8) or Either(from Vavr)". &lt;/p&gt;

&lt;p&gt;I initially ignored the topic, but once I became a Scala developer, I decided to analyze and truly understand the concept so that I could speak about it without any ambiguity if ever asked&lt;/p&gt;

&lt;p&gt;One thing I found out is that Monad is not a concept defined in Scala and that you have to implement it or benefit from already created ones.&lt;/p&gt;

&lt;p&gt;In mathematics the concept is based of morphisms from one set to another, and their composition. Which is quite simplistic and at the same time highly abstract.&lt;/p&gt;

&lt;p&gt;In programming though, you have to just start writing a &lt;strong&gt;for&lt;/strong&gt; and stumble upon an embarrassing question: how many items are in a set ?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for(int i=0;i&amp;lt;=? ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What if there are no items, one item, many or infinite ? Each case has to be treated separately jamming the code with if/cases and whatever other solutions out there...&lt;/p&gt;

&lt;p&gt;What if there are different pairs of sets? Implement a &lt;strong&gt;for&lt;/strong&gt; for each pair ?&lt;/p&gt;

&lt;p&gt;Regardless of the chosen implementation it is always solving one thing, a mapping from one set to another. So if it is just about mapping from one set to another, why not making it a standard that works on any set, performs an action, returns another set and allow the process to start over? &lt;/p&gt;

&lt;p&gt;Basically build a wrapper, it takes an array of a specific &lt;strong&gt;type&lt;/strong&gt;, a function from one &lt;strong&gt;type&lt;/strong&gt; to &lt;strong&gt;another type&lt;/strong&gt;, and return a wrapper over &lt;strong&gt;another type&lt;/strong&gt;. And it can be chained indefinitely or until the result is changed from wrapper to a value. &lt;strong&gt;&amp;lt;- the description of a monad in simple words&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From here things become simple if not obvious, a construction like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;int sum = Stream.of("String 1", "String 2", "String 3", "String 4", "String 5")&lt;br&gt;
                .mapToInt(String::length)&lt;br&gt;
                .reduce(0, Integer::sum);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is a Monad in Java. &lt;/p&gt;
&lt;h2&gt;
  
  
  Here’s the formal (mathematical) demonstration of that:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Monad is a functor. &lt;/li&gt;
&lt;li&gt;A Functor is a mapping between Categories, in simple terms it associates for any element x in Category A an element y in Category B,&lt;/li&gt;
&lt;li&gt;A Category is a structure that consists of a set of objects, a set of morphisms &lt;code&gt;and a binary operation defined on compatible pairs of morphisms called composition&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;A category that has only one object is a Monoid. And this is the key to reverse engineer concept. &lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  From Monoid to Monad
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Monoid definition is simple
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Set&lt;/li&gt;
&lt;li&gt;Binary operation with a result in the same Set&lt;/li&gt;
&lt;li&gt;Identity element&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  So lets define two monoids
&lt;/h3&gt;

&lt;p&gt;Monoid S&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A set of all strings&lt;/li&gt;
&lt;li&gt;Concatenation operation (returns a string, also a part of set)&lt;/li&gt;
&lt;li&gt;Identity element is ""&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Monoid I&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A set of all integers&lt;/li&gt;
&lt;li&gt;(+) operation&lt;/li&gt;
&lt;li&gt;Identity element is 0&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  From Monoid to Category
&lt;/h3&gt;

&lt;p&gt;Monoid is a particular form of Category, thus we have two categories S and I. &lt;/p&gt;
&lt;h3&gt;
  
  
  From Category to Functor
&lt;/h3&gt;

&lt;p&gt;We define a morphism from Category S to Category I:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(String item) -&amp;gt; item.length&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  And we have the Monad
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;sum = Stream.of("String 1", "String 2", "String 3", "String 4", "String 5")&lt;br&gt;
                .mapToInt(String::length)&lt;br&gt;
                .reduce(0, Integer::sum);&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Problems that monads address
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Simple for
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for(every i in list) {
   doSomeStuff
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Written in a monadic way:&lt;/p&gt;

&lt;p&gt;list.forEachElementDo(doSomeStuff)&lt;/p&gt;
&lt;h3&gt;
  
  
  Chaining fors
&lt;/h3&gt;

&lt;p&gt;Supposedly there is this list&lt;/p&gt;

&lt;p&gt;parentList = List[List[B]]&lt;/p&gt;

&lt;p&gt;The generic problem is to doSomeStuff on each element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for(every i in parentList ) {
   for(every j in childList[i]){
     doSomeStuff
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Written in a monadic way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parentList.forEachElementDo(childList -&amp;gt; childList.forEachElementDo(doSomeStuff))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is clear now that the result is &lt;strong&gt;flattened&lt;/strong&gt;(into doSomeStuff return type) therefore the &lt;strong&gt;flatMap&lt;/strong&gt; function used in monads.&lt;/p&gt;

&lt;p&gt;Thus, in a conventional manner, the code becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parentList.flatMap(childList -&amp;gt; childList.flatMap(someStuff))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sequencing fors
&lt;/h3&gt;

&lt;p&gt;If you sequence "fors" as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parentList.flatMap(doFirstStuff).flatMap(doSecondStuff)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You basically "monaded" this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for(int i=0; i&amp;lt;....){
   doFirstStuff
}
for(int j=0; j&amp;lt;....){
   doSecondStuff;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I approach monads from the perspective of the problems they solve rather than what they represent. It simplifies the concept and makes it easier to grasp intuitively, without getting lost in the mathematical formalism, which is often difficult to internalize and tends to create confusion.&lt;/p&gt;

&lt;p&gt;This explanation is presented in the simplest way possible, which might seem almost unbelievable to those who have invested considerable effort in explaining monads through more complex approaches. Apologies if this comes across as a slight on anyone’s expertise. If so, please feel free to point out any mistakes in the explanation or share additional examples of problems that monads help solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;Monad:&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Monad_(functional_programming)&lt;/a&gt;&lt;br&gt;
Functor: &lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Functor#endofunctor" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Functor#endofunctor&lt;/a&gt;&lt;br&gt;
Category: &lt;br&gt;
&lt;a href="https://mathworld.wolfram.com/Category.html" rel="noopener noreferrer"&gt;https://mathworld.wolfram.com/Category.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Category_(mathematics)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Category_(mathematics)&lt;/a&gt;&lt;br&gt;
Monoid: &lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Simplified explanation of JPA relations</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Wed, 16 Aug 2023 06:27:06 +0000</pubDate>
      <link>https://dev.to/hackus/simplified-explanation-of-jpa-relations-2cea</link>
      <guid>https://dev.to/hackus/simplified-explanation-of-jpa-relations-2cea</guid>
      <description>&lt;p&gt;It was hard for me to grasp the concept of JPA relations until I started to invest more time in it. &lt;/p&gt;

&lt;p&gt;I will start with OneToOne, the easiest, what I find important in this relation is that we can insert ids for each participant making it bidirectional at no cost(except allocated space for parent id in child table).&lt;/p&gt;

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

&lt;p&gt;It is not necessarily to map OneToOne bidirectionally and it does make sense to map it &lt;em&gt;LAZY&lt;/em&gt; otherwise N+1 problem is your friend if using JPA QueryBuilder. This is pretty strange because &lt;em&gt;LAZY&lt;/em&gt; is the source for N+1. True, however you can choose if it is a hidden N+1 or a managed one. When query a Parent through QueryBuilder, if OneToOne child is eagerly connected, JPA will run a query to find all parents, will create a list of child ids and for each id will run a query to get each child details, so N+1 through &lt;em&gt;EAGER&lt;/em&gt;. This is hidden, you can spot it just by verifying generated queries. Only by using &lt;em&gt;LAZY&lt;/em&gt;, you will be able to fetch Parents only. And yes you will have to fetch explicitly each child, still within N+1, the only difference is that first example is unmanaged, done by JPA behind the counter, second one is managed, you are fully aware of what happens.    &lt;/p&gt;

&lt;p&gt;OneToMany is a bit complicated, and I wish I knew from the beginning that in order to not duplicate the rows in parent table, parent table id should be placed into the child not vice-versa. The reason is simple, if child id is placed in parent, parent has to replicate its rows for each child relation just because child id is present in parent table.&lt;/p&gt;

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

&lt;p&gt;Here is how data in parent duplicates:&lt;/p&gt;

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

&lt;p&gt;A better approach would be to map child to parent by parent id and live it as is. It becomes ManyToOne now.&lt;/p&gt;

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

&lt;p&gt;And data is aligned as expected:&lt;/p&gt;

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

&lt;p&gt;The join table for OneToMany is an overhead. Not only it becomes redundant, requires additional space, and adds up to the complexity, it is also a source to mistakenly transform it into a ManyToMany relation.&lt;/p&gt;

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

&lt;p&gt;For OneToMany relation join table does not save allocated space:&lt;/p&gt;

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

&lt;p&gt;ManyToMany is where a join table helps. Its apparent complexity saves database space, without a join table database size will increase unjustifiably by replicating data. &lt;/p&gt;

&lt;p&gt;Without join table:&lt;/p&gt;

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

&lt;p&gt;Data is duplicated:&lt;/p&gt;

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

&lt;p&gt;Moving to join table and schema becomes comprehensible:&lt;/p&gt;

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

&lt;p&gt;Data also avoids redundancy except for ids:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Offtopic&lt;/strong&gt;&lt;br&gt;
Non relational databases are prone data replication issues. Mainly because it is hard to imagine a relational diagram. Though, not only non relational DBs are prone to this issue. Relational are too. For example if the architecture is based on Spark framework. The gain in performance by running tasks in parallel comes at the cost of removing foreign key relations from database. And when multiple DDL changes are made uncontrollably it is hard to imagine how data are linked. This is why Spark based architects run away from Hibernate/JPA, they will move to MyBatis or similar frameworks, even JDBC in this case would become a good choice. Most interesting is that after a while, Spark applications become Spark addictive. Due to data duplication it will be hard to optimize such databases. And the solution would be to increase the number of Spark workers. Unfortunately, even horizontal scaling is not indefinitely inflatable. It is easy to predict the refactoring to a new data storage solution, non relational inclusively, in this kind of projects. &lt;/p&gt;

</description>
      <category>jpa</category>
      <category>onetoone</category>
      <category>onetomany</category>
      <category>manytomany</category>
    </item>
    <item>
      <title>Run Docker from WSL</title>
      <dc:creator>Mircea Sirghi</dc:creator>
      <pubDate>Sat, 29 Jul 2023 07:12:50 +0000</pubDate>
      <link>https://dev.to/hackus/docker-to-wsl-migration-2lki</link>
      <guid>https://dev.to/hackus/docker-to-wsl-migration-2lki</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article is a complete guide on how to setup WSL on windows and run docker, Kafka, Kubernetes commands directly from GitBash console without having to open WSL.&lt;/p&gt;

&lt;p&gt;Additionally I have added the setup to use Java Test Containers.&lt;/p&gt;

&lt;p&gt;The whole purpose is for anyone who wants to migrate to a new distribution or to change machines, or has to fix a broken WSL, in just a few steps the environment is prepared rapidly without the need to investigate the internet on each particular problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preparing WSL with docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First part is preparing windows to use docker from WSL without Docker Desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding Java Test Containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I observed that I can also automate the part to add Java Test Containers so this is the second part. So that anytime WSL gets broken or I want to switch to a new linux distribution or to change laptops, I can allway run the same commands and expect it works. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up Kubernetes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Third part is how I setup Kubernetes through WSL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kafka setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I will add setting up Kafka soon. Currently I am looking to change the whole approach to using just Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I have removed scripts to enable docker on Powershell and CMD as I have never used them and find them redundant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hackus/wsl-scripts/tree/master"&gt;On Github&lt;/a&gt; &lt;/p&gt;

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

</description>
      <category>docker</category>
      <category>wsl</category>
    </item>
  </channel>
</rss>
