<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pro Coder</title><description>Actionable Advice to Accelerate Your Career</description><link>https://www.procoder.io</link><language>en-us</language><atom:link href="https://www.procoder.io/rss.xml" rel="self" type="application/rss+xml"/><item><title>Why hello there Substack!...</title><link>https://www.procoder.io/articles/2025/2025-11-23_hello_substack</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-11-23_hello_substack</guid><description>Substack is a great way to reach people. Are you on Substack? Me too!</description><pubDate>Sun, 23 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…what do you have for me today?&lt;/p&gt;
&lt;p&gt;When I started writing technical articles, back in 2019, I did that around the same time I began &lt;a href=&quot;https://youtube.com/@ProCoderIO&quot;&gt;making YouTube videos&lt;/a&gt;. The idea back then was to publish on Medium and maybe make a little extra money!&lt;/p&gt;
&lt;p&gt;That may have been my thoughts six years ago, but I made a seismic shift earlier this year. I discovered I could rebuild Pro Coder into something new. Instead of a lightweight website, I could build a deeper platform. And the first thing I wanted to do was pull over all the Medium articles and server them from my own site. For free.&lt;/p&gt;
&lt;p&gt;And with a little assistance from Chat GPT, I made that happen.&lt;/p&gt;
&lt;p&gt;But why stop there?&lt;/p&gt;
&lt;p&gt;I had heard from multiple people that Substack was exploding on popularity. So I pointed my attention at cross-posting all my past (and future) articles. Not to make money, but instead to share my experiences and help you grow.&lt;/p&gt;
&lt;p&gt;I was fully committed to syncing every past, present, and future article, automatically with a script, to Substack when I discovered…they don’t have an API.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/articles/2025/kid-staring-quizzically.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;kid staring quizzically&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;I looked for modules, pre-fab libraries, anything that would let me push an article. What did I find? Zip. Zero. Nada. Looks like Substack wants you to write there first.&lt;/p&gt;
&lt;p&gt;Well that ain’t gonna happen!&lt;/p&gt;
&lt;p&gt;So after trying various side tactics to slide content over to Substack, I finally chose to “go in through the front door.” That’s what I call it when you scriptify an application’s UI.&lt;/p&gt;
&lt;p&gt;Having migrated to Claude Code, I fired up a session, rubbed my hands together, and typed “ready for a challenge?”&lt;/p&gt;
&lt;p&gt;And Claude smiled back.&lt;/p&gt;
&lt;p&gt;And a challenge it truly was. We worked up a Typescript library, far from perfect, that would typeset the original Markdown I write my newsletters and articles with. Then we created a chain of “finishers”.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace Markdown image directives with a series of steps to upload images&lt;/li&gt;
&lt;li&gt;Replace link directives with hyperlinks&lt;/li&gt;
&lt;li&gt;Replace boldface and italicized text&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ll tell you, it wasn’t easy! Substack has various pop-ups. Things required certain delays for the widgets to act. And it took a LOT of iterations to get the image uploading to work right. I also wanted to “backdate” articles to their original pub date.&lt;/p&gt;
&lt;p&gt;But the thing that really irritates me is that Substack is REALLY hostile to being downstream. They want you creating content with them, first! The first piece of evidence is the fact that they don’t do “canonical links”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Canonical links are what you put in HTML when you want to say “the origin of this content was &lt;em&gt;hyperlink&lt;/em&gt;”. It tells search engines where to go to find the source and avoids you getting dinged for duplicate content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Medium has this feature. Substack doesn’t.&lt;/p&gt;
&lt;p&gt;Five years ago, that might have ended my efforts. But not today, Zurg!&lt;/p&gt;
&lt;p&gt;In this day and age of AI-powered synthesized search results, I imputed Google and its competitors with a little more trust. I wrote up a little footer to stick at the bottom of every article that reads “This article was original publishing on Pro Coder on &lt;date&gt;” and hyperlinked back to my own site.&lt;/date&gt;&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/articles/2025/substack_footer.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;footer of a substack post&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;Maybe the engineers behind Google etc. aren’t looking for that. But their AI processors may see it!&lt;/p&gt;
&lt;p&gt;And so I bulk loaded almost 80 articles to Substack. I had my tool load them all in draft mode, because no matter how hard I tried, there was always a flub. I hand edited each of them. And now they’re ready for you.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://procoder.substack.com&quot;&gt;Are you on Substack? Check it out!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;P.S. Articles are now posted on Substack. &lt;a href=&quot;https://procoder.substack.com&quot;&gt;Subscribe today&lt;/a&gt;!&lt;/p&gt;</content:encoded><media:content type="image/png" width="1536" height="1024" medium="image" url="https://www.procoder.io//_astro/hello_substack.DpaB9cXT.png"/></item><item><title>Claude Code is my new best friend...</title><link>https://www.procoder.io/articles/2025/2025-11-10_claude_code_is_my_new_best_friend</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-11-10_claude_code_is_my_new_best_friend</guid><description>...and maybe it should be yours as well?</description><pubDate>Mon, 10 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…and maybe it should be yours as well?&lt;/p&gt;
&lt;p&gt;I have been shelling out the big bucks on ChatGPT+ over the past 18 months. Yup…$20/month!&lt;/p&gt;
&lt;p&gt;Okay, maybe this ain’t the BIG bucks. But I have certainly gotten my money’s worth out of that $20/month.
This website wasn’t BUILT FOR ME by ChatGPT.
But I certainly worked hand-in-hand with ChatGPT for it to carry out my bidding in a very fast-paced collaborative way.&lt;/p&gt;
&lt;p&gt;And about a month ago I canceled my subscription.&lt;/p&gt;
&lt;p&gt;Because I had found something &lt;em&gt;better&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Claude Code, the CLI tool that hooks into Claude.ai from our overlords at Anthropic is the place where I activated a $20/month subscript.&lt;/p&gt;
&lt;p&gt;You see Claude Code is an &lt;strong&gt;&lt;em&gt;agentic&lt;/em&gt;&lt;/strong&gt; AI tool.
It closes a critical loop.
With ChatGPT, I would copy-and-paste all the text from a given page, paste it into ChatGPT’s window, give it a command on what tweak I wanted, get the resulting output, and paste it back into my IDE.&lt;/p&gt;
&lt;p&gt;With Claude Code, I launch it in a terminal inside my IDE where it can see all my files, tell it what I want done…&lt;/p&gt;
&lt;p&gt;…and it just edits the file directly.&lt;/p&gt;
&lt;p&gt;The first time, I said “whoah!”&lt;/p&gt;
&lt;p&gt;And then I did it again. And again. And again. And again.&lt;/p&gt;
&lt;p&gt;After about the 10th hop, where I’m simply handing out marching orders, and Claude Code is bending and twisting this website, it felt like I was sculpting a website.&lt;/p&gt;
&lt;p&gt;Claude Code is almost like the Starship Enterprise’s central computer.
On ST:TNG, they are always asking the computer to do this, that, and the other.
Through simple, verbal commands.&lt;/p&gt;
&lt;p&gt;Well here I am, telling Claude Code what to do, and it’s just…well…DOING IT.&lt;/p&gt;
&lt;p&gt;That’s already a boost over the flow with ChatGPT.
But there was more.&lt;/p&gt;
&lt;p&gt;ChatGPT, once you give it a prompt, makes you wait until it’s done.
Claude Code is always listening in.
You can type more instructions.
Clarificiations.&lt;/p&gt;
&lt;p&gt;And when it gets a chance, it will look at what you said, and fold that into its process.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/articles/2025/claude-code.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;claude-code.png&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;You see these agentic AI tools run on a sort of loop.
They start an action and then they LOOK at what’s happening, and may alter what they’re doing, until they think they’ve done what the original prompt asked for.&lt;/p&gt;
&lt;p&gt;That is &lt;em&gt;much&lt;/em&gt; more constructive in getting stuff done.&lt;/p&gt;
&lt;p&gt;The next big thing that I want to add to this site is, after having added the ability to send you e-books you signed up for (or purchased) is to build the ability to get audiobooks and videobooks.&lt;/p&gt;
&lt;p&gt;12 Rules for Pro Coders has a paperback, hardback, e-books, &lt;em&gt;audiobook&lt;/em&gt; and &lt;em&gt;videobook&lt;/em&gt; versions available.&lt;/p&gt;
&lt;p&gt;And I plan to make them available to you.&lt;/p&gt;
&lt;p&gt;The e-books I got working (&lt;a href=&quot;/newsletters/2025-09-029_keeping_up&quot;&gt;and already mentioned&lt;/a&gt;).
I’m working with Lulu Direct to print paperbacks and drop ship them to you. (Not sure if they have hardbacks or not)&lt;/p&gt;
&lt;p&gt;But the Holy Grail will be finally finishing up the audiobook and videobook versions.&lt;/p&gt;
&lt;p&gt;I plan to make each of those a “private podcast”, meaning I can host the files on my own backend system, stream the content through my back-of-the-house order fulfulment system, and then send you a unique private “podcast” that will contain all the content for you to consume on your favorite podcast player.
Since many podcast players now support video, that should work quite nicely.&lt;/p&gt;
&lt;p&gt;And since I have the vision of how that will work architecturally, I have no doubt Claude Code can help me implement it with ease.&lt;/p&gt;
&lt;p&gt;I’m amazed at the speed and scope of what I can do. Being able to apply my experience so deftly is amazing. And it also helps me learn as well. Topics I’m not as skilled out, these tools can coach me on. Considering the training is very contextual, the learning “sticks” much better than reading dusty opd textbooks ever were in grad school.&lt;/p&gt;
&lt;p&gt;If you’re not subscribed to Claude Code, you may want to consider it. (And no, I’m not sponsored by Anthropic!)&lt;/p&gt;
&lt;p&gt;It could be the power boost you’re looking for.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;P.S. Consider &lt;a href=&quot;https://www.youtube.com/@procoderio/join&quot;&gt;becoming a member&lt;/a&gt; if you want first dibs on EVERYTHING!&lt;/p&gt;</content:encoded><media:content type="image/png" width="1536" height="1024" medium="image" url="https://www.procoder.io//_astro/buddies.x-K_EvV3.png"/></item><item><title>Liquid Glass on iOS...</title><link>https://www.procoder.io/articles/2025/2025-10-12_liquid_glass_and_steve_jobs</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-10-12_liquid_glass_and_steve_jobs</guid><description>People say Apple&apos;s creativity is dead. Maybe not. Sounds like people are taking shots. The day we quit is the day Steve Jobs&apos; legacy truly dies.</description><pubDate>Sun, 12 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…may be something Steve Jobs would have been proud of!&lt;/p&gt;
&lt;p&gt;Ever since the great titan’s passing way back in 2011, people have questioned every design decision ever since. This may be The One!&lt;/p&gt;
&lt;p&gt;Steve Jobs while complicated and full of questionable personal decisions was someone that invested serious time and effort in stuff like fonts. Look and feel.
The shade of black.&lt;/p&gt;
&lt;p&gt;Others thought he was crazy.&lt;/p&gt;
&lt;p&gt;But who are we to question someone with enough artistic gravitas and business acumen that he ended up with more Disney stock and than Disney’s CEO at the time
of the acquisition of Pixar.&lt;/p&gt;
&lt;p&gt;And so with the passing of the only computer giant that gave Microsoft a run for it’s money, every single design decision ever since has been run through a lens
of “would Steve Jobs approve of this?”&lt;/p&gt;
&lt;p&gt;At one time the iPhone screen icons were curved and rounded. And then all of sudden they were flat.&lt;/p&gt;
&lt;p&gt;But now with this emergence of Liquid Glass, I have to yet hear a single person ask that very question.&lt;/p&gt;
&lt;p&gt;My gut reaction upon first seeing Apple’s own illustrative reel was “wow!” I’d like to Jobs would have been equally impressed.&lt;/p&gt;
&lt;p&gt;Apple devices have always had some element of other world-ness. It’s part of what draws me to Apple. Sometimes that nature has been subdued. Other times not.&lt;/p&gt;
&lt;p&gt;I’ll always remember that time I visited the Melbourne Square Mall, long before I ever owned a Mac. In the main thoroughfare between shops was a special setup
showing off their latest line, the Power Mac G4 Cube and all it’s peripherals.&lt;/p&gt;
&lt;p&gt;An antique today for sure. And something I didn’t know the specs of back then.&lt;/p&gt;
&lt;p&gt;But the look and feel was burned into my mind. And the fact that they were playing &lt;em&gt;The Fifth Element&lt;/em&gt; on one of them to show off it’s multimedia features put a
nice touch on it all.&lt;/p&gt;
&lt;p&gt;This was the sort of thing people that didn’t get Steve Jobs at all couldn’t comprehend.&lt;/p&gt;
&lt;p&gt;To Jobs it wasn’t about art OR power. It was about both, at once. And in your hands.&lt;/p&gt;
&lt;p&gt;I’ve seen people pose the question “why do you Apple fanbois like it so much?”&lt;/p&gt;
&lt;p&gt;My answer was a long Tweet that told the tale of my wife’s discovery of Apple. The one that culminated in her breaking from her family pack. First getting her a
MacBook Air. Then later, a possessor of lower-priced Samsung devices, she one night said “I think I want an iPhone.”&lt;/p&gt;
&lt;p&gt;That post was followed by a legion of “👆this” responses.&lt;/p&gt;
&lt;p&gt;I had jumped ship and got my first Mac when I joined the Spring team in 2010. The year before that, I had snagged an iPhone 3GS.&lt;/p&gt;
&lt;p&gt;I later sunk my own hard cash into a fully leaded M3 Max the day after being told I would no longer be a part of the Spring team in 2023…using every nickel of
VMware’s final au revoir bonus check before they vanished into the history books. (Purchase price exceeded $4,000.)&lt;/p&gt;
&lt;p&gt;I watched my best friend hire a video editor/producer to help with his company’s training material…and reach out to me when this new hire requested a MacBook
Pro. He needed to know how much budget to grant for her endeavors.&lt;/p&gt;
&lt;p&gt;In none of these situations have I heard an ounce of buyer’s remorse.&lt;/p&gt;
&lt;p&gt;So dragging us back to today…is Apple’s latest RIDICULOUS continuation of design aesthetics gone off the rails with Liquid Glass?&lt;/p&gt;
&lt;p&gt;I don’t know.&lt;/p&gt;
&lt;p&gt;Accessibility is important. Very important. In fact, accessibility has become one of the most important reasons you should favor tabs over spaces my fellow pro
coder.&lt;/p&gt;
&lt;p&gt;Does Liquid Glass violate accessibility?&lt;/p&gt;
&lt;p&gt;Again, I don’t know.&lt;/p&gt;
&lt;p&gt;But I’d like to see Liquid Glass tested in the marketplace. We’ll all learn something.&lt;/p&gt;
&lt;p&gt;It’s easy to throw rocks. I’ve done my fair share. And the tech community appears to be up in arms over this.&lt;/p&gt;
&lt;p&gt;But I’m glad Apple is continuing to try out new ideas. New concepts. New aesthetics.&lt;/p&gt;
&lt;p&gt;Because the day they stop trying will TRULY be the day that Steve Jobs’ ideals will have died.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;P.S. Consider &lt;a href=&quot;https://www.youtube.com/@procoderio/join&quot;&gt;becoming a member&lt;/a&gt; if you want first dibs on EVERYTHING!&lt;/p&gt;</content:encoded><media:content type="image/png" width="1536" height="1024" medium="image" url="https://www.procoder.io//_astro/apples-liquid-glass.C1EEEDEi.png"/></item><item><title>Keeping up with the times?</title><link>https://www.procoder.io/articles/2025/2025-09-029_keeping_up</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-09-029_keeping_up</guid><description>After getting dropped in the midst of a company acquisition, I replaced a $150/yr SaaS tool with my own. But what I learned in the midst of all that was priceless!</description><pubDate>Mon, 29 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;“Expertness and skill for the performance of special kinds of work lose their remunerativeness when new fashions or new methods of production narrow the opportunity for their employment.” —Ludwig von Mises, &lt;em&gt;Human Action&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The world is always changing. Skills we learned yesterday come with no guarantee that they’ll be usable tomorrow.&lt;/p&gt;
&lt;p&gt;A strong piece of evidence for this point of view is the emergence of AI tools like ChatGPT!&lt;/p&gt;
&lt;p&gt;I have actually ditched SaaS tools with ones that I built MYSELF.
As a published author, one of the key things I need to do is put a book into your hands.
I used to use a SaaS tool to handle that for me.
This tool would generate unique download links, and then send out an email to the recipient.
The download link would have a shelf life of two weeks.
The handy thing was handing the tool a list of 200 emails and let it go to town.&lt;/p&gt;
&lt;p&gt;But using AI tools, I’ve been able to supplant this $150/yr &lt;em&gt;rather quite useful&lt;/em&gt; tool with one of my own.
In fact, the website through which you read this newsletter has a portion of this feature!
The link you should have received to &lt;em&gt;&lt;strong&gt;Pro Coder’s Guide to AI&lt;/strong&gt;&lt;/em&gt; (reply to this email if you haven’t and alert me) came partially this website (and partially through my back-of-the-house order fulfilment system)&lt;/p&gt;
&lt;p&gt;I have also seen others in completely different industries say the same with regards to ditching various tools and building their own through the magic of AI assistance.&lt;/p&gt;
&lt;p&gt;In Mises’s landmark publication &lt;em&gt;Human Action: A Treatise on Economics&lt;/em&gt; (published in 1949), he argues that nothing is forever.
The market is always changing.
It’s rather silly to assume that anything will stay put.
And most assuredly, a consistent steady paycheck is going against the grain.&lt;/p&gt;
&lt;p&gt;My own experience with one day waking up and deciding I would throw my hat in the ring to join the Spring team (and succeeding), and then later having that bookended with a brand-new CEO deciding my tenure on that team was over, is one additional data point in Mises’ favor.&lt;/p&gt;
&lt;p&gt;That and many other experiences have shown me the value to always to be learning.
Always be reading.
Always be picking up new toolkits.&lt;/p&gt;
&lt;p&gt;To pick up one toolkit and presume that this will be your bread’n’butter for the rest of you career is foolish.&lt;/p&gt;
&lt;p&gt;Part of what stimluates me to get up and write for you is my desire to share some of the realizations I have with you.
Most of it is my own knowledge and awareness of this industry.
But some is my desire to bring you knowledge I wouldn’t have found through the usual channels.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Human Action&lt;/em&gt; is something that I had heard referenced by multiple people, so one day I decided “I’m going to read it!”
I didn’t realize the manuscript is approximately 450,000 words.
That’s about &lt;em&gt;1800 pages&lt;/em&gt; if you were to print it like any other conventional novel.
I also didn’t realize it was so “high brow”, i.e. academically flavored.
I quickly deduced I can’t read it at the end of the day.
I don’t have enough cerebral power at that point.&lt;/p&gt;
&lt;p&gt;So I began reading it in the morning.
Right after I read my morning passage of the Bible.&lt;/p&gt;
&lt;p&gt;And what’s quite fascinating, is that this &lt;em&gt;philosophical&lt;/em&gt; text has brought an awareness I didn’t expect.&lt;/p&gt;
&lt;p&gt;Certain phrases I’d hear a politician or a pundit say would leap out at me.
I could hear some of Mises’ arguments from his tome add &lt;em&gt;color&lt;/em&gt; to what this person was saying.&lt;/p&gt;
&lt;p&gt;And when I read the passage listed at the top, my experience in this industry seemed to line up perfectly.&lt;/p&gt;
&lt;p&gt;Nothing is set.
Nothing is guaranteed.
Nothing is steady.
The only guarantees we have are change, so plan accordingly.&lt;/p&gt;
&lt;p&gt;Whatever nervousness I had about learning more and more about our modern-day AI systems had to be set aside.&lt;/p&gt;
&lt;p&gt;I quickly realized that to survive in today’s software industry, you can’t ignore this AI revolution.
Maybe you can if are some tenured CompSci professor?
A) I ain’t that and B) Mises’ words suggest even tenured professors entrenched at well-funded universities may not be sacrosanct.&lt;/p&gt;
&lt;p&gt;I am learning what I can.
Some of those lessons have made their way into &lt;em&gt;&lt;strong&gt;Pro Coders’ Guide to AI&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;One thing is rather cute…MANY AI tools are simply wrapping up your request and then calling out to ChatGPT or Claude.
Supposedly with some additional prompting.
Is that really “new”? Or just plain old huxterism?
I’ll let you evaluate that for yourself.&lt;/p&gt;
&lt;p&gt;But this newsletter isn’t about AI.
Not specifically.
Instead, it’s about the fact you need to be constantly learning. Growing. Expanding.&lt;/p&gt;
&lt;p&gt;People ask me all the time “Is XYZ a good tech to invest in?”
&lt;a href=&quot;/articles/2024/2024-03-07_as-a-pro-coder--it-s-always-valuable-to-collect-skills-22134e566aba&quot;&gt;As I’ve mentioned before&lt;/a&gt;, YES!&lt;/p&gt;
&lt;p&gt;Considering the amount of competition out there, and the fact that someone I reached out to when I was cut &lt;em&gt;in turn got cut&lt;/em&gt; in a recent round of layoffs, it’s critical!
Keep reading.
And if I’ve learned anything from reading an economic philosophy book, not EVERYTHING you read has to pure software.
Simply reading (perhaps a hair above tabloid trash) a little bit every day can elevate your thinking and provide extra illumination to the things around you.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;P.S. Consider &lt;a href=&quot;https://www.youtube.com/@procoderio/join&quot;&gt;becoming a member&lt;/a&gt; if you want first dibs on EVERYTHING!&lt;/p&gt;</content:encoded><media:content type="image/png" width="1536" height="1024" medium="image" url="https://www.procoder.io//_astro/keeping-up.CtxCMp-0.png"/></item><item><title>Ever taken up a hobby?</title><link>https://www.procoder.io/articles/2025/2025-09-013_ever_taken_up_a_hobby</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-09-013_ever_taken_up_a_hobby</guid><description>You&apos;ve heard that all work and no play makes Jack a dull boy, right? I discovered something that is REALLY cool! Have you?</description><pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A couple years ago, the Mrs. had scooped up this little bitty iPad app called “Procreate”.&lt;/p&gt;
&lt;p&gt;Well, as part of my new job at Cockroach Labs I needed my own iPad to function as part of my teleprompter setup.&lt;/p&gt;
&lt;p&gt;So I sure as shootin’ I got on the app store and downloaded my own copy.&lt;/p&gt;
&lt;p&gt;And then I thought to myself…&lt;/p&gt;
&lt;p&gt;…how do you even DRAW?&lt;/p&gt;
&lt;p&gt;As a YouTube content creator, my first thought was “there ought to be a video on that!” And there was. And another. And another. Well, you get the idea.&lt;/p&gt;
&lt;p&gt;So I just started doing stuff.&lt;/p&gt;
&lt;p&gt;In fact, I dug into oil paintings. I remember visiting Paris back in 2007 and seeing artists on the street scrambling to earn a living selling oil paintings.
This
art form always blew my mind, because when you look up close, it’s just clumps of paint with weird colors. Dark blue, purple, off-pink. If you’ve seen one, you
know what I’m talking about.&lt;/p&gt;
&lt;p&gt;But then you step back just a bit, and POW!&lt;/p&gt;
&lt;p&gt;It LOOKS like something. Something AMAZING.&lt;/p&gt;
&lt;p&gt;So…I went back to trusty old YouTube and inquired after “oil paintings with Procreate”.&lt;/p&gt;
&lt;p&gt;I was not disappointed. An hour later, I had made this…&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/articles/2025/procreate-apple.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div class=&quot;two-column-layout&quot;&gt;
  &lt;div class=&quot;left-column&quot;&gt;
    &lt;span style=&quot;color: green;&quot;&gt;Today&apos;s sponsor...&lt;/span&gt;
    &lt;p&gt;
      Coding isn’t just about algorithms. There’s more. A LOT more. CI, security, team communication, meetings, career tips, you name it. I wrote 12 Rules for Pro Coders to give you actionable advice to accelerate your career. As a veteran pro coder, I want YOU to learn the same valuable lessons I did…but faster. Go and grab your copy and learn what your university or boot camp didn’t have time to teach you!
    &lt;/p&gt;
    &lt;p&gt;
      I wrote &lt;strong&gt;&lt;em&gt;12 Rules for Pro Coders&lt;/em&gt;&lt;/strong&gt; to give you actionable advice to accelerate your career. As a veteran pro coder, I want YOU to learn the same valuable lessons I did…but faster.
    &lt;/p&gt;
    &lt;p&gt;
      Go and grab your copy and learn what your university or boot camp didn’t have time to teach you!
    &lt;/p&gt;
    &lt;span class=&quot;custom-button&quot; onclick=&quot;window.location.href=&amp;#x27;/12-rules/offer&amp;#x27;;&quot;&gt;
      GET YOUR COPY NOW!
    &lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;right-column&quot;&gt;
    &lt;a href=&quot;/12-rules/offer&quot;&gt;
      &lt;img src=&quot;/images/books/12RulesforProCoders_Medium.jpg&quot; alt=&quot;12 Rules for Pro Coders&quot; class=&quot;promo-image&quot;&gt;
    &lt;/a&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
  .two-column-layout {
    display: flex;
    gap: 20px;
    align-items: center;
	margin-top: 40px;
	margin-bottom: 40px;
  }

  .left-column {
    flex: 2;
  }

  .right-column {
    flex: 1;
    text-align: center;
  }

  .promo-image {
    max-width: 100%;
    height: auto;
    border-radius: 10px;
  }

  .custom-button {
    display: inline-block;
    padding: 10px 20px;
    background-color: #007bff;
    color: #fff;
    font-weight: bold;
    text-align: center;
    border-radius: 5px;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.3s ease;
    margin-top: 10px;
  }

  .custom-button:hover {
    background-color: #0056b3;
  }
&lt;/style&gt;
&lt;hr&gt;
&lt;p&gt;Needless to say, I was hooked.&lt;/p&gt;
&lt;p&gt;I began watching more videos. I wanted to learn more ways to draw.&lt;/p&gt;
&lt;p&gt;Talk about a rabbit hole.&lt;/p&gt;
&lt;p&gt;But that ain’t everything. Turns out, Procreate also lets you export a time-lapse video built up out of every keystroke used to make your drawing.&lt;/p&gt;
&lt;p&gt;At the same time, in the thick of building our slide show content for our customers, I had been imbued with a real love for our product, CockroachDB, such that I began a pencil
sketch of all its bits and pieces.&lt;/p&gt;
&lt;p&gt;When I showed this to our team’s social media manager, he begged me to turn that time-lapse into a YouTube Short.&lt;/p&gt;
&lt;p&gt;I couldn’t resist, and so here it is.&lt;/p&gt;
&lt;iframe width=&quot;315&quot; height=&quot;560&quot; src=&quot;https://www.youtube.com/embed/AZnMnzQ797U&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media;
gyroscope; picture-in-picture;
web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;
&lt;/p&gt;&lt;p&gt;Have you ever found something, be it a hobby or something else, that you found rewarding?&lt;/p&gt;
&lt;p&gt;Reply to this email and let me know.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.S. Consider becoming a &lt;a href=&quot;http://procoder.io/member&quot;&gt;PREMIUM member &lt;/a&gt;if you want first dibs on EVERYTHING! I already shared with them my time-lapsed video of creating the cover for What Is A Database?, which you can now enjoy down below.&lt;/strong&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="1000" height="1000" medium="image" url="https://www.procoder.io//_astro/procreate-apple.ebChzGXg.png"/></item><item><title>Are you optimizing too much?</title><link>https://www.procoder.io/articles/2025/2025-08-29-are-you-optimizing-too-much</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-08-29-are-you-optimizing-too-much</guid><description>Sometimes constant optimization just digs you deeper into old assumptions. Real breakthroughs come when you pause, question the paradigm, and explore simpler, faster alternatives.</description><pubDate>Fri, 29 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’m always reaching for something to speed things up. Databases queries. Server startup times. Render time of my website.&lt;/p&gt;
&lt;p&gt;It’s easy to have picked a stack and push forward. You hit a bump so you optimize.&lt;/p&gt;
&lt;p&gt;And push forward.&lt;/p&gt;
&lt;p&gt;Hit another bump and optimize. Push forward again.&lt;/p&gt;
&lt;p&gt;The thing is, when you take a given paradigm and continue to keep going down the path of optimizing it, you may not realize the assumptions that begin dragging
you down.&lt;/p&gt;
&lt;p&gt;Let’s take Wordpress. Wordpress was a popular answer to the &lt;strong&gt;LAMP&lt;/strong&gt; stack. 20 years ago more or less, Linux/Apache Web Server/MySQL/PHP formed a nice little team.&lt;/p&gt;
&lt;p&gt;For those of you not born in yesteryear…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L&lt;/strong&gt; = Linux&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt; = Apache Web Server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M&lt;/strong&gt; = MySQL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;/strong&gt; = PHP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L + A + M + P = LAMP&lt;/p&gt;
&lt;p&gt;LAMP was versatile. LAMP was easy to install. And Wordpress leveraged these pieces quite well.&lt;/p&gt;
&lt;p&gt;People poured effort into Wordpress’s core. Untold plugins were built. Caching solutions were designed.&lt;/p&gt;
&lt;p&gt;The whole thing hummed along. It took less and less effort for the user to stand up a site, create content, and publish. Getting a website for your customer up and running became easier and easier.&lt;/p&gt;
&lt;p&gt;But there is an issue in optimizing this way.&lt;/p&gt;
&lt;p&gt;What if you could build a website WITHOUT a database? Without dynamic endpoints? Without a traditional CMS (Content Management System)?&lt;/p&gt;
&lt;p&gt;I was lured into Wordpress for so long it wasn’t &lt;a href=&quot;https://www.procoder.io/articles/2025/2025-02-26_been-hacked--i-have--6717be8d873f&quot;&gt;until a hacker hit my websites&lt;/a&gt; that it shook me loose enough that I asked “is there another way?”&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.procoder.io/articles/2025/2025-02-26_been-hacked--i-have--6717be8d873f&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*1Z2WiVEz00KT2nBxrOivTA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I began to think. I was curious.&lt;/p&gt;
&lt;p&gt;Mind you, I had stood up a WP site simply to provide a URL shortener with my own domain (trnq.st). It was NEVER performant. And all its redirect stats were locked away.
(What do you expect from a website where every single hit was a call to a database?)&lt;/p&gt;
&lt;p&gt;I started having a little conversation with ChatGPT.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“I have this website used solely for URL shortening and redirects”. &amp;#x3C;--- me&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In its exuberance, it offered to rewrite the whole thing with a Python script and a JSON data file!&lt;/p&gt;
&lt;p&gt;In no time, we rez’d up a solution. A STATIC solution. Every redirect was captured as a &lt;strong&gt;JSON entry&lt;/strong&gt; and the &lt;strong&gt;Python script&lt;/strong&gt; would generate a simple HTML file for each entry.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/articles/2025/redirects.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;And thanks to my eternal desire to have CI/CD pipelines perform all builds and releases, we also assembled a &lt;strong&gt;GitHub workflow&lt;/strong&gt;. Every new addition to that JSON data
file and the website would rebuild itself and redeploy as a static GitHub Page.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Generate and Deploy Redirects&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    branches&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;jobs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  build-and-deploy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    runs-on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ubuntu-latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    steps&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Checkout private repo (`trnq.st`) using GitHub Actions default token&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/checkout@v3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          repository&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;gregturn/trnq.st&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          token&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  # Uses default GitHub Actions token&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Set up Python&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/setup-python@v3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          python-version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;3.x&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Generate redirect pages&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          mkdir -p public&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          python generate.py&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Ensure clean `public_site` directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;rm -rf public_site&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Deploy to `trnq.st-site` (Public Repo) using `GH_PAT_DEPLOY`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git clone https://github.com/gregturn/trnq.st-site.git public_site&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          cd public_site&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git config --global user.name &quot;github-actions[bot]&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git config --global user.email &quot;github-actions@users.noreply.github.com&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          mv CNAME ../CNAME.bak || true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git rm -rf .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          mv ../CNAME.bak CNAME || true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          cp -r ../public/* .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git add .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git commit -m &quot;Auto-update from trnq.st&quot; || echo &quot;No changes to commit&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          git push https://x-access-token:${{ secrets.GH_PAT_DEPLOY }}@github.com/gregturn/trnq.st-site.git main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What a joy!&lt;/p&gt;
&lt;p&gt;ChatGPT and I then went on to build some additional GitHub workflows that made it possible to add new redirects to that JSON data file through the magic of
GitHub issues!&lt;/p&gt;
&lt;p&gt;But building this gem of a website had unearthed something incredible.&lt;/p&gt;
&lt;p&gt;A redirect website is one thing. Simple. Flat. Easy to grok because the essence of it was a single Python script.&lt;/p&gt;
&lt;p&gt;But what about ProCoder.io? The flagship of my medium I had built to share all my mistakes with, well, you!&lt;/p&gt;
&lt;p&gt;Could ChatGPT and I rebuild all THAT?&lt;/p&gt;
&lt;p&gt;The Pro Coder website is much more. It lets me sell books. It facilitates &lt;a href=&quot;https://www.procoder.io/list&quot;&gt;signing up for my free newsletter&lt;/a&gt; (including a freely downloadable e-book).&lt;/p&gt;
&lt;p&gt;What if I threw Wordpress out the window and rebuilt that?&lt;/p&gt;
&lt;p&gt;Statically.&lt;/p&gt;
&lt;p&gt;With no database. No CRM. No logins.&lt;/p&gt;
&lt;p&gt;No administrative dashboard.&lt;/p&gt;
&lt;p&gt;Just commits published to a private repo. What about that?&lt;/p&gt;
&lt;p&gt;Spoiler Alert: You CAN.&lt;/p&gt;
&lt;p&gt;We can talk about the specifics another time.&lt;/p&gt;
&lt;p&gt;The point is that every now and then, it’s good to pause and question some of the core assumptions and arguments that led you to where you’re presently
standing.&lt;/p&gt;
&lt;p&gt;Are you making vast improvements? Or are you optimizing down a dead end at ever diminishing rates? It’s sometimes hard to see.&lt;/p&gt;
&lt;p&gt;—Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this livestream where I figured out I’ve been spending too much time on social media!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="1536" height="1024" medium="image" url="https://www.procoder.io//_astro/wordpress-or-openai.C9WULp5Q.png"/></item><item><title>I have a new book ready for you...</title><link>https://www.procoder.io/articles/2025/2025-08-17_i_have_a_new_book_ready_for_you</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-08-17_i_have_a_new_book_ready_for_you</guid><description>...and it&apos;s FREE! Find out how AI can help YOU. As a subscriber to this newsletter, I&apos;m spilling the beans on how AI has changed my complete approach to software development. And it&apos;s chock full of advise you can start using TODAY.</description><pubDate>Sun, 17 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…and it’s free! Keep reading to secure your free copy of &lt;strong&gt;&lt;em&gt;Pro Coders Guide to AI&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“In the realm of action there is nothing perpetual but change.”
—Ludwig von Mises, &lt;em&gt;Human Action&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my 28 year career as a pro coder I’ve seen a lot of changes in the industry. Some of the biggest changes I have seen include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search engines&lt;/li&gt;
&lt;li&gt;IDEs with almost prescient awareness of what I need&lt;/li&gt;
&lt;li&gt;Laptops today that run circles around the UNIX workstations of old&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But nothing, and I mean &lt;strong&gt;nothing&lt;/strong&gt;, beats the revolutionary arrival of AI tools to help with crafting code.&lt;/p&gt;
&lt;p&gt;Yes AI tools introduce a new level of noise. And “hallucinations” isn’t something I ever expected to be a term of art that would enter our realm.&lt;/p&gt;
&lt;p&gt;But I’ve actually been using various AI tools in a multitude of ways over the past year. It’s hard to share all the ways AI has helped me and all the ways AI has also fallen flat on its face in a newsletter.&lt;/p&gt;
&lt;p&gt;So I instead wrote a book. And it’s &lt;strong&gt;&lt;em&gt;free&lt;/em&gt;&lt;/strong&gt;. For you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pro Coder’s Guide to AI&lt;/em&gt;&lt;/strong&gt; book will eventually go on sale to the general public for a price. But today I’m making it free for you in e-book formst.&lt;/p&gt;
&lt;p&gt;And I’m delivering it to you through my brand-new book delivery system I put together. To get it, you need to &lt;a href=&quot;/subscribe/pro-coders-guide-to-ai-launch-a3GqerEGcz&quot;&gt;&gt;&gt;&gt; click on this link &amp;#x3C;&amp;#x3C;&amp;#x3C;&lt;/a&gt; and enter your name and email address. My system will create a unique download link and send it to you in a separate email.&lt;/p&gt;
&lt;p&gt;Click on that, and you’ll have a copy of my book!&lt;/p&gt;
&lt;p&gt;Then, soon, I’ll start live-streaming where we can talk about how I rebuilt ProCoder.io from the ground up with a little help from you-know-who.&lt;/p&gt;
&lt;p&gt;—Greg&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I basically have departed social media…for good!&lt;/strong&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="4570" height="3500" medium="image" url="https://www.procoder.io//_astro/Pro_Coders_Guide_To_AI.BQ20EBb4.png"/></item><item><title>Do you backup your systems?</title><link>https://www.procoder.io/articles/2025/2025-08-11_do-you-backup-your-systems</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-08-11_do-you-backup-your-systems</guid><description>Are you ready to lose absolutely everything? That decision isn&apos;t free. Let me tell you what helped me choose.</description><pubDate>Mon, 11 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At the end of March my sister-in-law’s house burned down. She and her family moved in with us that night for the next two months. We went from 5 residents of
our little domicile to eleven. Overnight.&lt;/p&gt;
&lt;p&gt;I’ve held off writing this because frankly, the whole thing was shocking. To all of us! I didn’t want to rush this before I could genuinely
decide it was time.&lt;/p&gt;
&lt;p&gt;It’s time.&lt;/p&gt;
&lt;p&gt;(No one was hurt. And they have since found a rental to have their own space as they rebuild. Thanks for your concern.)&lt;/p&gt;
&lt;p&gt;Watching the fallout of that made me start double thinking some of my backup systems!&lt;/p&gt;
&lt;p&gt;If you ever build a RAID array to start doing backups…one of the first things you hear is “that’s not REALLY a backup!”&lt;/p&gt;
&lt;p&gt;A backup to another system isn’t REALLY a backup at all!&lt;/p&gt;
&lt;p&gt;And on some level that’s true. Why?&lt;/p&gt;
&lt;p&gt;After all…if your house burns down you’ve got nothing. See?&lt;/p&gt;
&lt;p&gt;But like anything, there’s no need to be pedantic. Standing up a RAID array and scheduling daily backups is the first step. It guards against immediate machine
failure.&lt;/p&gt;
&lt;p&gt;And so daily backups to a local RAID array IS a backup. At least it is to me.&lt;/p&gt;
&lt;p&gt;I stood mine up years ago. But ever since I watched a family of six join us for two months, my mind has gone back to the drawing board.&lt;/p&gt;
&lt;p&gt;And my conclusion? What we have ISN’T ENOUGH.&lt;/p&gt;
&lt;p&gt;Now I’m contemplating buying a SECOND RAID array and linking it to the first. And then staging it at someone else’s house.&lt;/p&gt;
&lt;p&gt;Maybe this is getting too specific. The idea of this article is to pique your interest. Do you have any backup solution at all? To lay it all on the table I
have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Synology 4-bay RAID array with a pair of 8 TB NAS drives. A real turnkey apparatus.&lt;/li&gt;
&lt;li&gt;I run Carbon Copy Cloner on all my machines. Despite Time Machine’s delicious
UI, &lt;a href=&quot;/articles/2022/2022-01-29_you-have-failed-me-for-the-last--time-machine--a1cd9473f90a&quot;&gt;it has failed me too many times&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s pretty much it.&lt;/p&gt;
&lt;p&gt;Linux has a world of tools to build RAID systems with LVM. But the cost of a Synology device is low enough, and considering it’s using all that under the hood
anyway, that it’s easier to just buy the box and get going.&lt;/p&gt;
&lt;p&gt;Hence, buying a second box should be pretty easy. I just need to figure out the part where I have these two devices linked to each…over the Internet…without
compromising security.&lt;/p&gt;
&lt;p&gt;I experimented with Cloudflare’s Zero Trust product a bit. And got dragged down a rabbit hole.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/articles/2025/man-thinking.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;It’s basically a VPN solution with a twist. Or rather multiple twists.&lt;/p&gt;
&lt;p&gt;Founded on network edge management, they offer a lot of nice services. And as a side effect they really can build VPN tunnels. I just haven’t caught on to all
the twists. Not yet.&lt;/p&gt;
&lt;p&gt;So I’ll probably doing more reading on that front.&lt;/p&gt;
&lt;p&gt;What are you doing? Any backups at all?&lt;/p&gt;
&lt;p&gt;The first level of backing stuff is simply buying an external drive. They have ‘em everywhere. Can you rig it so that everyone out plug that external drive into
your machine it takes a backup?&lt;/p&gt;
&lt;p&gt;The second level is realizing that this isn’t good rough. This is what dawned on me as the Mrs. and I started taking more and more pictures of the kids as they
grew. We had a treasure trove and i feared losing those digital memories. This was the reason to stand up an always-on NAS.&lt;/p&gt;
&lt;p&gt;The third level is backing up your backup. That’s where I am right now.&lt;/p&gt;
&lt;p&gt;If you’re wondering “are there any cloud based solutions?” The answer is yes.&lt;/p&gt;
&lt;p&gt;And I used to use them. But somewhere along the way, maybe 10 years ago, they all pivoted toward a metered-based pricing model and the costs jumped. Too high
IMHO.&lt;/p&gt;
&lt;p&gt;I could actually keep yammering on and on about this, but I sense I may be wearing out my welcome. So let’s land the plane already!&lt;/p&gt;
&lt;p&gt;I want you to think about what’s important to you. Digitally.&lt;/p&gt;
&lt;p&gt;And then think about what would happen were you to lose those digital assets and had to start from zero.&lt;/p&gt;
&lt;p&gt;And then start setting aside a little money to cover the cost of restoration. What a simple $20 in an envelope?&lt;/p&gt;
&lt;p&gt;Eventually, that envelope will grow large enough, and the desire to not start from zero will be strong enough, that these two can meet and you’ll take action.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video of me painting one of
my recent book covers! Who knows? I may show you HOW I did that in a future article.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="2048" height="1536" medium="image" url="https://www.procoder.io//_astro/burning-down.m0oG9Q23.JPG"/></item><item><title>I’m leaving social media...</title><link>https://www.procoder.io/articles/2025/2025-07-28_im-leaving-social-media</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-07-28_im-leaving-social-media</guid><description>I&apos;m leaving social media...for good! X, Twitter, Facebook, everything. But we can still stay in touch!</description><pubDate>Mon, 28 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…forever!&lt;/p&gt;
&lt;p&gt;I’m done.&lt;/p&gt;
&lt;p&gt;I’m signing off of X/Twitter. I already left Facebook two years ago. And I never really got far with Instagram or Pinterest.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And I’m not coming back.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Studies show people average &lt;em&gt;2 hours every day&lt;/em&gt; simply scrolling?&lt;/p&gt;
&lt;p&gt;Here’s the kicker. It ain’t from sitting down and flipping through for a solid two hours. Nope. It’s a minute here. Two minutes there.
In between your kids kicking a goal at a soccer match. Or those three minutes during a meeting at work.&lt;/p&gt;
&lt;p&gt;If you wonder why the Pro Coder Show hasn’t aired an episode since September 2024, &lt;strong&gt;&lt;em&gt;that’s a piece of it&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now mind you, I’m not innocent in all this. There are ADDITIONAL reasons why all that I’ve squeezed out since then has been
half-a-dozen members-only livestreams in the interlude. But 14 hours each and every week &lt;strong&gt;is certainly a decent portion of it&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To answer the question in the back of your mind, I’m not leaving for any political reason.
I frankly find it loathsome to discuss political affairs online. If you search my social media presence you’ll find it devoid of political jabbering.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;No, this is because I am reclaiming my life.
Scrolling on social media platforms is documented to have depressive effects on people’s mentality and it’s frankly &lt;strong&gt;not good&lt;/strong&gt; for business.&lt;/p&gt;
&lt;p&gt;Social media used to offer gobs of “free traffic”.
That was really useful for book sales, published articles, and your latest video.
Anything you want.&lt;/p&gt;
&lt;p&gt;But all that kind of ended around 2018.
All the platforms switched to an “algorithm”.&lt;/p&gt;
&lt;p&gt;This “algorithm” has been described as being in a stadium full of 100,000 people, all shouting.
And all you can hear is whoever has the mic on stage RIGHT NOW, or someone right next you WHEN YOU’RE FACING them.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Kind of reminds me of a Jason’s Deli that opened years ago in Melbourne, FL when I lived down there. The sandwiches were stacked so tall, Dagwood Bumstead couldn’t get a bite! But after about six months, they stopped stacking ‘em so tall. Can you guess why?&lt;/p&gt;
&lt;p&gt;The truth is, social media baited us all with “free” traffic. And then they cashed in. Well I’m cashing out.&lt;/p&gt;
&lt;p&gt;Doesn’t mean I’m not making more content. Actually, the opposite. I’ll be creating MORE content. Just for you. Social media will no longer get between us.&lt;/p&gt;
&lt;p&gt;If you want to continue hearing about my mistakes as a 28-year veteran in the industry and learn how to dodge some of the potholes, I encourage you to &lt;a href=&quot;/list&quot;&gt;sign up for my newsletter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am also resuming the &lt;strong&gt;Pro Coder Show&lt;/strong&gt;. You can either &lt;a href=&quot;https://www.youtube.com/@ProCoderIO?sub_confirmation=1&quot; target=&quot;_blank&quot;&gt;subscribe for it on YouTube&lt;/a&gt; or catch it on your &lt;a href=&quot;https://podcast.procoder.io&quot; target=&quot;_blank&quot;&gt;favorite podcasting platform&lt;/a&gt; (or both!)&lt;/p&gt;
&lt;blockquote&gt;
  “He who has the gold makes the rules!”&lt;br&gt;
  &lt;div style=&quot;text-align: right;&quot;&gt;—The Golden Rule as explained by Nelson Nash&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;I am taking my experiences and wisdom, my “gold” if you will, off social media and instead investing them 100% into this website in the form of articles, newsletters, and podcasts.
All of which you are free to consume 100% at no charge.&lt;/p&gt;
&lt;p&gt;I rebuilt Pro Coder to serve those needs, and will be delving into how I used my talent, experience, and a touch of AI to make it happen, so sign up if you want to catch that!&lt;/p&gt;
&lt;p&gt;(If you choose to grab a copy of my latest books as they come out, be my guest.)&lt;/p&gt;
&lt;p&gt;I invite you to join me on this journey. Feel free to share anything that tickles your fancy with a friend. In truth, content is best shared this way. Word of mouth is well documented as the most solid “sell” of any good.&lt;/p&gt;
&lt;p&gt;I’ll do my best to make it worth your time.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.S. Don’t forget to sign up to get the &lt;a href=&quot;/list&quot;&gt;latest lessons learned&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Writing Off Social, &lt;a href=&quot;https://writingoffsocial.com/1-2/&quot; target=&quot;_blank&quot;&gt;Ep. 1: Why We Left Social Media&lt;/a&gt;, Sandy and Mary K. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded><media:content type="image/png" width="1536" height="1024" medium="image" url="https://www.procoder.io//_astro/i&apos;m-leaving-social-media.B_U7z7Xl.png"/></item><item><title>Teaching software is harder than writing it</title><link>https://www.procoder.io/articles/2025/2025-03-19_teaching-software-is-harder-than-writing-it-ee3b1eefca9b</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-03-19_teaching-software-is-harder-than-writing-it-ee3b1eefca9b</guid><description>Reflections on my first year as a bona fide teacher.</description><pubDate>Wed, 19 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Being in the trenches of software development for 28 years, I’ve seen a lot. Writing software is HARD!&lt;/p&gt;
&lt;p&gt;I remember an article that surfaced back in 2011 titled “Yes, Virginia, Scala is hard.” It was written by a prominent fan of Scala that seriously challenged some of what Scala embraced.&lt;/p&gt;
&lt;p&gt;What it kicked off was a furious debate in multiple platforms that IMHO was about the trade off between more powerful constructs vs constructs used by the masses.&lt;/p&gt;
&lt;p&gt;I’m not here to revisit THAT debate.&lt;/p&gt;
&lt;p&gt;What I’m here to dig into is another age old wrinkle…training up the next generation of pro coders.&lt;/p&gt;
&lt;p&gt;You may not know this but I used to study martial arts. Unfortunately I had to give it up due to arthritis in my knees. But something I had learned at the time was how to teach others.&lt;/p&gt;
&lt;p&gt;There’s a mantra thst says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The fastest way to learn something is to teach it to someone else.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That may sound kooky or flat out wrong. But it’s actually true.&lt;/p&gt;
&lt;p&gt;You see to teach someone else, you need a certain amount of understanding yourself. Not 100%. But enough to get the basics.&lt;/p&gt;
&lt;p&gt;The REAL challenge is when you start getting questions.&lt;/p&gt;
&lt;p&gt;This is the feedback loop of the most common challenge with the content you’re sharing. And so you end up either knowing the answer by digging for the answers, thus forming mental pathways for yourself and the person you’re teaching.&lt;/p&gt;
&lt;p&gt;As I helped junior Tae Kwon Do students with basics, I was getting schooled in the same.&lt;/p&gt;
&lt;p&gt;Let me ask you, do world class athletes practice fundamentals? Ever?&lt;/p&gt;
&lt;p&gt;You’re darn right they do!&lt;/p&gt;
&lt;p&gt;Every day. Probably a key thing to maintain their skill.&lt;/p&gt;
&lt;p&gt;Practicing your skills whether you’re a beginner or a pro is VITAL. I was practicing my martial arts discipline twice: once during my own lessons and once when helping others.&lt;/p&gt;
&lt;p&gt;And the feedback was always there.&lt;/p&gt;
&lt;p&gt;Either my own master coached me, or the questions from a junior student pushed back on me.&lt;/p&gt;
&lt;p&gt;This ain’t something you can teach sitting on your dairy air!&lt;/p&gt;
&lt;p&gt;Same goes for training pro coders.&lt;/p&gt;
&lt;p&gt;As I host episodes of SELECT STAR, create drawings for slide decks, or assemble a challenge exercise, not only do I have to get it working, I want this content to align with our official documentation. I want it to match our best practices.&lt;/p&gt;
&lt;p&gt;I’m constantly reviewing things and either taking feedback to the Docs team or to someone else.&lt;/p&gt;
&lt;p&gt;Iterative feedback is GREAT! Intense, but great.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are you aware that the span of time between the Wright brothers first powered flight and us landing on the moon is only about 60 years?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That’s what I think of as a solid 60 YEARS of engineering feedback. That is a golden era of development.&lt;/p&gt;
&lt;p&gt;Feedback is INCREDIBLE. Don’t knock it when feedback is brought to you.&lt;/p&gt;
&lt;p&gt;It’s been tough but quite gratifying. Training that genuinely strives for top notch content instead of summaries and simplistic boiled down artifacts can elevate whole teams. Empower fellow developers.&lt;/p&gt;
&lt;p&gt;Who doesn’t want that?&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video an old friend of mine and I discuss why YOU may be your best investment!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_S0sQmck-bkYMSGuU7K-vog.BK86IV2n.png"/></item><item><title>Been hacked? I have.</title><link>https://www.procoder.io/articles/2025/2025-02-26_been-hacked--i-have--6717be8d873f</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-02-26_been-hacked--i-have--6717be8d873f</guid><description>Taking on ALL the roles as tech support for my wife’s LLC can be a harrowing experience.</description><pubDate>Wed, 26 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Being a pro coder, there is no shortage of questions that come my way when people “learn” what I do. The question I always want to know is, why are at least HALF of them all about tech support?!?&lt;/p&gt;
&lt;p&gt;Whelp I guess it was prone to happen sooner or later.&lt;/p&gt;
&lt;p&gt;My wife’s website which undergirds her publishing business gots HACKED.&lt;/p&gt;
&lt;p&gt;The website was offline. I tried to get in. I couldn’t. I pinged tech support. They came back and told me the server was humming right along. I said “no it’s not.” They ran a scan. And…&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*yGqQ1oVf6I_q3Vlq6eCTAA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Okay, I guess I’ve been LARPing as tech support long enough that the Good Lord has decided to serve me a dose of humility. &lt;em&gt;Noted!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Time to get cracking, ehh?&lt;/p&gt;
&lt;p&gt;Fun fact: I actually have five websites hosted on this server. They’re ALL offline. Alas, only one of them is the basis for my wife’s publishing business so I already know which one to focus on first.&lt;/p&gt;
&lt;p&gt;Maybe I’m the CFO of my wife’s enterprise. Maybe I do the books and coordinate with our accountant.&lt;/p&gt;
&lt;p&gt;But the truth is, I’m the one that makes all the software “go.” So taking my years of experience, and remembering what a friend of mine once said, “when a website is eaten up like that, just start with a fresh install.”&lt;/p&gt;
&lt;p&gt;I can spend gobs of time trying to suss it all out, but I’ll probably be better if I start from scratch. And I will. However, there are a COUPLE things I’d like to bring along.&lt;/p&gt;
&lt;p&gt;Like all the images that my wife uploaded to her Wordpress site. Now how in the world could I possibly grab all the existing images from her old site WITHOUT GOING to her old site and upload them to a new site?&lt;/p&gt;
&lt;p&gt;Easy.&lt;/p&gt;
&lt;p&gt;Find another source. Like…the Wayback Machine at the Internet archive!&lt;/p&gt;
&lt;p&gt;I actually started writing another book, and a good chunk of is written. In one of the chapters, I demonstrate how I leveraged ChatGPT to create a tool that would let me download EVERY SINGLE IMAGE from another Wordpress site.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*VfEiTQX3ojo694LB2gBSKw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;The book I’m in the middle of writing will be called PRO CODER’S GUIDE TO AI. As a content creator, the prudent thing would be to offer a pre-sale buy link right here in the middle of the article.&lt;/p&gt;
&lt;p&gt;Unfortunately, the site where I would OFFER that pre-sale link was also hacked. So I’ll just have to trust that when the time is right, and my job as “tech support” has been carried out, I can solicit your support. 😇&lt;/p&gt;
&lt;p&gt;Back to “tech support” crisis management!&lt;/p&gt;
&lt;p&gt;Looks the script ChatGPT and I worked up is going to be needed sooner rather than later. Since this is a combo of database + PHP files + uploaded content, I am going to find out if the database is intact and this hack job is pure file-based.&lt;/p&gt;
&lt;p&gt;If it’s just files on the server, then a scrape-and-load with a restored database won’t be quite as devastating a thing.&lt;/p&gt;
&lt;p&gt;I am suspicious of some plugin I was using that was the culprit. I thought I had phased out that plugin and removed it altogether, but the scans from my hosting provider showed signs of it still being there.&lt;/p&gt;
&lt;p&gt;Ho-hum. In the words of Willy Wonka, I’ll figure it out. I always do.&lt;/p&gt;
&lt;p&gt;Sometimes being a pro coder and solving other people’s problems means putting aside your glorified authoring of beautiful majestic code, and instead being the janitor of someone else’s Wordpress site.&lt;/p&gt;
&lt;p&gt;People come to us pro coders because we have experience. We have our “spidey senses” that guide on when it’s okay to push a button or when not to and instead read a little more.&lt;/p&gt;
&lt;p&gt;I have patched many servers. Sussed out systems for 24x7x365 systems that sustained comm systems between air traffic controllers and aircraft in flight.&lt;/p&gt;
&lt;p&gt;I have experience the Mrs. doesn’t. And so it’s my job to pick the most efficient route to resolve all this and get her website operational again. And to rinse and repeat for my other sites.&lt;/p&gt;
&lt;p&gt;And once all is said and done, to offer you that pending book!&lt;/p&gt;
&lt;p&gt;It’s not the most EXCITING task I’ve been handed. But I actually look forward to solving this catastrophe and restoring order. And hopefully, having better controls in place.&lt;/p&gt;
&lt;p&gt;There is joy when we do what we are called to do. Software stuff is what I was called to do. And so when I accomplish something, even if it’s not “on the clock”, I still relish that accomplishment and smile.&lt;/p&gt;
&lt;p&gt;What about you? Does pro coding provide satisfaction to you?&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I show EXACTLY how to interview like a champ, even in a struggling economy!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_1Z2WiVEz00KT2nBxrOivTA.CayCLWjV.jpeg"/></item><item><title>To AI or not to AI, that is the question!</title><link>https://www.procoder.io/articles/2025/2025-01-17_to-ai-or-not-to-ai--that-is-the-question--6d877eb88571</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-01-17_to-ai-or-not-to-ai--that-is-the-question--6d877eb88571</guid><description>Knowing when and when NOT to use AI is vital for all pro coders</description><pubDate>Fri, 17 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s no question that AI has emerged rapidly and swept not just the tech industry, but many other industries by storm!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Before we go any further, I understand that you may disagree with the term “AI”. These tools have no real “intelligence” whatsoever. You are probably right. But it doesn’t matter. This article focuses on the utility of these tools, not their metaphyiscal implications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Part of the evidence that AI tools are “it” is the fact that every third ad I see on YouTube is for someone’s course on how you can making five-figures of passive income today. &lt;em&gt;You and I both know THAT’s not going to happen.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;so-what-is-ai-good-for-and-what-should-we-not-be-using-itfor&quot;&gt;So what IS AI good for? And what should we NOT be using it for?&lt;/h3&gt;
&lt;p&gt;For starters, since it’s probably at least ONE of the questions in the back of your mind, let me answer the following question: &lt;em&gt;Greg, did you use AI to write this articles?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This article (nor none of my others) was NOT written using any AI tools.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I actually took a stand in my latest books &lt;strong&gt;against&lt;/strong&gt; using AI to write any bit of prose. I even stated it outright, up front, for everyone to see, in the copyright page shown below of my first book to be published since my departure from the Spring team:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Br01J0BS4zmIfESv30Dl3Q.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Soon after I released this book, Amazon added a REQUIRED prompt to the its upload process asking “Is this content generated by AI?”&lt;/p&gt;
&lt;p&gt;People ARE writing books using AI. People are COMPLAINING about AI-written books. People FEAR the market being flooded with AI junk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And I whole-heartedly agree that letting AI tools write your book for you is absolutely, 100%, as clear as I can say it &lt;em&gt;WRONG&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I’ve been writing for years. I studied ad copy. Penned hundreds of blog posts, articles, and am have started what will soon be my 10th and hopefully 11th book (yes, I have two books in flight right now).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One of your most valued assets is the “voice” you develop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Heck, I’ve had to push back on edits from a past publisher when they tried to “edit out” my voice!&lt;/p&gt;
&lt;p&gt;This lovable, tech-oriented, snarky prose you are reading is 100% me. AI can’t replace that.&lt;/p&gt;
&lt;p&gt;But I have to let you know…authors are pretty HORRIBLE at ad copy.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But Greg, why do authors need ad copy??&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ad copy is something that once you discover and learn what it is, you can’t help but see it. EVERYWHERE. It’s the stuff that reads kind of like “&lt;em&gt;Grab your copy of 5 Ways To Do ___ and learn how to make money TODAY!&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;That expression has some key aspects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Action-based&lt;/strong&gt;: Notice the comand to “grab”? This is a strong action.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Active&lt;/strong&gt;: Notice usage of “you” and “today”? This is aimed at the person reading it, and creating a sense of urgency making it very active.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Appealing&lt;/strong&gt;: Notice the drive to help the reader “make money”? This signals the value at taking on the offer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re going to write, you need a &lt;em&gt;&lt;strong&gt;certain&lt;/strong&gt;&lt;/em&gt; amount of this. After all, if you’re writing an article on Medium, you definitely want to convince someone seeing it for the first time to &lt;strong&gt;click&lt;/strong&gt; on it. You just don’t want TOO much. Don’t want to sound like a slippery car salesman, right?&lt;/p&gt;
&lt;p&gt;But you can see how ad copy is DIFFERENT than prose, right? Hence, authors can build up their prose-writing talent, but not know how to write ad copy. Not know how to write up a 1-paragraph pitch to convince an acquisition editor to convince them to give that person a book-writing contract!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enter AI tools!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AI tools are GREAT at this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Read this article and give me a 1-paragraph summary using middle school writing level ad copy that drives the person to click on the link at the bottom.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You type prompt into a tool like ChatGPT, then append your actual article, and in seconds, you have a nicely written up paragraph. It might be a tad off. Need a slight tuneup. But it’s probably better than what you would have written from scratch.&lt;/p&gt;
&lt;p&gt;And this is a splendid usage of AI.&lt;/p&gt;
&lt;p&gt;Were you going to hire someone to write it before the emergence of AI? Lots of authors don’t have much in resources, so probably not. You would have struggled to write it yourself, but that’s what you would have done.&lt;/p&gt;
&lt;p&gt;Using AI to accomplish something you weren’t going to hire anyone else to do in the first place is probably okay.&lt;/p&gt;
&lt;p&gt;Speaking of getting stuff done without having to hire someone else, check out the sponsor of this article…&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*TUSnMiywr2ccvwVfhEThaA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;12 Rules For Pro Coders is chock full of painfully learned lessons&lt;em&gt;&lt;strong&gt;12 Rules For Pro Coders&lt;/strong&gt;&lt;/em&gt; is probably the easiest way to grab someone else’s hard-won experience and using it advance your OWN career.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.procoder.io/step/12-rules-page/&quot;&gt;Grab your copy&lt;/a&gt; and learn from my mistakes with actionable advice to accelerate your career!&lt;/p&gt;
&lt;p&gt;Now back to your fun AI article!&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-about-using-ai-atwork&quot;&gt;What about using AI at work?&lt;/h3&gt;
&lt;p&gt;As a content creator and training write in my current position, we have picked up and ran with AI tools!&lt;/p&gt;
&lt;p&gt;In this context, its our team’s job to create slides, runnable exercises, write video scripts, and produce drawings. No one else. Us.&lt;/p&gt;
&lt;p&gt;Remember how I mentioned hiring “someone else” up above? Yeah…that someone else in this situation…is just me.&lt;/p&gt;
&lt;p&gt;We sit down, draw up the list of things we need to cover in a given course. We glean input from SMEs, field staff, and architects to curate that high-level list.&lt;/p&gt;
&lt;p&gt;Then we fashion a multi-paragraph prompt where we describe the problem, explain “who” we are, explain “who” is receiving the training, explain what the output format is, and then feed it the list of material to cover. Then we sit back and watch it crank out a draft exercise.&lt;/p&gt;
&lt;p&gt;With the exercise in hand, we deploy the newly minted exercise to our environment that runs it.&lt;/p&gt;
&lt;p&gt;And then we test the HECK out of it!&lt;/p&gt;
&lt;p&gt;Oftentimes, the prose is GREAT! And oftentimes, the code fragments are way off.&lt;/p&gt;
&lt;p&gt;This is where we “do our job” and dig in to find out what the RIGHT way of doing each chunk of code (or each command).&lt;/p&gt;
&lt;p&gt;There is still a LOT of work to get this challenge exercise operational. But the point is, we didn’t start from zero. No, we started at 40% with someone we can edit. We noodled through it, and were able to focus on the criticals.&lt;/p&gt;
&lt;p&gt;The AI tool was able to help us knock out the prose and the structure, kind of like how an IDE can help you with formatting a Java class file including auto-generated getters and setters.&lt;/p&gt;
&lt;h3 id=&quot;is-that-it-using-a-tool-to-skip-over-the-beginning-phase-of-something&quot;&gt;Is that it? Using a tool to skip over the beginning phase of something?&lt;/h3&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;We go way further than that.&lt;/p&gt;
&lt;p&gt;Remember me mentioning slides earlier? We take our series of exercises and feed them back into the AI tool, and ask it to generate reveal.js/asciidoctor slides. The prompt has more details in it again describing who they are for, how the work with the exercises, and how we want to have Q&amp;#x26;A review questions after the exercises.&lt;/p&gt;
&lt;p&gt;And then the AI tool will crank out a round of slides.&lt;/p&gt;
&lt;p&gt;And then we can iterate on THAT.&lt;/p&gt;
&lt;p&gt;It’s really amazing how far you can get with this stuff. To top things off, we’ve noticed strengths in weakness in various AI tools. And we’ve figured out how to use them together.&lt;/p&gt;
&lt;p&gt;To explain how that works, there’s a riddle you may or may not have heard of.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You are standing outside two doors. Behind one door is a vast trove of riches beyond your wildest dreams. Behind the other door is certain death. You can open either door. Next to the doors are two guards. They both know what is behind which door. One always tells the truth, one always lies. If you could ask one question, what would it be?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The answer is to ask one of them, “which door would the other guy suggest?” and then open the OTHER door.&lt;/p&gt;
&lt;p&gt;If you are talking to the truth-teller, he will truthfully tell you that the other guy would lyingly recommend the door that offers death. So you pick the other door.&lt;/p&gt;
&lt;p&gt;If you are talking to the liar, he knows that the other guardian will tell you the door with the riches behind it. But he will lie and tell you to take the door that portends your death. So you pick the other door.&lt;/p&gt;
&lt;p&gt;You see, you are taking a shaky circumstance, and using BOTH of them together, to effect a positive change.&lt;/p&gt;
&lt;p&gt;With AI tools, their strength is being able to process HUGE volumes of text and then give you a guided answer based on your prescription.&lt;/p&gt;
&lt;p&gt;And so we will take the slide content generated by one AI tool, and carry it over to another AI tool and run it through a “finishing” process.&lt;/p&gt;
&lt;p&gt;We basically have ANOTHER prompt where we instruct this finisher that its job is to “edit” the first AI tool. Don’t alter the structure. But help clean up any code blocks. Also look for glaring issues.&lt;/p&gt;
&lt;p&gt;And in general, this has helped us crank out HUGE volumes of content.&lt;/p&gt;
&lt;p&gt;Now remember the criteria I mentioned earlier! The only people getting displaced by this…is us! We are the team that is building this content. So any tool that helps us speed up the write-read-review-test-update process directly, is a boon!&lt;/p&gt;
&lt;p&gt;What are you doing with AI?&lt;/p&gt;
&lt;p&gt;Someone has to verify every spec of the content the crosses your desk. That someone…is you.&lt;/p&gt;
&lt;p&gt;There is fear of these tools supplanting whole developers. That fear has some amount of justification. But there is going to be a growing number of people needed to cross-check and verify what is being generated.&lt;/p&gt;
&lt;p&gt;AI isn’t destroying any industries. It’s just another tool that can accelerate some things. The idea is to learn its strengths, make certain principaled decisions about what to use it and not use it for, and then be comfortable in the places that you’re okay with doing that.&lt;/p&gt;
&lt;p&gt;You’ve heard some of the ways I’m doing it (which includes generating banner images for these articles, someone I wasn’t going to pay anyone to do anyway). What about you? Have you used AI tools for anything? Put it in the comments!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I explain why the tech stack you use doesn’t REALLY matter as a pro coder!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_CfqV9y8zzTVqbeJCGY8y0g.UIJQBqTi.jpeg"/></item><item><title>Are you ready to commit yourself to being a pro coder in 2025?</title><link>https://www.procoder.io/articles/2025/2025-01-05_are-you-ready-to-commit-yourself-to-being-a-pro-coder-in-2025--e1053a8d2eb9</link><guid isPermaLink="true">https://www.procoder.io/articles/2025/2025-01-05_are-you-ready-to-commit-yourself-to-being-a-pro-coder-in-2025--e1053a8d2eb9</guid><description>Something every pro coder must embrace if they wish to truly make this more than a hobby</description><pubDate>Sun, 05 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is a keen fact that separates hobbyists and amateur enthusiasts from career-seeking pro coders: hobbyists can stop and start whenever they wish. A hobbyist can carry out a tutorial, try out a new stack, or experiment with a new library recently released. This is true.&lt;/p&gt;
&lt;p&gt;But a pro coder does all these things for the sake of their clients or the shop they work for.&lt;/p&gt;
&lt;p&gt;There are naturally consequences to this.&lt;/p&gt;
&lt;h3 id=&quot;we-cannot-stop-and-start-as-wewish&quot;&gt;We cannot stop and start as we wish.&lt;/h3&gt;
&lt;p&gt;While you should take breaks and re-energize suitably, you need to seek to move the needle. Drive things forward. Iterate on either a piece of code, a continuous integration job, or update the reference documentation &lt;em&gt;&lt;strong&gt;even when we don’t feel the passion&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Sometimes you’ll be tired.&lt;/p&gt;
&lt;p&gt;Sometimes you’ll be frustrated.&lt;/p&gt;
&lt;p&gt;And sometimes no one around you will have the answer you seek. You must find it yourself.&lt;/p&gt;
&lt;p&gt;A hobbyist in such a situation would set the issue on the shelf and go do something else. Perhaps another beginner’s tutorial. Or perhaps something else entirely.&lt;/p&gt;
&lt;p&gt;A pro coder squints his or her eyes, feels a desire a PASSION to defeat the problem laid bare, and pushes forward!&lt;/p&gt;
&lt;h3 id=&quot;we-must-learn-all-that-we-canlearn&quot;&gt;We must learn all that we can learn&lt;/h3&gt;
&lt;p&gt;There is something called the arrival syndrome. A situation where you feel as if you’ve “mastered” some topic and that there is no more to learn.&lt;/p&gt;
&lt;p&gt;The arrival syndrome is horrible and something that can take the most capable, most skilled people and let them decay into nothingness.&lt;/p&gt;
&lt;p&gt;There is always more to learn. New stacks. New toolkits. New protocols. New WAYS of doing some of the old things.&lt;/p&gt;
&lt;p&gt;I recently dig some digging into Cloudflare’s Zero Trust offering. I was interested in the possibility of accessing my RAID array’s internal Dropbox-equivalent FROM ANYWHERE ON THE INTERNET.&lt;/p&gt;
&lt;p&gt;But I didn’t want to open any ports if possible. Zero Trust is a “newer” way of building a VPN. I have enjoyed Cloudflare’s other offerings, so I dug into Zero Trust.&lt;/p&gt;
&lt;p&gt;I began reading docs. Configuring my home router in ways I didn’t know were possible. Gearing up my iPhone and my MacBook Pro to interact with Zero Trust. I’m not convinced it’s for me.&lt;/p&gt;
&lt;p&gt;But the point is, I have learned new things despite having been in this industry for 27 years!&lt;/p&gt;
&lt;p&gt;My favorite Christmas presents this year were three books. Two of them are Jack Reacher novels I haven’t read yet, the third being THE PIRATES OF MANHATTEN by Barry Dyke. I’m excited about all three.&lt;/p&gt;
&lt;p&gt;If you’re still reading, there is hope for you. If you haven’t read for years, it could be a sign. Let me know in the comments when you last read something and if you’re bold enough, what it was.&lt;/p&gt;
&lt;p&gt;In software development, the world changes rapidly. Learning is MUST. What you learned in college is probably obsolete if we’re talking about tech. But critical if what you learned include HOW TO LEARN.&lt;/p&gt;
&lt;p&gt;AI is upon us. I have already began dipping into different AI tools to lend me assistance in content creation. I don’t use them to write the words you are now reading. But I sure as heck have leveraged it to help me create introductory content, Q&amp;#x26;A post-session questions, graphics, even videos. We have no clue where this is going, but the potential for a revolution as great as the Industrial one is immense.&lt;/p&gt;
&lt;p&gt;Don’t. Stop. Learning.&lt;/p&gt;
&lt;h3 id=&quot;we-must-hone-our-craft-with-ourtools&quot;&gt;We must hone our craft with our tools&lt;/h3&gt;
&lt;p&gt;Have you ever wondered by doctor and dentists offices are called “practices”? It’s because while these people learned critical skills in medical school, it’s their daily work in which they PRACTICE their medical and dental arts.&lt;/p&gt;
&lt;p&gt;As pro coders, we must practice as well.&lt;/p&gt;
&lt;p&gt;This is why I am challenging you to explore working with at least THREE SPECIFIC IDEs this year. If you need a suggestion, I would recommend IntelliJ IDEA, VS Code, and Eclipse.&lt;/p&gt;
&lt;p&gt;If you don’t use Java, but instead another stack entirely, you’ll have to make a different choice.&lt;/p&gt;
&lt;p&gt;But the point is to pick up new tools and take them for a run. And to make it a real, sincere, &lt;strong&gt;learning&lt;/strong&gt; experience, I suggest you commit to at least &lt;em&gt;six weeks with each one&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The point is to learn how to navigate code. How to compile code. How to test code. How to “find” stuff. How to make the IDE serve you, and not you serving it.&lt;/p&gt;
&lt;p&gt;You probably won’t learn all the hot keys. That’s okay. You’ll probably be less efficient than you’d like. Again, that’s okay. The point is to learn. To grow. To expand your knowledge.&lt;/p&gt;
&lt;p&gt;Because when we practice learning, we become better at learning. And when it’s against something that truly challenges us, then the experience can a stronger effect on us.&lt;/p&gt;
&lt;p&gt;Leave me a comment and tell me you’re going to commit. You’re going to try some new IDEs!&lt;/p&gt;
&lt;p&gt;Are you ready for 2025? It’s here. It’s ready to throw you all kinds of curve balls.&lt;/p&gt;
&lt;p&gt;Maybe you don’t have everything together. Maybe you don’t know all the answers. I’m not asking for that.&lt;/p&gt;
&lt;p&gt;All I want you to do is be ready to GROW this year! Be ready to EMBRACE new things. Be ready to truly become a PRO CODER!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I chat with an old friend about some of the amazing/shocking AI trends that are hitting us from all directions!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_iAlnkT-XrHbhx8nLvtYdOg.CI83ZX7a.jpeg"/></item><item><title>Making rookie mistakes</title><link>https://www.procoder.io/articles/2024/2024-12-27_making-rookie-mistakes-3a1da8b4ba06</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-12-27_making-rookie-mistakes-3a1da8b4ba06</guid><description>As a pro coder, it’s easy to make mistakes. Check out what I did WRONG. And why this was easily preventable.</description><pubDate>Fri, 27 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a pro coder, I made a terrible rookie mistake!&lt;/p&gt;
&lt;p&gt;It was really embarrassing.&lt;/p&gt;
&lt;p&gt;Just spent three days tracking down why my website wouldn’t let me enter edit mode… but my wife’s would!&lt;/p&gt;
&lt;p&gt;Turns out that on Cloudflare I had enabled “Rocket Loader”.&lt;/p&gt;
&lt;p&gt;I use Cloudflare because it has superior DNS management and lots of other great features.&lt;/p&gt;
&lt;p&gt;I assumed that Rocket Loader was another great tool to deploy.&lt;/p&gt;
&lt;p&gt;Turns out it was kind of like going into your Gentoo Linux machine and rebuilding everything with maximum GCC optimization switched on.&lt;/p&gt;
&lt;p&gt;Might speed things up. But probably won’t work.&lt;/p&gt;
&lt;p&gt;The webpage when I’d click “Edit” (i used Divi on all my websites), the edit spinner would pop up…&lt;/p&gt;
&lt;p&gt;…and just keep spinning.&lt;/p&gt;
&lt;p&gt;I disabled almost every plug-in I had on my website trying to figure out what had broken things.&lt;/p&gt;
&lt;p&gt;Speaking of breaking things and putting them back together, check out the sponsor of this article…&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*JNyhv2y6As6tZ3wEG-501A.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;12 Rules For Pro Coders is chock full of painfully learned lessonsI smart person learns from their mistakes. A WISE person learns from OTHER people’s mistakes. &lt;a href=&quot;https://www.procoder.io/step/12-rules-page/&quot;&gt;Grab &lt;em&gt;&lt;strong&gt;12 Rules For Pro Coders&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; and learn from my mistakes with actionable advice to accelerate your career!&lt;/p&gt;
&lt;p&gt;Now back to your regularly scheduled article!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I had even switched to “development mode” on Cloudflare!&lt;/p&gt;
&lt;p&gt;Turns out that knob doesn’t disable EVERYTHING.&lt;/p&gt;
&lt;p&gt;Truth is…I went too fast.&lt;/p&gt;
&lt;p&gt;I kicked myself knowing I had just made this newbie mistake. I shook my head, upset with myself.&lt;/p&gt;
&lt;p&gt;I had switched on Rocket Loader along with a few other optimizations without verifying it worked let alone sped things up.&lt;/p&gt;
&lt;p&gt;And that was my fault.&lt;/p&gt;
&lt;p&gt;As a pro coder we just always slow down and do things one step at a time.&lt;/p&gt;
&lt;p&gt;Test one thing and verify it works.&lt;/p&gt;
&lt;p&gt;Then test another thing. And another. And another.&lt;/p&gt;
&lt;p&gt;Being a pro coder means taking your time and doing it correctly.&lt;/p&gt;
&lt;p&gt;A series of correctly done steps and people that don’t code will thing your some kind if frickin’ genius. But you’re just moving things forward one step at a time.&lt;/p&gt;
&lt;p&gt;It’s easy to say but this process requires discipline and commitment. Don’t make the mistake I made.&lt;/p&gt;
&lt;p&gt;Test your changes. One by one.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I explain what the most IMPORTANT tool a pro coder can have!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_xI1AopY1TeWfWCdgXcWK0Q.CcZ3tk0K.jpeg"/></item><item><title>I hate New Year’s Resolutions…</title><link>https://www.procoder.io/articles/2024/2024-12-23_i-hate-new-year-s-resolutions--d33fffaf8e99</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-12-23_i-hate-new-year-s-resolutions--d33fffaf8e99</guid><description>If something is good enough to dedicate your time and energy, why wait until New Year’s Day?</description><pubDate>Mon, 23 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…and so should you!&lt;/p&gt;
&lt;p&gt;If something is good enough to dedicate your time and energy, why wait until New Year’s Day?&lt;/p&gt;
&lt;p&gt;For example, I saw this posted on Reddit the other day…&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*adKjCN4ReJj1XdEY6v-VYw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;The OP is wondering if doubling down on SQL would be a good move for their budding career. (I’m assuming
its embedded in a new-found love for SQL, a love I can certainly appreciate.)&lt;/p&gt;
&lt;p&gt;To which my answer is an emphatic YES!&lt;/p&gt;
&lt;p&gt;This person doesn’t need to wait until January 1st. They can start now!&lt;/p&gt;
&lt;p&gt;What is something you either started doing this year…or delved into due to some task pushed onto your plate…and you find a sudden satisfaction doing it? (Share
in the comments below!)&lt;/p&gt;
&lt;p&gt;Whatever it is, don’t wait until 2025 to start doing MOAH!&lt;/p&gt;
&lt;p&gt;And if I can nudge you a tad, consider making it a topic you start posting about on a weekly basis. Perhaps LinkedIn. Perhaps X. (Perhaps Medium??) Whatever is
your favorite platform, I implore you to SHARE the fun you’re having by writing what you’re doing and why you’re doing it.&lt;/p&gt;
&lt;p&gt;This is what is the gold that is social media. People sharing things they love. Not meaningless clickbait engagement tricks.&lt;/p&gt;
&lt;h3 id=&quot;but-nothing-is-drawing-my-attention-thisyear&quot;&gt;But NOTHING is drawing my attention this year!&lt;/h3&gt;
&lt;p&gt;I get it.&lt;/p&gt;
&lt;p&gt;Maybe this past year (and perhaps the year before it) you drudged through some mind-numbingly boring stuff. Or perhaps you had to suffer working with a stack
that wasn’t &lt;em&gt;shall we say&lt;/em&gt; your cup of tea.&lt;/p&gt;
&lt;p&gt;I’m not telling you to quit your job. But at least pause, perhaps use this holiday season to spend a couple hours, and review what you liked and didn’t like
about this past year.&lt;/p&gt;
&lt;p&gt;Spend some time and contemplate where things are going in your life. If it helps, consider creating a Google Document and making a 2-column table. List PROs on
one side and CONs on the other.&lt;/p&gt;
&lt;p&gt;Sometimes, that’s all it takes.&lt;/p&gt;
&lt;p&gt;Writing down what you’ve done can make things clear where you want to go. From there, you can start to think about how to make the changes you want to make.&lt;/p&gt;
&lt;p&gt;Is that possible at your own shop? Or is your future somewhere else?&lt;/p&gt;
&lt;p&gt;Like I said, I’m not telling you to quite today. I’m just encouraging you to take stock of your current situation and formulate a plan. After all, this is your
career.&lt;/p&gt;
&lt;p&gt;Maybe the title of this article IS a little clickbaity. But the idea is sound. Don’t wait until the New Year is here. Start right now deciding what the future
of your career will be.&lt;/p&gt;
&lt;p&gt;Because no one else is doing that.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I explain why
the tech stack you pick doesn’t really matter. And if you want to get content FIRST, then I encourage you &lt;a href=&quot;https://www.youtube.com/@ProCoderIO/join&quot;&gt;
to become a member&lt;/a&gt;!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_yeq5RuvRSDx1wH_srfjtHA.CE0oZAQD.jpeg"/></item><item><title>What are you thankful for?</title><link>https://www.procoder.io/articles/2024/2024-12-09_what-are-you-thankful-for--b6f956cbdfa7</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-12-09_what-are-you-thankful-for--b6f956cbdfa7</guid><description>It was one year ago at the beginning of December that I felt a really BIG test thrust upon me.</description><pubDate>Mon, 09 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It was one year ago at the beginning of December that I felt a really BIG test thrust upon me.&lt;/p&gt;
&lt;p&gt;I had been let go maybe a week or two earlier in the Broadcom acquisition of VMware and told I was no longer a part of the Spring team.&lt;/p&gt;
&lt;p&gt;This wasn’t just a job…it was one of the best pieces of tech I had EVER worked on!&lt;/p&gt;
&lt;p&gt;But that was over. And something that I was suddenly in the midst of was the fact that two of my kids had been picked to be part of the bible quizzing team
going to the regional competition in St. Louis!&lt;/p&gt;
&lt;p&gt;So I told myself that whatever angst I had, I would put it on the shelf and instead focus on spending time with them. After all, no one else was calling me up.
No tickets. No pull requests to review. And I had keenly decided to NOT do any podcasting of livestreaming until the severance check (of which I qualified for
the MAX, which combined with my accelerated equity option, gave me about 7 1/2 months of salary) was in my hands. I didn’t want to hand the incoming company any
REASON to withhold that check. I doubted they would, but way put yourself into a position of playing defense?&lt;/p&gt;
&lt;p&gt;So I loaded my two kids into the van, and off we went for a 5-hour drive.&lt;/p&gt;
&lt;p&gt;And something happened on that trip.&lt;/p&gt;
&lt;p&gt;Another family from the district, their dad was in St. Louis. Someone had asked me what had happened, and in mentioning Broadcom, his ears pricked up. So we
started chatting over breakfast.&lt;/p&gt;
&lt;p&gt;I came to discover that this guy had risen up through the ranks of network engineering and rigging up various systems. Eventually, he reached a point where we
was principal technologist running a non-profit in the Greater Nashville Area.&lt;/p&gt;
&lt;p&gt;And so I just shared my story. What I knew and had done.&lt;/p&gt;
&lt;p&gt;I wasn’t interviewing, per se, but I needed to remember how to have a conversation from this perspective. It had been awhile since I had gone “job shopping” (
first was after college, second was to join the Spring team). This was my third EVER interviewing I’d be doing, so I figured I had to warm up to speaking techno
lingo while ALSO being willing to share tid bits of my experience.&lt;/p&gt;
&lt;p&gt;(BTW, if you ARE needing to interview to find a new position, I made this video FOR YOU!)&lt;/p&gt;
&lt;div class=&quot;relative w-full aspect-video mb-6&quot;&gt;
  &lt;iframe src=&quot;https://www.youtube.com/embed/YdvPRVLvfEU?si=mrKFRlc_w4EN514X&quot; title=&quot;YouTube video player&quot; class=&quot;absolute top-0 left-0 w-full h-full&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;
  &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;And no, this fine gentleman with whom we traded war stories was not my future.&lt;/p&gt;
&lt;p&gt;But a couple weeks after that, someone ELSE…WAS.&lt;/p&gt;
&lt;p&gt;Josh Long had introduced me to Doug Weatherbee, and despite insisting I wasn’t going to be rushing my resume into the hands of recruiters during the Xmas
season (what recruiter is focused on their job amidst sleigh bells in the snow?!?), Doug and I ended up having a video chat.&lt;/p&gt;
&lt;p&gt;It easily ran over an hour. And we easily shifted into shorthand discussing the industry, Spring, and more amazingly…CockroachDB.&lt;/p&gt;
&lt;p&gt;Fast forward, a year, and here I am. Reminiscing about those early conversations.&lt;/p&gt;
&lt;p&gt;I didn’t know what was going to happen. And I have friends and past colleagues going through some of the struggles. My heart goes out to them.&lt;/p&gt;
&lt;p&gt;But I am incredibly blessed this Christmas season to have found a new home, to have written some really amazing content, and to have delivered it to a customer.
All in this year.&lt;/p&gt;
&lt;p&gt;I call that a great start. And I hope the best for you as well.&lt;/p&gt;
&lt;p&gt;Merry Christmas!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you are a pro coder, or are planning to become one, then please subscribe to this newsletter. And if you want to get content FIRST, then I encourage you
&lt;a href=&quot;https://www.youtube.com/@ProCoderIO/join&quot;&gt;to become a member&lt;/a&gt;!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="457" medium="image" url="https://www.procoder.io//_astro/1_SM4O2TESe2oY4LHg1mTw2Q.CC1c6rL7.jpeg"/></item><item><title>Do you code for profit…or for fun?</title><link>https://www.procoder.io/articles/2024/2024-07-08_do-you-code-for-profit-or-for-fun--f997a9b9857d</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-07-08_do-you-code-for-profit-or-for-fun--f997a9b9857d</guid><description>I don’t know how first came up with this attention-farming post, but have heard the question posted…</description><pubDate>Mon, 08 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I don’t know how first came up with this attention-farming post, but have heard the question posted…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do you write code for fun or for money?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is absurd.&lt;/p&gt;
&lt;p&gt;For starters, it’s a false dichotomy implying you can only be one or the other. You either code for money OR you code for fun. This is an arguing strategy I see
far too often. The author is angling to get you to talk yourself into agreeing with them on some topic. Hence, they concoct the “opposite” of what is the
“right” answer, and then proceed, probably with several strawman arguments, about how the “opposite” is wrong and what they started with is “right”.&lt;/p&gt;
&lt;p&gt;And I’m assuming you KNOW this.&lt;/p&gt;
&lt;p&gt;We ALL know this. We can see it from a mile away.&lt;/p&gt;
&lt;p&gt;The real nut buried in this particular instance, is the idea that somehow, someway, making money is evil and wrong. And that if you are attempting to make money
as a pro coder, then you are “impure” in some way.&lt;/p&gt;
&lt;p&gt;I first saw this called out in the fiction. The author Derek Murphy in his work BOOK CRAFT mentions that too many authors have been told that “art” can only
TRULY be art…when it’s not linked to revenue and profit.&lt;/p&gt;
&lt;p&gt;And he summarily smashes the idea to pieces. It’s possible to have true, enjoyable art that you love. And to also earn a living doing it. In fact, the sooner
you break yourself of that “starving artist” lie, the better off you’ll be. It will energize you and empower to REALLY make art. Instead of loathing it.&lt;/p&gt;
&lt;p&gt;So why is software development any different?&lt;/p&gt;
&lt;p&gt;There is a sense of “art” to that as well. I didn’t realize this until I began to observe HOW MANY members of the Spring team are also artists. Rod Johnson,
Mark Fisher, Dave Turanski, Ben Corrie, Jeremy Grelle, myself (I play the guitar), and probably others that I’m not even aware of.&lt;/p&gt;
&lt;p&gt;I once mentioned this, and someone on the team signaled that a software developer WHO ALSO embraces the artistic side the brain, can have a more holistic
perspective on things.&lt;/p&gt;
&lt;p&gt;And watching Rod Johnson play Chopin on the piano at a Spring Experience conference back in the day is truly inspiring.&lt;/p&gt;
&lt;p&gt;It’s possible to engage in the art of software design, to work within the corridor of what a language demands while building something of beauty that serves
multiple people.&lt;/p&gt;
&lt;p&gt;And it’s possible to let people pay you handsomely for it.&lt;/p&gt;
&lt;p&gt;If someone is hinting that accepting money is somehow wrong, then ask them if they perform their own work efforts free of charge. It’s okay to be paid for
software, to be paid for TRAINING on that software, and it’s okay to be paid for other ancillary things surrounding the software.&lt;/p&gt;
&lt;p&gt;And none of that precludes you from truly enjoying the process, from beginning to end, of PRODUCING that software.&lt;/p&gt;
&lt;p&gt;In fact, this realization in myself is what has made it EASIER for me to pay others for software as well.&lt;/p&gt;
&lt;p&gt;I once learned that Rod Johnson, in his attempts to sell Spring, had discovered that software developers tend to be cheap and stingy. He identified that you
have to sell it to someone higher up. Fist bump that one. We do tend to be cheapskates.&lt;/p&gt;
&lt;p&gt;I took me great effort to FINALLY pull the trigger on buying Final Cut Pro, the software I used to edit videos. I was sweating over shelling out $300.&lt;/p&gt;
&lt;p&gt;Alas, it has become one of my favorite purchases ever. I use it all the time. It is powerful and effective. And I’ve learned to drive it in many scenarios. It’s
okay to pay for software.&lt;/p&gt;
&lt;p&gt;And so much so, that in their most recent release, where several key features + some rough bugs were ironed out, I DM’d a college friend of mine to thank him
for that release.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*w-XRPdXGEA1XaF_OV6ye4w.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t
wait then check out this video and learn why investing in yourself may be the most important thing you do!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;</content:encoded><media:content type="image/png" width="776" height="350" medium="image" url="https://www.procoder.io//_astro/1_w-XRPdXGEA1XaF_OV6ye4w.C2LeyKsh.png"/></item><item><title>Something NONE of us need!</title><link>https://www.procoder.io/articles/2024/2024-06-26_something-none-of-us-need--e2f6a8d80d38</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-06-26_something-none-of-us-need--e2f6a8d80d38</guid><description>There is a phenomena out there you may have run into, in one form or another…</description><pubDate>Wed, 26 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is a phenomena out there you may have run into, in one form or another…&lt;/p&gt;
&lt;h3 id=&quot;the-arrivalsyndrome&quot;&gt;The Arrival Syndrome&lt;/h3&gt;
&lt;p&gt;You’ve probably seen it in others. It’s scarier to see it manifest in yourself.&lt;/p&gt;
&lt;p&gt;It’s basically a state of mind where you (or someone else) has a feeling of, “I’ve arrived!” It implies that you learned what had to be learned, you applied it, and now all is done and well.&lt;/p&gt;
&lt;p&gt;So what’s wrong with that?&lt;/p&gt;
&lt;p&gt;Simply put, it suggests a state of mind where you don’t have to learn any more. There is no more growing to be done. Almost as if everything is smooth sailing.&lt;/p&gt;
&lt;p&gt;And that’s the problem.&lt;/p&gt;
&lt;p&gt;There is a saying I first heard of in German:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Um ein Meister zu werden, muss man immer ein Schüler bleiben&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Translated, it reads, “To become a master, one must always remain a student.” We must continue to grow and to learn. When we stop learning, then we began to atrophy.&lt;/p&gt;
&lt;p&gt;As a keen example, I myself have studied and use SQL for years. I once had a textbook on ORACLE/SQL from college that I reached for all the time when I started working on a contract…&lt;em&gt;in 2001&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;Way back in 2001, I had no clue what a &lt;strong&gt;LEFT OUTER JOIN&lt;/strong&gt; was. In case you didn’t know, that’s when the values on the left-hand side of the query are required, but the values on the right-hand side are optional. Suffice it to say, LEFT OUTER JOINs are used ALL THE TIME, so there was no NOT learning this concept.&lt;/p&gt;
&lt;p&gt;By the time I left that contract to join the Spring team in 2010, LEFT OUTER JOINs were burned into my brain amidst other SQL and relational database concepts.&lt;/p&gt;
&lt;p&gt;Another 14 years passes by, and I find myself as a technical content engineer with Cockroach Labs where I’m helping to fashion content to train our paying customers. This includes some of the most advanced SQL. Given CockroachDB’s distributed highly available nature, we are having to coach them on various SQL practices.&lt;/p&gt;
&lt;p&gt;It’s in early 2024 that I first see mention of CTEs or Common Table Expressions.&lt;/p&gt;
&lt;p&gt;Hmm. Never heard of that. Okay, I HAD heard of that, the previous year, when Hibernate 6 added CTEs to Hibernate Query Language and I modded Spring Data JPA’s query parser to handle them.&lt;/p&gt;
&lt;p&gt;Time to study up on this technology…&lt;/p&gt;
&lt;p&gt;…that became a part of SQL in 2001.&lt;/p&gt;
&lt;p&gt;Gulp.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*cwlCIgH64qAKe-KA.jpg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Way back when I didn’t know LEFT OUTER JOINs, CTEs had entered the arena. I knew nothing about them. It’s kind of humbling to get kicked in the gut like that after working in this industry for 27 years.&lt;/p&gt;
&lt;p&gt;It’s vital that no matter how seasoned we become, no matter how much expertise we accrue, that we ALWAYS remain open to continued learning and growth.&lt;/p&gt;
&lt;p&gt;The hard thing is, that requires a certain level of humility. Especially if the source of further growth comes from the next generation of pro coders.&lt;/p&gt;
&lt;p&gt;But if you include learning as a key thing of being a pro coder, and make sure to not skip over present and future opportunies to keep learning, it will serve you well.&lt;/p&gt;
&lt;p&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where it turns out, the tech stack you pick DOESN’T REALLY MATTER!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/0_cwlCIgH64qAKe-KA.D_JveNvZ.jpg"/></item><item><title>Want to hear another story?</title><link>https://www.procoder.io/articles/2024/2024-04-23_want-to-hear-another-story--1d55ea1fa224</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-04-23_want-to-hear-another-story--1d55ea1fa224</guid><description>We all are given special gifts. Often time these gifts can sustain us, help us provide for our families and for others.</description><pubDate>Tue, 23 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We all are given special gifts. Often time these gifts can sustain us, help us provide for our families and for others.&lt;/p&gt;
&lt;p&gt;And sometimes, those gifts can serve a much deeper purpose.&lt;/p&gt;
&lt;p&gt;This past weekend, I went down to visit my parents, who are now in their late 80s. I brought half of my YouTube studio gear with me. Cameras. Microphones. Tripods. Lights.&lt;/p&gt;
&lt;p&gt;And I let my mother tell her story.&lt;/p&gt;
&lt;p&gt;She has amazing memories back to before WWII. Times she spent with her grandparents, who were married in a state before that state joined the Union.&lt;/p&gt;
&lt;p&gt;All my skills I’ve learned over the past five years at shooting and producing videos for you were now able to quickly and efficiently gather something greater than myself.&lt;/p&gt;
&lt;p&gt;A recent reader of my latest book heralded my comments in the book that as SW engineers we carry certain duties to the profession. While I appreciate that reader’s words, this weekend I felt that I (we) carry an even higher duty to capture the past and preserve it for the future.&lt;/p&gt;
&lt;p&gt;I have just transferred all the gathered video and stills onto my RAID array and am now importing it into a Final Cut Pro project where I can splice it together.&lt;/p&gt;
&lt;p&gt;My father, since before I was born, has shot Super 8 films and taken literally thousands of photos. And I feel that I have now taken up a new mantle to carry on this duty to capture such memories in today’s day and age.&lt;/p&gt;
&lt;p&gt;And as my parents have invested much in me to bring me to where I am today, I intend to invest hopefully as much into my own children, so that someday they can carry the torch forward.&lt;/p&gt;
&lt;p&gt;This is what we all carry in some shape or form. A duty to serve those around us with the talents and gifts granted to us.&lt;/p&gt;
&lt;p&gt;It may start with your job and your daily tasks. But don’t hesitate to help a friend, a family member, or a complete stranger when the opportunity presents itself.&lt;/p&gt;
&lt;p&gt;I also had the chance to chat this weekend with a family friend I’ve known since I was quite young. He’s also a retired professor and someone I worked with during grad school. He’s also a pro coder.&lt;/p&gt;
&lt;p&gt;He shaped much of whom I am today career-wise. He even got me in amateur radio.&lt;/p&gt;
&lt;p&gt;When I saw him yesterday, one thing he said stuck with me. He said, “I’ve got a story for you. All I have now are stories.”&lt;/p&gt;
&lt;p&gt;He said those words in a self-deprecating manner. But I realized in that moment, that if I were to someday reach his age, I too hoped that I would be filled with stories. Because stories are what really matter.&lt;/p&gt;
&lt;p&gt;Our interactions with each other are what weave all of humanity together. That’s what is most important above all. Stories.&lt;/p&gt;
&lt;p&gt;Do you have any stories? And what are you doing to make more of them?&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_6OJsRCH-jJMB3BI6LE_j3Q.PzOhydIx.jpeg"/></item><item><title>Returning to first principles…</title><link>https://www.procoder.io/articles/2024/2024-04-15_returning-to-first-principles--414fb137aaed</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-04-15_returning-to-first-principles--414fb137aaed</guid><description>Over the past few weeks, I’ve heard more than one person, from very different places, mention “getting back to first principles.”</description><pubDate>Mon, 15 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over the past few weeks, I’ve heard more than one person, from very different places, mention “getting back to first principles.”&lt;/p&gt;
&lt;p&gt;First principles are axioms that we pin stuff to. Another way is to look at what your values are, and what flows from that.&lt;/p&gt;
&lt;p&gt;As a pro coder, it’s easy to get sucked into processes, tools, concepts, and philosophies written by others. I mean come on, we can’t build this stuff &lt;em&gt;all by ourselves&lt;/em&gt;. We need help! We need IDEs, compilers, frameworks, books, strategies, ticketing, tools, and gobs of other stuff to do this. So yes, we need others to help or nothing is happening.&lt;/p&gt;
&lt;p&gt;But it’s also good, every now and then, to double check what we’re doing and compare it against our own values. One of the things I’ve reexamined multiple times is &lt;strong&gt;continuous integration&lt;/strong&gt;. If you caught the latest episode of the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLLAi7xIKHkiuV6njcma_JAtt-a2x80MaO&quot;&gt;&lt;em&gt;&lt;strong&gt;Pro Coder Show&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;, I went into detail about how I kind of sort of INVENTED continuous integration as one of my first assignments in my career.&lt;/p&gt;
&lt;p&gt;But not really.&lt;/p&gt;
&lt;p&gt;Let me put it like this…I spotted the value of building our system on a recurring nightly cycle in order to detect when errors would creep into the system. And that was useful. VERY useful.&lt;/p&gt;
&lt;p&gt;And that fundamental idea has become a first principle to me.&lt;/p&gt;
&lt;p&gt;Having joined the Spring team in 2010, I later became a part of its Spring Data department in 2017 and within a year’s time, took over as the manager of all their CI pipelines. I began migrating stuff off of our UX-heavy system (Bamboo) in favor of a source control-managed approach. I had already worked with Drone, Travis, and CircleCI and had seen I’d seen the pluses and minuses of various systems in various environments. I later shepherded Spring Data into using a Docker-oriented CI tool called Concourse. It had its own pros and cons, the biggest pro being its “every step inside a container” tactic, which I LOVED.&lt;/p&gt;
&lt;p&gt;Simply put, containers provide the perfect tool to ensure the exact environment you wish a step to be executed inside is always there.&lt;/p&gt;
&lt;p&gt;Nevertheless, it did NOT support another key thing I needed, &lt;strong&gt;branch builds&lt;/strong&gt;. So after much analysis, I eventually migrated us to good ole’ Jenkins.&lt;/p&gt;
&lt;p&gt;Suffice it to say, every time I dug in to solve another problem with a given CI solution, I constantly checked my assumptions and my values in that context and sought out the most critical axioms. And that is how I was able to set aside my accumulated distaste for Jenkins…and actually go back to it! (A biggie being that Jenkins now supported a source control-managed solution, allowing me to avoid its horrendous UX-based configuration!)&lt;/p&gt;
&lt;p&gt;BTW something to take note of, is that no implementation of your values is ever perfect. Instead, you must understand your own thoughts and beliefs such that you can weigh any given tool against another and decide which is better. But be ready to accept that nothing will be EXACTLY what you seek.&lt;/p&gt;
&lt;p&gt;The same goes for IDEs. I have seen lots of them. Years ago, I spotted certain aspects of IntelliJ IDEA that best fit my need for tools. What is your favorite tool? I spoke to one person that can’t give up VS Code.&lt;/p&gt;
&lt;p&gt;I asked “why?”&lt;/p&gt;
&lt;p&gt;“Because, I have all the hot keys wired into my fingertips!”&lt;/p&gt;
&lt;p&gt;You may think that I’d either laugh or scoff at such an assertion given my adoration for IntelliJ IDEA.&lt;/p&gt;
&lt;p&gt;Nope.&lt;/p&gt;
&lt;p&gt;Picking a tool because of deep-seated familiarity is not bad reason. You know your tool. Inside and out. The current crop of modern IDEs generally support much of the same stuff, so if you can wield it with such intensity, no need to waste time moving off of it!&lt;/p&gt;
&lt;p&gt;The point is when assessing tools, processes, and ideas, to try and spot the handful of characteristics that are most important TO YOU. Then…use them anytime you are evaluating something else.&lt;/p&gt;
&lt;p&gt;What are YOUR 1st principles?&lt;/p&gt;
&lt;p&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out episode where I mention how I accidentally invented continuous integration!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;</content:encoded><media:content type="image/png" width="1408" height="768" medium="image" url="https://www.procoder.io//_astro/default-hero.D-v8eEMA.jpg"/></item><item><title>Most over engineered solution EVER…</title><link>https://www.procoder.io/articles/2024/2024-04-04_most-over-engineered-solution-ever--28236a4c34aa</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-04-04_most-over-engineered-solution-ever--28236a4c34aa</guid><description>I recently saw this “ah hem” challenge posted on X:</description><pubDate>Thu, 04 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently saw this “ah hem” challenge posted on X:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What is the most overengineered library/tool/framework/environment that you ever used at work? —Mario Fusco&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I looked no further than my own coding experience to fine an answer&lt;/p&gt;
&lt;p&gt;Early in my career I had read GoF Design Patterns.&lt;/p&gt;
&lt;p&gt;It was read like magic! So naturally I had to use those patterns. I was that impressed by those incarnations of OOP.&lt;/p&gt;
&lt;p&gt;So in my next project, a small one with few fellow teammates, I began using that.&lt;/p&gt;
&lt;p&gt;All of them.&lt;/p&gt;
&lt;p&gt;My solution was probably triple what it really needed to be.&lt;/p&gt;
&lt;p&gt;And there was really no one there to tell me that what I’d built was ridiculous.&lt;/p&gt;
&lt;p&gt;Later on when the anti-pattern movement arose and book after was published, I realized what a foolish decision that had been.&lt;/p&gt;
&lt;p&gt;I have since become a bigger fan of “The Poutsma Principle”.&lt;/p&gt;
&lt;p&gt;A tongue in cheek idea, it says that if Arjen Poutsma (creator of Spring @MVC and RestTemplate among others the things) doesn’t understand what you wrote, you’re probably wrong.&lt;/p&gt;
&lt;p&gt;A more serious phrasing is to not do “cute” stuff but instead strive to make things as simple and straight forward as possible. And if you can’t find a less “hacky“ solution, perhaps you need to hold off on your supposed “solution”.&lt;/p&gt;
&lt;p&gt;Complex and hacky solutions only put additional maintenance on our own plate and demand further hacks and tricks to sustain.&lt;/p&gt;
&lt;p&gt;What about you? What’s the most over engineered thing you have done?&lt;/p&gt;
&lt;p&gt;If you’re a pro coder or plan to become one then stay tuned for my next article. But if you simply can’t wait then check out this video where I helped a fellow pro coder who fumbled an interview.&lt;/p&gt;
&lt;p&gt;-Greg&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="530" medium="image" url="https://www.procoder.io//_astro/1_6K_KvdB8l9WdsicoO97Iyg@2x.DMkdDQMQ.jpeg"/></item><item><title>Thank you, Spring!</title><link>https://www.procoder.io/articles/2024/2024-03-27_thank-you--spring--09adf0300ab6</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-03-27_thank-you--spring--09adf0300ab6</guid><description>14 years ago, a young coder with a wife and a baby girl, left his comfy, secure position and struck out to join the recently acquired…</description><pubDate>Wed, 27 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;14 years ago, a young coder with a wife and a baby girl, left his comfy, secure position and struck out to join the recently acquired Spring team. That someone was me.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*A1qDeVq1S4feOi6o.jpg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;em&gt;My daughter’s reaction when I told here I was joining the Spring team!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I had never worked on such an elite team. I had been used to writing functioning code and shipping it out to our users. Of course I’d had feedback on proposed solutions and seen my handiwork reviewed to see if it was correct. But I’d never submitted code that was then “polished”.&lt;/p&gt;
&lt;p&gt;I’d never done that before.&lt;/p&gt;
&lt;p&gt;But here I was working for a team that was serving literally millions while my previous system’s users clocked in at less than 1000.&lt;/p&gt;
&lt;p&gt;There was some awe being able to claim&lt;/p&gt;
&lt;p&gt;I was part of this fantastic team. But there a much bigger dose of panic I was trying hold at bay!&lt;/p&gt;
&lt;p&gt;And so I did my best to just listen to the feedback I received.&lt;/p&gt;
&lt;p&gt;The Spring team is somewhat famous for “&lt;strong&gt;juergenization&lt;/strong&gt;”. Some call it polishing. But that’s an oversimplification.&lt;/p&gt;
&lt;p&gt;You see, the idea is to polish your code such that Juergen Hoeller (Spring founder and present lead developer of the Spring Framework) would approve your changes. Invariably, he would make a slight tweak…or a veritable rewrite (assuming your patch qualified) and make your code appear as if it had been there the whole time.&lt;/p&gt;
&lt;p&gt;Over time, the more patches you submit, the more your work gets “polished”, it’s ultimately YOU that becomes &lt;strong&gt;juergenized&lt;/strong&gt;. (Maybe I should write a book about juergenization itself? Let me know in the comments what you think!)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Today’s sponsor…&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Coding isn’t just about algorithms. There’s more. A LOT more. CI, security, team communication, meetings, career tips, you name it.&lt;/p&gt;
&lt;p&gt;I wrote &lt;em&gt;&lt;strong&gt;12 Rules for Pro Coders&lt;/strong&gt;&lt;/em&gt; to give you actionable advice to accelerate your career. As a veteran pro coder, I want YOU to learn the same valuable lessons I did…but faster.&lt;/p&gt;
&lt;p&gt;This advice has been put to the test. In my own process of being cut in the acquisition, I have actually leaned into what I wrote in the midst of coming up to speed on my new endeavor over at Cockroach Labs. This book can help you too.&lt;/p&gt;
&lt;p&gt;So &lt;a href=&quot;https://12rules.io/&quot;&gt;grab your copy&lt;/a&gt; and learn what your university or boot camp didn’t have time to teach you!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*PU65olVx18K1RcIO.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;a href=&quot;https://12rules.io&quot;&gt;https://12rules.io&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;For several years I contributed not just tiny patches but instead whole features and new approaches to Spring HATEOAS under Oliver Drotbohm’s management. And I swear, not a single contribution was made without some form of juergenization. (Some called Ollie “mini Juergen”!)&lt;/p&gt;
&lt;p&gt;I had constant feedback on style, structure, format, and purpose of every piece of code that I wrote.&lt;/p&gt;
&lt;p&gt;But the Spring team doesn’t just polish code for fun…or sadistic pleasure. There is a reason.&lt;/p&gt;
&lt;p&gt;Just like there is a reason that they often say “no” more often than “yes” to new ideas and new patches.&lt;/p&gt;
&lt;p&gt;Spring is a slate of portfolio projects used around the globe by literally millions. For something to be absorbed into a Spring project means taking on a long window of maintenance and support. Because Spring doesn’t break users except in very strict and controlled ways.&lt;/p&gt;
&lt;p&gt;The Spring team wants the upgrade experience to be smooth and easy. Patch releases should fix bugs…and just that. Minor releases may allow new features, but shouldn’t break existing behavior.&lt;/p&gt;
&lt;p&gt;When I listened in on Juergen at a SpringOne conference birds-of-a-feather conversation, and heard him talking about Spring being “JDK 8 ready”, I was befuddled at what he meant!&lt;/p&gt;
&lt;p&gt;So I did some digging. And found out that while it was baselined on JDK 6 at the time, it was being compiled using JDK 8 and had chunks of code that would activate to support various JDK 8 features like Optional return types for Spring MVC controller methods.&lt;/p&gt;
&lt;p&gt;I didn’t know Java could even do such a thing!&lt;/p&gt;
&lt;p&gt;I spotted places in Spring Data JPA where two solutions existed, based upon whether or not the JPA provider was on JPA 2.1+. What?!?&lt;/p&gt;
&lt;p&gt;The more I learned and grew on the Spring team, the more I learned the levels of effort this team spent on this type of support for end users. A lesser toolkit might have simply jumped to the newer version of a given standard and called it a day.&lt;/p&gt;
&lt;p&gt;But not Spring.&lt;/p&gt;
&lt;p&gt;Part of this was borne of the fact that Spring used to be the underdog. They had to offer an overwhelming reason for people to turn away from “standard enterprise Java.”&lt;/p&gt;
&lt;p&gt;And so they focused on user success. They focused on making it easy for developers to solve problems. After all, Rod’s vision for Spring was to reduce Java complexity and offer a better way forward.&lt;/p&gt;
&lt;p&gt;And having such an ethos ingrained in me over the part 14 years has truly &lt;strong&gt;juergenized&lt;/strong&gt; me.&lt;/p&gt;
&lt;p&gt;When I joined Cockroach Labs and dove into all the content we are building for our customers, I began spotting places where we could improve things. I saw opportunities where I could apply lessons I’d already learned.&lt;/p&gt;
&lt;p&gt;I saw the chance to begin &lt;strong&gt;juergenizing&lt;/strong&gt; things here and affording our customers and community a better experience. And this is where all those years of continuous feedback to be now be turned to serve this community.&lt;/p&gt;
&lt;p&gt;Thank you Spring team for honing my skills and desire to serve. Thank you for &lt;strong&gt;juergenizing&lt;/strong&gt; me.&lt;/p&gt;
&lt;p&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. But if you simply can’t wait, then check out the video below where I talk about exactly what you must do to get promoted or received a merit increase!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="480" height="640" medium="image" url="https://www.procoder.io//_astro/0_A1qDeVq1S4feOi6o.B7A84R2K.jpg"/></item><item><title>I survived the first three weeks…</title><link>https://www.procoder.io/articles/2024/2024-03-12_i-survived-the-first-three-weeks--51063101681e</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-03-12_i-survived-the-first-three-weeks--51063101681e</guid><description>I then went on with suggestions about the first week, first month, six months, and a year.</description><pubDate>Tue, 12 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;…and you can too!&lt;/p&gt;
&lt;p&gt;If you aren’t aware, last year while writing the manuscript for &lt;em&gt;&lt;strong&gt;12 Rules For Pro Coders&lt;/strong&gt;&lt;/em&gt;, I
penciled down tips on what to do on your first day a a pro coder at a new position.&lt;/p&gt;
&lt;p&gt;I then went on with suggestions about the first week, first month, six months, and a year.&lt;/p&gt;
&lt;p&gt;And then Broadcom decided to lay me off.&lt;/p&gt;
&lt;p&gt;After securing a new position and starting last month, I felt like everything I had written down in that chapter of my book was being put to the test.&lt;/p&gt;
&lt;p&gt;To catch you up, here are some key tips if you find yourself in new position.&lt;/p&gt;
&lt;h3 id=&quot;1-firstday&quot;&gt;1. First Day&lt;/h3&gt;
&lt;p&gt;On your first day, you should focus on getting hooked into your company’s email, instant messenger (Slack, etc.), and other systems.&lt;/p&gt;
&lt;p&gt;Focus on filling out any paperwork they send to you. Whatever they give you, whether it’s a meeting invite, a video to watch, or a something to read, focus on
completing it.&lt;/p&gt;
&lt;p&gt;No one will be asking you to write software on Day 1.&lt;/p&gt;
&lt;p&gt;Above all, listen. Your immediate manager will probably do most of the talking. Just take notes. No one is expecting you to memorize anything.&lt;/p&gt;
&lt;p&gt;Start drinking from the firehouse…and while it may be a little crazy, enjoy it.&lt;/p&gt;
&lt;h3 id=&quot;2-firstweek&quot;&gt;2. First week&lt;/h3&gt;
&lt;p&gt;For starters, do you have a work machine yet? That’s pretty important, right?&lt;/p&gt;
&lt;p&gt;If they haven’t gotten one to you, then either reach out to your manager, or perhaps they have you linked up the system administrator. Someone should be
facilitating getting you set up like this.&lt;/p&gt;
&lt;p&gt;Assuming you DO have a work machine, have you grabbed a copy of the repository you are going to be working on? I suggestion you simply find time and start
reading the code. Or the build files. Perhaps they have a Jenkinsfile spelling out their pipelines.&lt;/p&gt;
&lt;p&gt;Start trying to drink in the information. You’ll have to get warmed on it sooner or later.&lt;/p&gt;
&lt;p&gt;At Cockroach Labs, I have been assigned a “roachmate”, someone that meets with me once-a-week. On my first meeting, this person walked me through the high-level
fundamentals on how CockroachDB works, and that helped massively.&lt;/p&gt;
&lt;p&gt;Do you have a partner to check in with?&lt;/p&gt;
&lt;p&gt;To top things off, my manager has a “Welcome” Google Doc with a stack of things to start working through. This might be a good time for you to do the same.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Today’s sponsor…&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Coding isn’t just about algorithms. There’s more. A LOT more. CI, security, team communication, meetings, career tips, you name it.&lt;/p&gt;
&lt;p&gt;I wrote &lt;em&gt;&lt;strong&gt;12 Rules for Pro Coders&lt;/strong&gt;&lt;/em&gt; to give you actionable advice to accelerate your career. As a veteran pro coder, I want YOU to learn the same valuable
lessons I did…but faster.&lt;/p&gt;
&lt;p&gt;This advice has been put to the test. In my own process of being cut in the acquisition, I have actually leaned into what I wrote in the midst of coming up to
speed on my new endeavor over at Cockroach Labs. This book can help you too.&lt;/p&gt;
&lt;p&gt;So &lt;a href=&quot;https://12rules.io&quot;&gt;grab your copy&lt;/a&gt; and learn what your university or boot camp didn’t have time to teach you!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Reijomqwbzk050AJxkYuxA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;a href=&quot;https://12rules.io&quot;&gt;https://12rules.io&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3-firstmonth&quot;&gt;3. First month&lt;/h3&gt;
&lt;p&gt;I’m three weeks in to my new position, and so far, I’ve been able to effect some actual change. The team I’m on is responsible to writing all the educational
content, whether that’s for customers or the community.&lt;/p&gt;
&lt;p&gt;I spotted an area that would benefit from a readjustment of tools. I cloned the repository the slides were in and then dug in and learned how to build the
content. Next, I created a branch and applied my tentative tool change. Finally, I put together a short proposal and pinged them on Slack to ask about
scheduling a meeting.&lt;/p&gt;
&lt;p&gt;At the same time, I’ve dialed into a few reviews and given my $0.02. I had some tidbits to share, while at the same time, I was listening and paying attention
to how they create graphics, how they conduct reviews, and have been making note of what everyone’s skillsets are.&lt;/p&gt;
&lt;p&gt;At the same time, my manager and I have booked a couple meeting each week where we just talk for about an hour. In essence, he’s warming me up to where the
plans are, where the outlines are, and how that ties into their ticketing system.&lt;/p&gt;
&lt;p&gt;Basically, I’ve been learning the processes this team uses.&lt;/p&gt;
&lt;p&gt;I encourage you to do the same. You can always ask your manager if you can have a chat, whether its to learn something, or if you just have a question.&lt;/p&gt;
&lt;h3 id=&quot;4-first-sixmonths&quot;&gt;4. First six months&lt;/h3&gt;
&lt;p&gt;I’d like to comment on this one, but like I said, everything I wrote down is being put to the test.&lt;/p&gt;
&lt;p&gt;When my six-month mark at Cockroach Labs rolls around, I’ll share the results!&lt;/p&gt;
&lt;p&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. But if you simply can’t wait, then check out the video below where I show how
you CAN interview for a new position even in the midst of a struggling tech sector!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY
NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="419" medium="image" url="https://www.procoder.io//_astro/1_TiXx7V69DUhLgwpzf4P0cw.BjLcbTXk.jpeg"/></item><item><title>As a pro coder, it’s ALWAYS valuable to collect skills</title><link>https://www.procoder.io/articles/2024/2024-03-07_as-a-pro-coder--it-s-always-valuable-to-collect-skills-22134e566aba</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-03-07_as-a-pro-coder--it-s-always-valuable-to-collect-skills-22134e566aba</guid><description>Is it okay to study X, Y, and Z? Find out!</description><pubDate>Thu, 07 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;“Is it okay to study Java?” &lt;strong&gt;Yes!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;“Is JavaScript good to learn?” &lt;strong&gt;Yes!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;“Is there any benefit in learning CSS?” &lt;strong&gt;Yes yes yes.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The answer is almost always an emphatic &lt;em&gt;&lt;strong&gt;yes&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Years ago, I dubbed myself a “JavaScript Padawan”. That’s because several years ago, as part of a side role on the Spring team, I was able to work with John
Hann and Brian Cavalier, two JavaScript masters who taught me MUCH.&lt;/p&gt;
&lt;p&gt;A skillset I have used rarely has once again come back to serve me today!&lt;/p&gt;
&lt;p&gt;I am investigating the usage of Asciidoctor.js + reveal.js in a Node.js environment for some top-dollar content creation, and I’m the one with The Knowledge™.&lt;/p&gt;
&lt;p&gt;You’ll never know when a skill will serve you.&lt;/p&gt;
&lt;p&gt;Don’t hesitate to keep on learning. “Arrival syndrome”, the feeling that you have learned all that there is, is insidious and will tell you “Don’t worry about
that. You won’t need that.”&lt;/p&gt;
&lt;p&gt;EVEN IF you never leverage that new skill EVER, the very process of learning it can enhance your ability to learn, your ability to see how that product
influenced other products you DO use and obtain deeper understanding, and your ability to keep on growing, a vital thing we must all pursue.&lt;/p&gt;
&lt;p&gt;But in this industry, things often come full circle. Opportunities open up and the one with the skill may be able to offer a solution where none was found
before.&lt;/p&gt;
&lt;p&gt;Be willing to learn that toolkit or that technology. In today’s searchable/AI-empowered world, when you seek out the ref docs someday in the future, it will be
a snap to find them and get kicking.&lt;/p&gt;
&lt;p&gt;I may have dropped “JavaScript Padawan” from my tagline, but I will always treasure having learned that crazy language and being able to use it to serve my
team. I will always feel like I’m a JavaScript Padawan thanks to those two guys.&lt;/p&gt;
&lt;p&gt;Now what skill are YOU being offered a chance to go and learn? Do it!&lt;/p&gt;
&lt;p&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. But if you simply can’t wait, then check out the video below where I show how
you CAN interview for a new position even in the midst of a struggling tech sector!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY
NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="538" medium="image" url="https://www.procoder.io//_astro/1_5JfBtlGiwvBkW3ModPEFQw.COzNfked.png"/></item><item><title>“How do you deal with imposter syndrome? Asking for a friend… really.”</title><link>https://www.procoder.io/articles/2024/2024-02-21_-how-do-you-deal-with-imposter-syndrome--asking-for-a-friend--really---db9a34b5fb23</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-02-21_-how-do-you-deal-with-imposter-syndrome--asking-for-a-friend--really---db9a34b5fb23</guid><description>I first saw this question on Twitter, so I wrote the following response, sharing someone I had really done to help myself when I was…</description><pubDate>Wed, 21 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I first saw this question on Twitter, so I wrote the following response, sharing someone I had really done to help myself when I was squeezed into a corner. And amazingly, it helped me BEAT imposter syndrome!&lt;/p&gt;
&lt;p&gt;I started a Google Doc where I log what I do on a daily basis. Not deep. Just track tasks as bullet points. You should do the same.&lt;/p&gt;
&lt;p&gt;Worked a ticket? Grab a link to it. Read an issue? Grab a link to it. Had a meeting with someone? Write it down.&lt;/p&gt;
&lt;p&gt;Real easy to track daily tasks in short, summary form, newest stuff at the top. Headline every day.&lt;/p&gt;
&lt;p&gt;Commit to doing this everyday. It’s a new habit, so you may stumble, skip some days. That’s okay. Get back up and try again. Work to make a habit over the next 30 days. You can do this. This document is JUST FOR YOU.&lt;/p&gt;
&lt;p&gt;Now here’s where it begins to pay off.&lt;/p&gt;
&lt;p&gt;After a couple months of doing this, just pause. At the beginning of your day, before you lift a finger, just glance at your log of activity. Scroll your eyes down the page. That’s everything you just did over the past three days.&lt;/p&gt;
&lt;p&gt;Want a little more? Start scrolling the page. A week’s work right there within seconds.&lt;/p&gt;
&lt;p&gt;Haven’t looked in a while, go further back. Pages of actions YOU TOOK.&lt;/p&gt;
&lt;p&gt;Your memory will fail you. Your attempts to “motivate” yourself will fail you from time to time.&lt;/p&gt;
&lt;p&gt;But maintaining a running log of every contribution you make, big or small, won’t. Instead, you can SEE exactly what you did.&lt;/p&gt;
&lt;p&gt;Because it’s not about knocking out big ticket items every day. It’s about generating a certain amount of momentum for your team, built up out of lots of tiny tasks that you are deliberately picking every day.&lt;/p&gt;
&lt;p&gt;When I started doing this, whatever sense of Imposter Syndrome I did would evaporate in seconds.&lt;/p&gt;
&lt;p&gt;And that’s not all.&lt;/p&gt;
&lt;p&gt;This log begins to serve you in other ways.&lt;/p&gt;
&lt;p&gt;Too many big ticket items lately? Perhaps today is a day where it’s too hard to focus on that sort of stuff? Switch to grooming your backlog of tickets. Log ’em all. Do that for 2–3 days. Clean up tickets/close tickets/resolve tickets. Log ’em all.&lt;/p&gt;
&lt;p&gt;Seeing several days of dispositioned tickets is cool.&lt;/p&gt;
&lt;p&gt;After a few days of that, you’ll find that such menial labor will have allowed your “big” thinking energy to charge back up.&lt;/p&gt;
&lt;p&gt;That’s not all.&lt;/p&gt;
&lt;p&gt;Your manager, from time to time, perhaps just once a year, will come by and ask, “What is the big stuff you did this year?”&lt;/p&gt;
&lt;p&gt;He/she needs to attend that manager meeting where he needs to defend you.&lt;/p&gt;
&lt;p&gt;“Can you give me an hour?”&lt;/p&gt;
&lt;p&gt;Skim through your log of activity and try to spot all the key tasks you did over the last year. You can also tabulate HOW MANY tickets you cleaned up.&lt;/p&gt;
&lt;p&gt;Put together an email to your manager and list it out.&lt;/p&gt;
&lt;p&gt;“Hey boss, there’s the big stuff I did. A) I built that new parser with ANTLR, B) I upgraded the system to handle Whatchamadigit 2.0, and C) I cleaned up 58 tickets, reducing the backlog from 10 pages to 5. If you need more than that, let me know!”&lt;/p&gt;
&lt;p&gt;To do that, you have to start today. And you have to commit. Want more tips like that? Check out &lt;a href=&quot;https://www.youtube.com/redirect?event=backstage_event&amp;#x26;redir_token=QUFFLUhqbVV1T1FUSDVOeHRNNDhDVndGc0xFUnZsWHdSQXxBQ3Jtc0trOU1oREJCeUQ5R1k4Q1NwbmdEaHlIN3ZDc0stdm96TWtqT2tPOXhrNGhSeEdLTHBGRndKako5Q3FHeG1HenVyVzEzb3NZTEFQb3Rmc05Nc3lTdmZTaHFYQXgzQlB2WjhPdXpSandIRW56eUZXcUlaaw&amp;#x26;q=https%3A%2F%2F12rules.io%2F&quot;&gt;https://12rules.io&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*z9zT81x4hJhBtVOgn9-X3w.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. But if you simply can’t wait, then check out the episode below where I shared a handful of actionable tips to grow your career. In the meantime, go out there and be professional!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="612" height="408" medium="image" url="https://www.procoder.io//_astro/1_ek1VlaCIjb6xKtYobjP0PA.CfVhcW-g.png"/></item><item><title>The most important thing no one discusses in engineering!</title><link>https://www.procoder.io/articles/2024/2024-02-07_the-most-important-thing-no-one-discusses-in-engineering--f67150154a78</link><guid isPermaLink="true">https://www.procoder.io/articles/2024/2024-02-07_the-most-important-thing-no-one-discusses-in-engineering--f67150154a78</guid><description>During my senior year of computer engineering at Auburn University I had I take this one quarter course (yes, AU was on the quarter system…</description><pubDate>Wed, 07 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During my senior year of computer engineering at Auburn University I had I take this one quarter course (yes, AU was on the quarter system back then).&lt;/p&gt;
&lt;p&gt;It was almost nothing. And yet…it’s everything.&lt;/p&gt;
&lt;p&gt;I studied &lt;strong&gt;Engineering Economics&lt;/strong&gt;, and something that only took me nine weeks of study, its concepts and equations are something I reach for all the time, both in work and in life.&lt;/p&gt;
&lt;p&gt;The name of the course and the corresponding textbook doesn’t do the subject justice, You see this is the class where I was introduced to &lt;strong&gt;TVM&lt;/strong&gt;, the &lt;strong&gt;Time Value of Money&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The bedrock concept is that any payment has a &lt;strong&gt;present value&lt;/strong&gt; (PV) as well as a &lt;strong&gt;future value&lt;/strong&gt; (FV). For example, if you had:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$100 today.&lt;/li&gt;
&lt;li&gt;You were to put it in a bank account with a 7.2% yield.&lt;/li&gt;
&lt;li&gt;According to the equation FV=PV*(1+i)^n, it’s value in 10 years would be $200.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*Dl1oobpGvgCc5pwh.jpg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Where TVM begins to sizzle is when you take this simple equation and then dream up bigger scenarios.&lt;/p&gt;
&lt;p&gt;Imagine 10 consecutive cash flow payments where each year you put $100 into that same bank (7.2% annual interest). The first payment has 10 years to grow, just like before. Now if we’re talking about figuring out the value of things in ten years, like the previous example, then the second payment of $100 only has nine years to grow. The third payment will only have eight years. Rinse. Repeat.&lt;/p&gt;
&lt;p&gt;Using the equation above, you can grind through all ten cash flows. I realize that’s a chore, so I’ll go ahead and derive the sum &lt;strong&gt;future value&lt;/strong&gt; for you as $&lt;strong&gt;1394&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*nKrUHN8mo15FELoI.jpg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;On top of that, using the very same equation, you can handily equate this to a &lt;strong&gt;present value&lt;/strong&gt; of $&lt;strong&gt;695&lt;/strong&gt;. (We sometimes describe this as net present value, implying a sum of cash flows valued in present-day dollars)&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*Es7vOm8VN-TIyIY3.jpg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Essentially, you can either set aside $695 &lt;em&gt;today&lt;/em&gt;, or you can set aside $100 &lt;em&gt;a year&lt;/em&gt; for &lt;em&gt;ten years&lt;/em&gt;, and reach the same future value. To turn that around, ten payments of $100/year at 7.2% are equivalent to a $695 &lt;strong&gt;net present value&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you ever go to one of those financial services company that offers to convert your “structured settlement” into a lump sum, you should understand that they KNOW this equation backward and forward. (Ever seen a J.G. Wentworth commercial??) Their whole business model is to turn those &lt;strong&gt;cash flows&lt;/strong&gt; into a &lt;strong&gt;net present value&lt;/strong&gt; and then buy it from you &lt;em&gt;&lt;strong&gt;at a steep discount&lt;/strong&gt;&lt;/em&gt;!&lt;/p&gt;
&lt;h3 id=&quot;can-you-really-wait-for-that-100year-payment-id-be-willing-to-pay-you-400-right-now-its-your-money-use-it-when-you-wantit&quot;&gt;“Can you really wait for that $100/year payment? I’d be willing to pay you $400 right now! It’s your money. Use it when YOU want it!”&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Just to hammer the point home, accepting $400 for that cash flow would cost you $592 of future value, or $58/month in annualized payments. Ouch!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Just so you know, there is actually a calculator from the 1980s that can do TVM on the fly. You enter all the variable but one, and it solves for the other (notice the top-left row of buttons down below). &lt;strong&gt;Present value&lt;/strong&gt;, &lt;strong&gt;future value&lt;/strong&gt;, &lt;strong&gt;payment&lt;/strong&gt;, &lt;strong&gt;interest&lt;/strong&gt;, or &lt;strong&gt;number of payments&lt;/strong&gt;. It’s called the HP-12C (the “12” is important). You can still &lt;a href=&quot;https://amzn.to/480HxJI&quot;&gt;buy one on Amazon&lt;/a&gt; for a measly $38 (affiliate link). &lt;em&gt;Or just do what I did and buy the $10 iPhone app equivalent.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*-n9lwCL-qhls32zF.jpg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;em&gt;Wasn’t this supposed to be about engineering, Greg??&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;p&gt;We can build all kinds of things, but we aren’t talking pure research. We’re talking &lt;em&gt;&lt;strong&gt;engineering&lt;/strong&gt;&lt;/em&gt;. Engineering involves buildings things COMBINED with economics.&lt;/p&gt;
&lt;p&gt;To practice sound engineering, we need to not only develop the technology, we must analyze its economic impact. This means we need to translate things into dollars.&lt;/p&gt;
&lt;p&gt;Every effort, every task, every investment can be translated from technology into dollars. All of our efforts, once converted into cash flows, can be assessed as to whether we’re working at a profit or a loss.&lt;/p&gt;
&lt;p&gt;Many people balked at Cloudflare’s firing of a sales executive that had barely completed her onboarding process. &lt;a href=&quot;https://www.buymeacoffee.com/procoderio/this-not-pro-coders&quot;&gt;I disagreed&lt;/a&gt; with that reaction. Strongly.&lt;/p&gt;
&lt;p&gt;Companies operate based on cash flow, not good intentions nor by accumulating assets. If a new hire isn’t able to move the needle on cash flow, then it doesn’t matter how “well” they did at onboarding or much of anything else. To be honest, Cloudflare may have ramped up too many sales execs too late, and her fate may have already been sealed.&lt;/p&gt;
&lt;p&gt;When it comes to engineering, it’s vital that all the various efforts at play MUST be transformed into cash flow and then viewed at how things are stacking up.&lt;/p&gt;
&lt;p&gt;A team may be willing to invest in two years of &lt;strong&gt;negative cash flow&lt;/strong&gt; because they are aiming to turn a profit in the 3rd year. The total cost of all those cash flows, once tallied up and converted back to &lt;strong&gt;net present value&lt;/strong&gt; can inform management on whether or not the raised capital is sufficient for that investment. See?&lt;/p&gt;
&lt;p&gt;The sooner you as an enginer grok this concept, the sooner you can speak on management’s level, and begin to make decisions that perhaps better impact cash flow of the business. Ultimately, it the business doesn’t succeed, there will be no engineering. We as engineers need to understand where little tweaks in efficiency will subsequently get applied to every cash flow, and how that may turn a loss into a profit.&lt;/p&gt;
&lt;p&gt;We must also realize when we’re building something “too perfect” and causing the repeating cash flows to be come too heavy, hence turning a future profit into a loss.&lt;/p&gt;
&lt;p&gt;This is what engineering is about. If you don’t grok TVM, then you may still be in the “junior” camp. One of the most important skills to pick up and understand is to how think in dollars over time. And this is why ALL pro coders benefit from understanding these concepts.&lt;/p&gt;
&lt;p&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. But if you simply can’t wait, then check out the episode below where former Spring advocate Mark Heckler and I discuss what it really means to invest in yourself. In the meantime, go out there and be professional!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="600" medium="image" url="https://www.procoder.io//_astro/0_Dl1oobpGvgCc5pwh.C18peePT.jpg"/></item><item><title>Docker — What is it good for?</title><link>https://www.procoder.io/articles/2023/2023-12-23_docker---what-is-it-good-for--a087e6d78715</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-12-23_docker---what-is-it-good-for--a087e6d78715</guid><description>*Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then* [*SIGN UP FOR MY NEWSLETTER*](https://trnq.st/d2v5)*.*</description><pubDate>Sat, 23 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;dockerwhat-is-it-good-for&quot;&gt;Docker — What is it good for?&lt;/h1&gt;
&lt;hr&gt;
&lt;h2 id=&quot;dockerwhat-is-it-goodfor&quot;&gt;Docker — What is it good for?&lt;/h2&gt;
&lt;p&gt;Docker is one of most useful technologies to befall continuous integration. Containers empower you to define precisely what tools are available in every stage of your CI pipeline without battling CI configuration stuff.&lt;/p&gt;
&lt;p&gt;Consider this: in the olden days, if you wanted a new version of Java, you had to enlist your sys admin to install it into your CI tools. With Docker, you just update the container! (Or bake a new one.)&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*g10mKrjkXV3hI0v0Rt0trA@2x.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Of course, this requires a certain trust between you and the sys admin. It’s also advisable to have team agreement on certain things, like consistently using the same Java distribution across your team. Mixing distributions among other things can introduce risk.&lt;/p&gt;
&lt;p&gt;But leveraging containers to encapsulate aspects of test infrastructure and putting those container definitions along with your pipelines under source control can wrest control of your entire CI process away from clicky buttons and effectively make it all “code” that is reproducible and much more manageable.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*hDYKXxTwwfXePj5CwVi8wQ@2x.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. In the meantime, go out there and be professional!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="530" medium="image" url="https://www.procoder.io//_astro/1_g10mKrjkXV3hI0v0Rt0trA@2x.BAg68Ryx.jpeg"/></item><item><title>What is a pro coder’s most important tool?</title><link>https://www.procoder.io/articles/2023/2023-12-01_what-is-a-pro-coder-s-most-important-tool--ec1082bb52d2</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-12-01_what-is-a-pro-coder-s-most-important-tool--ec1082bb52d2</guid><description>It’s not a grab bag of programming languages, though speaking multiple languages is useful.</description><pubDate>Fri, 01 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;what-is-a-pro-coders-most-important-tool&quot;&gt;What is a pro coder’s most important tool?&lt;/h1&gt;
&lt;p&gt;It’s not a grab bag of programming languages, though speaking multiple languages is useful.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;what-is-a-pro-coders-most-important-tool-1&quot;&gt;What is a pro coder’s most important tool?&lt;/h2&gt;
&lt;p&gt;It’s not a grab bag of programming languages, though speaking multiple languages is useful.&lt;/p&gt;
&lt;p&gt;It’s not that shiny new M3 Max MacBook Pro maxed out in cores &amp;#x26; RAM with the 8 TB internal drive either. (Want to see how quickly Apple turns this article from edgy to antique with their high speed rollout of Apple silicon?)&lt;/p&gt;
&lt;p&gt;And it’s CERTAINLY not that that Samsung 49” curved monitor (which can double as a boat anchor in an emergency!)&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*6CW3A4SRWHduOKfiDcmFbg@2x.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Nope.&lt;/p&gt;
&lt;p&gt;While those are powerful tools, there is something else of much greater value. In fact, it’s such a powerful tool, you can’t buy it. At least not directly.&lt;/p&gt;
&lt;p&gt;This asset that will pay ever increasing dividends for the life of your career can only be possessed when you invest your own personal time.&lt;/p&gt;
&lt;p&gt;Professional relationships.&lt;/p&gt;
&lt;p&gt;The people that you meet and serve as you forge your path are the most important thing you can add to your portfolio.&lt;/p&gt;
&lt;p&gt;Remember how I said you can’t buy it with money? That’s true. Only an investment of &lt;em&gt;genuine&lt;/em&gt; and &lt;em&gt;sincere&lt;/em&gt; time will grow this bountiful asset.&lt;/p&gt;
&lt;p&gt;You see, the thing this world runs on isn’t money or greed, though it’s easy to see the cynical side of things. This world runs on value creation.&lt;/p&gt;
&lt;p&gt;When you provide value to others by solving problems for them, they will appreciate it on a deeper level than any business transaction ever can. As coders, our job is to solve problems for others. Look for ways to help others, to provide value, and eventually that genuine investment will pour back into you.&lt;/p&gt;
&lt;p&gt;Remember me saying &lt;em&gt;sincere&lt;/em&gt; investment earlier? It’s true. If you take a shallow approach of helping something simply to bum a favor off of them, it won’t work.&lt;/p&gt;
&lt;p&gt;You can smell someone using you like that, right? Well other people sense the same coming from you. So put aside what you need right now, and instead simply listen. Find out what they need. And strive to meet that need.&lt;/p&gt;
&lt;p&gt;Sometimes you’ll get paid right away. Sometimes you won’t. Sometimes you won’t see anything came your way for years. Or perhaps never, from that person.&lt;/p&gt;
&lt;p&gt;But I promise, if you take a general attitude of serving others, of providing value to others and not sitting there with your hand out at the same time, but instead sincerely serve everyone you meet, you will witness a flow of abundance back to you over time.&lt;/p&gt;
&lt;p&gt;And truth be told, as much as coding is about computers, it’s more so about the people using the computers. When I adopted an always-test approach to a non-functioning invoice reconciliation app and held true to that standard, it took me five months to get it working. But once I did, it began to gain momentum.&lt;/p&gt;
&lt;p&gt;As excited as I was to see that growing sea of green checkboxes, it wasn’t until months later when I stopped in the break room and ran into once of people from accounts payable that used it. She remarked how the latest version of that app had let her finish ten invoices that morning. Something that she used to have to do manually and would have taken 2–3 weeks.&lt;/p&gt;
&lt;p&gt;The look on her face and the excitement in her voice made it clear to me that this app wasn’t about me. It wasn’t about the tech it was written in or what patterns had been used.&lt;/p&gt;
&lt;p&gt;It was all about the value afforded to a fellow colleague.&lt;/p&gt;
&lt;p&gt;And that realization has forever steered me toward seeking the value I can provide to others on each and every task.&lt;/p&gt;
&lt;p&gt;And when you build a career out of providing value to others, and you are in a pinch, it becomes a lot easier to ask for help. Because now it isn’t about business and money. Now it’s about the genuine value they can offer you when you truly need it.&lt;/p&gt;
&lt;p&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. In the meantime, go out there and be professional!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="398" medium="image" url="https://www.procoder.io//_astro/1_6CW3A4SRWHduOKfiDcmFbg@2x.LYrfyvxA.jpeg"/></item><item><title>Don’t be afraid to take a shot!</title><link>https://www.procoder.io/articles/2023/2023-10-07_don-t-be-afraid-to-take-a-shot--70e6c3cb80d0</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-10-07_don-t-be-afraid-to-take-a-shot--70e6c3cb80d0</guid><description>A couple weeks ago, I pinged our fearless leader. I needed some direction before taking on a couple tasks. One of these tasks I was…</description><pubDate>Sat, 07 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;dont-be-afraid-to-take-a-shot&quot;&gt;Don’t be afraid to take a shot!&lt;/h1&gt;
&lt;p&gt;A couple weeks ago, I pinged our fearless leader. I needed some direction before taking on a couple tasks. One of these tasks I was…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;dont-be-afraid-to-take-ashot&quot;&gt;Don’t be afraid to take a shot!&lt;/h3&gt;
&lt;p&gt;A couple weeks ago, I pinged our fearless leader. I needed some direction before taking on a couple tasks. One of these tasks I was thinking about, which seemed tiny at the time, I joked “for THAT one, perhaps I should write a parser?”&lt;/p&gt;
&lt;p&gt;He rolled his eyes. “We don’t need a parser.”&lt;/p&gt;
&lt;p&gt;Two weeks later…&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*rsWLmOIE9cRFhtGIvMjFUg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Spring Data JPA has a handy feature where you can dynamically feed it &lt;strong&gt;ORDER BY&lt;/strong&gt; clauses with simple strings, e.g. &lt;strong&gt;Sort.by(“firstname”)&lt;/strong&gt;. This nicely gets turned into a JPA Criteria &lt;strong&gt;Expression&lt;/strong&gt; object.&lt;/p&gt;
&lt;p&gt;In the simplest of cases, this is an entity type’s property name. However, we have always offered this escape hatch where you can feed it ANYTHING. For example, you could feed it &lt;strong&gt;LENGTH(firstname)&lt;/strong&gt; as your criteria to apply an &lt;strong&gt;ORDER BY&lt;/strong&gt; to a query, where you order things not by the row’s &lt;strong&gt;firstname&lt;/strong&gt; but instead by the length of the row’s &lt;strong&gt;firstname&lt;/strong&gt;. Basically, anything that your JPA provider supports.&lt;/p&gt;
&lt;p&gt;In my pre-op analysis, I uncovered a seemingly endless supply of hacks and workarounds on StackOverflow.com. I was beginning to think that this feature NEVER worked!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*bjE44xN1CuLz3491ZCllDA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Quite naturally, as a test-bitten script junky, my first step was to write a test case. &lt;strong&gt;LENGTH(firstname)&lt;/strong&gt; seemed like the textbook scenario that perfectly captured the situation while being easy to reason over.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*r9VfRzW_xHLNDa2sOIDt1w.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Right there, in the middle, you can see &lt;strong&gt;LENGTH(firstname)&lt;/strong&gt; nestled in the midst of &lt;strong&gt;JpaSort.unsafe()&lt;/strong&gt;. To be clear, this query essentially says “find all objects and order them not by their &lt;strong&gt;firstname&lt;/strong&gt;, but instead by the &lt;strong&gt;length&lt;/strong&gt; of their &lt;strong&gt;firstname&lt;/strong&gt;. (This query also has a paging argument, which I won’t delve into).&lt;/p&gt;
&lt;p&gt;With this tasty string value at my finger tips, I cracked open JPA’s &lt;strong&gt;CriteriaBuilder&lt;/strong&gt; interface and began scouring it, looking for the place where you feed it a string like that and get handed back an &lt;strong&gt;Expression&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There was none to be found.&lt;/p&gt;
&lt;p&gt;You see, if you have a simple entity property like &lt;strong&gt;firstname&lt;/strong&gt;, then you can submit a &lt;strong&gt;from.get(“firstname”)&lt;/strong&gt; call. The from object is the root entity (&lt;strong&gt;User&lt;/strong&gt; in this test scenario). &lt;strong&gt;from.get(“firstname”)&lt;/strong&gt; is turned by the Criteria API into &lt;strong&gt;ORDER BY User.firstname&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But any sort of “parse this string” doesn’t exist!&lt;/p&gt;
&lt;p&gt;My eyebrows narrowed. Having tamed the beast of HQL a few months ago with the power of ANTLR, my thoughts of writing some type of parser rapidly shifted from humor toward seriousness.&lt;/p&gt;
&lt;p&gt;And then a lightbulb went off.&lt;/p&gt;
&lt;p&gt;I didn’t have to write a parser. I already HAD a parser! The HQL one I had written months ago. You see in ANTLR, there is no requirement that you enter a parser at the “top”. That’s only required if you are parsing an entire query.&lt;/p&gt;
&lt;p&gt;In this scenario, I only want to parse from the &lt;strong&gt;ORDER BY&lt;/strong&gt; clause, which for HQL is the &lt;strong&gt;sortExpression&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*VHY0ImgbquuSC3K12JMnxA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;In HQL parsing, it’s technically &lt;strong&gt;ORDER BY sortedItem&lt;/strong&gt;, which &lt;strong&gt;sortedItem&lt;/strong&gt; including things like &lt;strong&gt;ASC&lt;/strong&gt; and &lt;strong&gt;DESC&lt;/strong&gt;. However, our &lt;strong&gt;JpaSort&lt;/strong&gt; already takes on aspects like direction, so I must enter one level deeper, the &lt;strong&gt;sortExpression&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And thus a method was drafted!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*KdSNLmKgClgUj3SV_JW0KA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This is standard entry into ANTLR. You craft an HQL lexer to turn the string value of the JpaSort’s property value into a series of tokens. You then feed that stream of tokens into an HQL-based parser, and finally “visit” it by invoking the sortExpression() method in the ANTLR-generated class.&lt;/p&gt;
&lt;p&gt;Hanging this inside a newly minted &lt;strong&gt;HqlOrderByExtractor&lt;/strong&gt; class, with copies of JPA’s &lt;strong&gt;CriterialBuilder&lt;/strong&gt; and &lt;strong&gt;From&lt;/strong&gt;, I was ready to begin.&lt;/p&gt;
&lt;p&gt;But WHAT was I ready to begin doing?&lt;/p&gt;
&lt;p&gt;Simply put, I was going to write a brand new ANTLR visitor!&lt;/p&gt;
&lt;p&gt;ANTLR has two ways to walk through a parsed structure. The visitor pattern is the only one that gives you one method to handle entering and exiting a given token, hence this was it.&lt;/p&gt;
&lt;p&gt;The previous ANTLR visitor I wrote for fully parsing an entire HQL query is based upon transforming one string into another. That’s not what we’re doing here. Instead, the mission here is to transform an &lt;strong&gt;ORDER BY&lt;/strong&gt; clause into a Criteria API &lt;strong&gt;Expression&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And away I flew! It turned out to not be that hard to capture our leading example of &lt;strong&gt;LENGTH(firstname)&lt;/strong&gt; and turn it into an &lt;strong&gt;Expression&lt;/strong&gt;. The code itself may appear tedious to those unfamiliar with ANTLR’s visitor paradigm, but for me, this was old hat.&lt;/p&gt;
&lt;p&gt;I had that function working within a day. The question shifted to what OTHER expressions did HQL support?&lt;/p&gt;
&lt;p&gt;A. Lot.&lt;/p&gt;
&lt;p&gt;The screenshot below is but a sliver of the test cases I wrote.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*j_aj8YNqIZZ0b20jjip8JA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;You can really write an HQL query with &lt;strong&gt;ORDER BY CASE firstname WHEN ‘Oliver’ then ‘A’ ELSE firstname end&lt;/strong&gt;, where if the &lt;strong&gt;firstname&lt;/strong&gt; matches &lt;strong&gt;Oliver&lt;/strong&gt;, it will swap in the value &lt;strong&gt;A&lt;/strong&gt;, and otherwise it will simply use the row’s &lt;strong&gt;firstname&lt;/strong&gt;, all for the purposes of ordering the data.&lt;/p&gt;
&lt;p&gt;Once I captured all these scenarios and implemented them, I moved on to coding support for JPQL (Java Persistence Query Language) as well EQL (EclipseLink Query Language).&lt;/p&gt;
&lt;p&gt;In the interests of bringing this article back to this world, suffice it to say, I spent another four days writing tests and implementing them. I even wrote some special test utilities that helped me “hide” Hibernate as well as EclipseLink from some of our classpath checks, making it a snap to verify our supported JPA providers.&lt;/p&gt;
&lt;p&gt;After almost entire day spent simply polishing my changes, renaming things, and writing suitable comments, I submitted a pull request to our team leader. He happened to be on PTO the week I did all this work.&lt;/p&gt;
&lt;p&gt;And perhaps that’s a good thing.&lt;/p&gt;
&lt;p&gt;His absence provoked me to take this shot and implement support for a feature that looks as if it may NEVER have worked. And I’m quite proud of being able to leverage the knowledge I attained in building our HQL parser in the first place.&lt;/p&gt;
&lt;p&gt;And I hope this provokes &lt;em&gt;you&lt;/em&gt; to consider taking a shot on something that may at first sound like a lark, but could be the turning point in a system you are working on.&lt;/p&gt;
&lt;p&gt;To be a pro coder, you sometimes have to take that shot.&lt;/p&gt;
&lt;p&gt;Not a reckless gamble, but instead a fair minded attempt at something that may take more than a day to even figure out if it’s plausible. But an attempt that if successful, may be a turning point in the system you’re working on.&lt;/p&gt;
&lt;p&gt;Because that’s one of the defining differences between a hobbyist and a pro coder. Pro coders implement things that aren’t always the easiest nor straight forward. But sometimes because we have little more than a hint that this may be the right thing to do.&lt;/p&gt;
&lt;p&gt;If you are pro coder or aiming to become one, then stay tuned for my next article. But if you simply can’t wait, then check out this video below where Josh Long and I shoot the breeze over Spring Data during SpringOne @ VMware Explore in 2023.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about PRO CODING? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="425" medium="image" url="https://www.procoder.io//_astro/1_rsWLmOIE9cRFhtGIvMjFUg.BlLEZdjo.png"/></item><item><title>Have you said “thank you” to yourself lately?</title><link>https://www.procoder.io/articles/2023/2023-06-17_have-you-said--thank-you--to-yourself-lately--b0e8b3818a29</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-06-17_have-you-said--thank-you--to-yourself-lately--b0e8b3818a29</guid><description>“What? Say ‘thank you’? What kind of column is this, Greg?”</description><pubDate>Sat, 17 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;have-you-said-thank-you-to-yourself-lately&quot;&gt;Have you said “thank you” to yourself lately?&lt;/h1&gt;
&lt;p&gt;“What? Say ‘thank you’? What kind of column is this, Greg?”&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;have-you-said-thank-you-to-yourselflately&quot;&gt;Have you said “thank you” to yourself lately?&lt;/h3&gt;
&lt;p&gt;“What? Say ‘thank you’? What kind of column is this, Greg?”&lt;/p&gt;
&lt;p&gt;I am trying to share with you some of the most important things you can be doing as a pro coder, and stopping to thank yourself is pretty high on the list!&lt;/p&gt;
&lt;p&gt;When we slug it out, day in and day out, writing code, crafting automated tests, tracking down bugs, and working on releases, there are days when you’re flat out beat. Sometimes at the end of the day, your brain dissolves into goo.&lt;/p&gt;
&lt;p&gt;Hopefully, writing the code is loads of fun and very exciting. Doesn’t mean it also doesn’t wear you out.&lt;/p&gt;
&lt;p&gt;And so it’s OKAY to stop every now and then. Maybe this hour or the next, and say “thank you” to yourself. But I’m not talking about words. I’m talking about something a little more substantive than that.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It’s okay to stop and read another chapter of that latest book you’re on. (I’ve been reading &lt;a href=&quot;https://trnq.st/v1df&quot;&gt;&lt;em&gt;Humble Pi&lt;/em&gt;&lt;/a&gt; by Matt Parker lately.)&lt;/li&gt;
&lt;li&gt;It’s also okay to pause and watch a video from your favorite YouTube channel. (I love physics videos and calculus videos. Go figure!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’d mention stopping to check out your favorite social media for a bit, but there is a greater risk you’ll start scrolling and suddenly get sucked in for the next hour!&lt;/p&gt;
&lt;p&gt;Taking a few breaks throughout the day and rewarding yourself with something enjoyable (but not TOO long) is OKAY.&lt;/p&gt;
&lt;p&gt;I once met with someone that point blank told me it was okay for ME to take breaks like this. I…didn’t realize I was so instinctively apprehensive to the thought of taking breaks like that. But somehow, TELLING me it was okay brushed that aside.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*24Yrvoye3Aq5ktsRRpA0OA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Anytime I feel the slightest hint that I shouldn’t be doing it…I remember that voice. And I smile a bit. It’s okay to take a break. And so I’m telling YOU the same.&lt;/p&gt;
&lt;p&gt;Anytime someone suggests you shouldn’t do it…tell them I said it was OKAY. Because we have an important job to do. That code requires the best of us, and taking a break to replenish your energy is actually a Good Idea.&lt;/p&gt;
&lt;p&gt;We can’t operate systems if we’re hobbling along. It’s vital to eat, rest, and replenish our mental, spiritual, and emotional energies. If taking a break to read a chapter or watch a video is what it takes, then that’s what it takes.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I get to the bottom of what it takes to make yourself absolutely indespensible to your team.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_24Yrvoye3Aq5ktsRRpA0OA.CtZMOK8t.jpeg"/></item><item><title>I have to admit…Spring Data is ACTUALLY my favorite Spring project!</title><link>https://www.procoder.io/articles/2023/2023-06-10_i-have-to-admit-spring-data-is-actually-my-favorite-spring-project--cc76722f37c5</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-06-10_i-have-to-admit-spring-data-is-actually-my-favorite-spring-project--cc76722f37c5</guid><description>I know I’ve previously written about how Spring Security just might be my favorite project. However, that opinion had to be put on the…</description><pubDate>Sat, 10 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;i-have-to-admitspring-data-is-actually-my-favorite-spring-project&quot;&gt;I have to admit…Spring Data is ACTUALLY my favorite Spring project!&lt;/h1&gt;
&lt;p&gt;I know I’ve previously written about how Spring Security just might be my favorite project. However, that opinion had to be put on the…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;i-have-to-admitspring-data-is-actually-my-favorite-springproject&quot;&gt;I have to admit…Spring Data is ACTUALLY my favorite Spring project!&lt;/h3&gt;
&lt;p&gt;I know I’ve previously written about how Spring Security just might be my favorite project. However, that opinion had to be put on the shelf when I realized that Spring Integration might actually be my favorite project. It’s really tough to hold onto that opinion when I stopped to realize how Spring MVC might be favorite project.&lt;/p&gt;
&lt;p&gt;But I’ve been thinking real hard since I wrote those articles. And I have to be honest. Truthfully, spiritually, &lt;em&gt;ecumenically&lt;/em&gt; honest.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*9w5WDg4UAjsYxs7G0rJsLw.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Spring Data is ACTUALLY my favorite Spring project.&lt;/p&gt;
&lt;p&gt;Spring Data is the thing that makes application development really sizzle. Why? Because every application has data. What kind of app doesn’t?&lt;/p&gt;
&lt;p&gt;The number of times I’ve needed some quick-and-dirty solution to grab a piece of data, Spring Data lets me jump right to it using custom finders. Custom finders let you define all the details of a query with a simple method signature. No implementation. No Hibernate query. No SQL query. Just a method name and the parameters. Spring Data will write the query for me.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*XS271OKHQ_xr41eWXchVDQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Just look at this example. These are three different custom finders.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first one fetches a &lt;strong&gt;List&lt;/strong&gt; of &lt;strong&gt;User&lt;/strong&gt; domain objects based on a complete match of the &lt;strong&gt;firstName&lt;/strong&gt; field. The user supplies not just the &lt;strong&gt;firstName&lt;/strong&gt;, but also a &lt;strong&gt;Pageable&lt;/strong&gt;, meaning you can pick the page of date you’ll get back.&lt;/li&gt;
&lt;li&gt;The second one fetches a &lt;strong&gt;Page&lt;/strong&gt; of &lt;strong&gt;User&lt;/strong&gt; domain objects using the same page-based filtering. But instead of matching on a single &lt;strong&gt;firstName&lt;/strong&gt;, it instead does a &lt;em&gt;&lt;strong&gt;WHERE first_name IN (:firstNames)&lt;/strong&gt;&lt;/em&gt; type criteria, allowing you to find multiple matches.&lt;/li&gt;
&lt;li&gt;The third one is much more details. It find the first three User domain objects that match the firstName exactly against a result set ordered by firstName ascending and emailAddress ascending. But does it through Spring Data JPA’s new scroll API, meaning that you can fetch a Window of data, then move to the next window smoothly, and without being confined to the same page size for each iteration!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just stop and try to imagine the time it would have taken using good ole’ JDBC to do the same!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You would have to open a connection to the database.&lt;/li&gt;
&lt;li&gt;Come up with your query. Probably have to consult the team’s ER diagram. Make sure you have an entity object that maps to all the fields. With the query put together, which might take some testing against in a SQL shell, you could then plug it into JDBC.&lt;/li&gt;
&lt;li&gt;Next you’d have to iterate over the result set handed back to you. If you were smart, you’d be using JdbcTemplate and simply define a mapper. But still, that’s a lot of effort. As you iterate, you’d have to populate the target data type. Notice how each method above has a slightly different container?&lt;/li&gt;
&lt;li&gt;Then you’d have to close the result set.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Did I miss anything?&lt;/p&gt;
&lt;p&gt;Oh wait! You also have to close the connection! (How many times have you fumbled over that?)&lt;/p&gt;
&lt;p&gt;Spring Data JPA lets you step over ALL of that and begin thinking in business terms. Now I admit that JPA gives you a leg up by taking away the need for doing all the result set mapping onto domain objects. But nevertheless, there is a still a process to do that dance with the entity manager!&lt;/p&gt;
&lt;p&gt;With Spring Data you can move right to the point of speaking in business-speak and writing the results that you want, while letting Spring Data “figure it out.”&lt;/p&gt;
&lt;p&gt;But this is where Spring Data is just getting started. There are so many other options should you need them. For example, if you have a search box on your web page where the user can enter anything into any field, and you really have no idea what is filled out and what’s not, then custom finders aren’t the way.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*24Yrvoye3Aq5ktsRRpA0OA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This is the PERFECT scenario for Query by Example. This is where you fill out a “probe” with the inputs provided from the search box on your webpage.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*L9p1NDG7PSwTxiqC_pTKOg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;When you turn it over to Spring Data, it simply matches on the fields that aren’t null, and ignores the rest. This pushes power into the user’s hands and takes the responsibility off of you.&lt;/p&gt;
&lt;p&gt;Spring Data also has the ability to simply let you write the query, if you already know it, using the @Query annotation. And given Spring Data JPA’s recent addition of both JPQL and HQL parsers, it can still support flexible sorting options.&lt;/p&gt;
&lt;p&gt;In a world where everyone and their cousin is learning a new web-based toolkit every week, and where security certifications and training is turning into an expensive, time-consuming beast to build your skill set, there lies a glimmer of hope.&lt;/p&gt;
&lt;p&gt;That’s because if you can learn how to query for data, how to store it &amp;#x26; fetch it at will from any database, and how to turn business requirements in database actions, you can make yourself incredibly valuable to your team!&lt;/p&gt;
&lt;p&gt;And with Spring Data on your tool belt, it’s not as hard as perhaps it once was ages ago.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where you can get a deeper dive into EXACTLY what Spring Data has to offer.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="780" height="438" medium="image" url="https://www.procoder.io//_astro/1_9w5WDg4UAjsYxs7G0rJsLw.B35ysWCY.jpeg"/></item><item><title>Now that I think about it, Spring MVC may be my favorite Spring project!</title><link>https://www.procoder.io/articles/2023/2023-04-15_now-that-i-think-about-it--spring-mvc-may-be-my-favorite-spring-project--d20a6b1ace03</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-04-15_now-that-i-think-about-it--spring-mvc-may-be-my-favorite-spring-project--d20a6b1ace03</guid><description>I’ve said before how Spring Integration may in fact be my favorite Spring portfolio project.</description><pubDate>Sat, 15 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;now-that-i-think-about-it-spring-mvc-may-be-my-favorite-spring-project&quot;&gt;Now that I think about it, Spring MVC may be my favorite Spring project!&lt;/h1&gt;
&lt;p&gt;I’ve said before how Spring Integration may in fact be my favorite Spring portfolio project.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;now-that-i-think-about-it-spring-mvc-may-be-my-favorite-springproject&quot;&gt;Now that I think about it, Spring MVC may be my favorite Spring project!&lt;/h3&gt;
&lt;p&gt;I’ve said before how Spring Integration may in fact be my favorite Spring portfolio project.&lt;/p&gt;
&lt;p&gt;While true, I simply can’t go any further without bringing up Spring MVC.&lt;/p&gt;
&lt;p&gt;In case you didn’t know, Spring MVC is part of the Spring Framework, the origin of Spring’s goodness. And Spring MVC has been a core item for years. So no, it’s not a portfolio project. Nevertheless, it’s really hopping good!&lt;/p&gt;
&lt;p&gt;Why is it possible my FAVORITE project? Let’s find out.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*KD4Ybkb-p_UVsvMvuZeHxg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 1 — Powerful support for any web app, with or without JavaScript&lt;/p&gt;
&lt;p&gt;The web development landscape is ever-evolving. Heck, I’ve written past article citing the crazy game where you pick a noun and enter that word + “javascript” into Google, to see if there’s some Node library by that name.&lt;/p&gt;
&lt;p&gt;As funny as that may be, we can’t ignore trends in the front end market. It’s vital to stay on top of them. And what’s key, is knowing that whether you’re building a lightweight app or a feature-packed behemoth, Spring MVC has your back.&lt;/p&gt;
&lt;p&gt;Spring MVC offers unparalleled support for web applications, both with and without JavaScript front-end toolkits like Angular, React, or Vue. Those are the biggies, but frankly, and Node toolkit you need, you can integrate into your application and make it work.&lt;/p&gt;
&lt;p&gt;When I was writing the web chapter of Learning Spring Boot 3.0, I frankly wasn’t sure where to start!&lt;/p&gt;
&lt;p&gt;In prior editions, I had gone a tad too deep for what people expect from a Java-based book. So this time around, I sought to show the basics of how to stir in some Node-based code and get it off the ground. Where you take it is up to you.&lt;/p&gt;
&lt;p&gt;That’s because Spring MVC frankly doesn’t care WHAT you put in your front end. Whether it’s a bunch of JS that violates every rule about globally scoped variables or something that upholds the highest standards of ES5 modules, Spring MVC won’t get in your way.&lt;/p&gt;
&lt;p&gt;Its role is to integrate rock solid HTTP standards into your flow and make them work, and by golly, it does just that.&lt;/p&gt;
&lt;p&gt;The beauty of Spring MVC lies in its versatility. You can harness its power to create a server-rendered app or a single-page application (SPA). The framework embraces the concept of modularity, allowing you to plug in your favorite front-end tools to create a bespoke solution tailored to your needs. So, whether you’re a seasoned JavaScript pro or prefer a more traditional server-rendered approach, Spring MVC is the reliable, adaptable partner you’ve been seeking.&lt;/p&gt;
&lt;h3 id=&quot;2easy-to-build-simple-web-flows-scale-up-to-complex-problems-asneeded&quot;&gt;2 — Easy to build simple web flows, scale up to complex problems as needed&lt;/h3&gt;
&lt;p&gt;There’s no denying that we want elegant, streamlined solutions. When it comes to Spring MVC, I’ve been amazed how I can slap together simplest web flows with finesse.&lt;/p&gt;
&lt;p&gt;I’m no web expert. I don’t spin HTML and CSS together like some sort of web wizard. In fact, I usually have to look up stuff to do it right. But Spring MVC is always ready to help me along the way.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*wmO31IKLsmXUyar6AR0TDg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;On a certain assignment, a few years ago, I dug in deep using React to build a complex GUI to pick out various options. Spring MVC didn’t bat an eyelash. It was, in fact, an eye-opening experience to the magic of React! And Spring MVC choreographed the data dance with elegance.&lt;/p&gt;
&lt;p&gt;No sense of slogging through a morass of convoluted code. My web controllers and service layers nicely worked with the React UI I had built like a wonderful incantation.&lt;/p&gt;
&lt;p&gt;So no matter what you are building, big or small, Spring MVC makes it snap to execute.&lt;/p&gt;
&lt;h3 id=&quot;3integrates-tightly-with-springsecurity&quot;&gt;3 — Integrates tightly with Spring Security&lt;/h3&gt;
&lt;p&gt;Let’s face it. Today’s digital threat landscape is ever-expanding, and security is paramount. Spring MVC’s commitment to protecting our application is unwavering. That’s why it’s tight integration with Spring Security is built to ensure that our app remains secure and impenetrable to cyber threats.&lt;/p&gt;
&lt;p&gt;Now it should go without saying that security is a multi-layered effort. Nothing is truly “impenetrable”. But we can at least make it difficult.&lt;/p&gt;
&lt;p&gt;As mentioned &lt;a href=&quot;/articles/medium/2023-03-27_why-spring-security-may-be-my-favorite-spring-project-e0131ae1bb68&quot;&gt;in my previous article&lt;/a&gt;, Spring Security has gobs of sensible defaults activate when we choose to flip the switch on web security. Part of that is because Spring MVC makes it easy to craft filters that leverage the various HTTP standards to implement and enforce security protocols by communicating properly with the browser.&lt;/p&gt;
&lt;p&gt;If you pause and start reading the specs on both security as well as HTTP security and headers, it’s honestly a long read. And it ain’t super exciting. But Spring MVC has built the mechanisms through which Spring Security can institute the right actions to take.&lt;/p&gt;
&lt;p&gt;All while allowing US to write our OWN filters such that we won’t derail everything. It’s possible to plugin custom filters that meet our business needs, and not accidentally knock security out the window.&lt;/p&gt;
&lt;p&gt;To top things off, whenever we need access to security, we can easily inject them into your web controller methods. Check out the following web controller method where we hand the current authentication object to the template engine:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*ftoCHZsXBzf-9Gq1j2Py4w.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;By passing the authentication object along to the template, the template has the opportunity to conditionally render bits of HTML.&lt;/p&gt;
&lt;p&gt;All we have to do is include the Authentication object in our web controller’s method signature, and Spring MVC will automatically inject it. Nothing else is needed!&lt;/p&gt;
&lt;h3 id=&quot;4works-nicely-with-template-engines-especially-thymeleaf&quot;&gt;4 — Works nicely with template engines, especially Thymeleaf&lt;/h3&gt;
&lt;p&gt;When it comes to crafting proper HTML, template engines are pretty much here to stay. We’ve seen many come and go, but no one is writing HTML by hand ever again.&lt;/p&gt;
&lt;p&gt;Spring MVC works like a dream with a variety of template engines, but it truly shines when paired with Thymeleaf. This dynamic duo will make implementing any web solution a walk in the park.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*aQ8VfXg8_V8FXC0fdspkpg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Source: &lt;a href=&quot;https://www.thymeleaf.org/doc/tutorials/3.1/thymeleafspring.html&quot;&gt;https://www.thymeleaf.org/doc/tutorials/3.1/thymeleafspring.html&lt;/a&gt;Now I have a confession: Whenever I write Thymeleaf templates, I absolutely must have the ref docs open and in front of me. I’m sorry, but I must.&lt;/p&gt;
&lt;p&gt;Nevertheless, that templating engine is loaded with the power we need. And…it’s HTML compliant! Older templating engines like good ole JSPs were not. That means you can open a raw template in your browser, and it won’t look like pure garbage.&lt;/p&gt;
&lt;p&gt;If you look at the fragment up above, all the fields prefixed “th:” are Thymeleaf directives. And with the DTD in place, you actually have some amount of code completion in your IDE!&lt;/p&gt;
&lt;p&gt;Thymeleaf integrates seamlessly with Spring MVC, allowing you to create rich, interactive web applications with ease. The result is a powerful yet straightforward approach to web development, which simplifies your workflow and streamlines your code.&lt;/p&gt;
&lt;p&gt;Thanks to Thymeleaf’s expressive syntax and Spring MVC’s robust architecture, you’ll be able to create stunning, responsive web applications with unrivaled efficiency.&lt;/p&gt;
&lt;h3 id=&quot;5doesnt-get-in-your-way-when-solvingproblems&quot;&gt;5 — Doesn’t get in your way when solving problems&lt;/h3&gt;
&lt;p&gt;One of the most endearing aspects of Spring MVC is its unobtrusive nature. As developers, the last thing we need is a cumbersome framework that hinders our problem-solving prowess.&lt;/p&gt;
&lt;p&gt;Spring MVC does what it’s SUPPOSED to do…and then it gets out of the way. This really lets me focus on the problem and not get bogged down in the “working the toolkit”.&lt;/p&gt;
&lt;p&gt;Spring MVC’s non-intrusive approach is a testament to its thoughtful design. And when you chat with its creators including (but not limited to) Arjen Poutsma and Rossen Stoyanchev, you’ll find that they spent an INORDINATE amount of time carefully putting this type of usability into it.&lt;/p&gt;
&lt;p&gt;Spring MVC was built to be flexible.&lt;/p&gt;
&lt;p&gt;Spring MVC is a true gem in the realm of web development. It’s no wonder that some of the biggest shops out still use it to this day for some of the latest and greatest apps.&lt;/p&gt;
&lt;p&gt;And that’s why, even though not REALLY a portfolio project, Spring MVC may nevertheless be my favorite Spring project.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I found the most powerful programmer in the entire gaming world and had him help me build a web app with Mustache.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="420" medium="image" url="https://www.procoder.io//_astro/1_KD4Ybkb-p_UVsvMvuZeHxg.DvuLulhd.jpeg"/></item><item><title>Actually, Spring Integration May Be My Favorite Spring Project</title><link>https://www.procoder.io/articles/2023/2023-04-01_actually--spring-integration-may-be-my-favorite-spring-project-c7a5b04f0433</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-04-01_actually--spring-integration-may-be-my-favorite-spring-project-c7a5b04f0433</guid><description>While Spring Security is wickedly powerful and essential for securing Java applications, there’s another Spring project that is equally…</description><pubDate>Sat, 01 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;actually-spring-integration-may-be-my-favorite-spring-project&quot;&gt;Actually, Spring Integration May Be My Favorite Spring Project&lt;/h1&gt;
&lt;p&gt;While Spring Security is wickedly powerful and essential for securing Java applications, there’s another Spring project that is equally…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;actually-spring-integration-may-be-my-favorite-springproject&quot;&gt;Actually, Spring Integration May Be My Favorite Spring Project&lt;/h3&gt;
&lt;p&gt;While Spring Security is wickedly powerful and essential for securing Java applications, there’s another Spring project that is equally deserving of praise and admiration: &lt;strong&gt;Spring Integration&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Spring Integration is a lightweight framework that allows developers to build complex, scalable, and extensible systems by connecting components using a messaging paradigm.&lt;/p&gt;
&lt;p&gt;If you’re wondering why this little ole’ toolkit originally built by still-active Spring veteran Mark Fisher has grown to such huge popularity, then hang on.&lt;/p&gt;
&lt;h3 id=&quot;1messaging-paradigm-withpojos&quot;&gt;1 — Messaging Paradigm with POJOs&lt;/h3&gt;
&lt;p&gt;One of the most coolest aspects of Spring Integration is its messaging paradigm, which enables developers to connect components without having to implement any framework-specific code.&lt;/p&gt;
&lt;p&gt;No RPC. No JMS calls. No REST calls. (Well, unless you’re aching for it!)&lt;/p&gt;
&lt;p&gt;By allowing you to work with &lt;strong&gt;POJOs&lt;/strong&gt; (&lt;strong&gt;Plain Old Java Objects&lt;/strong&gt;), Spring Integration simplifies the process of building and maintaining your application’s architecture.&lt;/p&gt;
&lt;p&gt;It must be pointed out that while you CAN use POJOs all over the place, it’s ALSO possible to use Spring tech-neutral Message type.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Xm8Ut-CwaVj1371JnK-CmA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;If you dig into just about any messaging solution (HTTP, AMQP, etc.) you’ll find they ALL have this paradigm of headers and a payload.&lt;/p&gt;
&lt;p&gt;And Spring Integration codifies this as a barebones interface:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*1Bw3EYhW6RUO8BmYKmNehw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This generic container provides the means to capture both information about the task at end along with metadata to support routing, processing, TTL, and other aspects. In fact, you can do just about ANYTHING with this.&lt;/p&gt;
&lt;p&gt;And something to be aware of, is that several OTHER portfolio projects. For example, if you dig into the guts of Spring Cloud Stream, you’ll discover that it harnesses the core concept of Spring Integration messaging, and dials it up to an 11.&lt;/p&gt;
&lt;p&gt;Let go of your concept of synchronous remote calls and instead start thinking of bundling up information into messages. And think about incoming vs. outgoing messages. An incoming message could include the Work to Do while the outgoing message can contain the results.&lt;/p&gt;
&lt;p&gt;Who is bringing the inputs, and who is consuming the outputs is not necessary to know by the worker.&lt;/p&gt;
&lt;p&gt;This messaging paradigm promotes loose coupling between components and enables you to focus on implementing your application’s core functionality, rather than getting bogged down in the intricacies of integrating various components. As a result, Spring Integration facilitates the creation of incredibly maintainable, testable, and scalable applications. (Say that three times fast!)&lt;/p&gt;
&lt;p&gt;But that is not all…&lt;/p&gt;
&lt;h3 id=&quot;2support-for-multiple-protocols&quot;&gt;2 — Support for Multiple Protocols&lt;/h3&gt;
&lt;p&gt;Spring Integration offers support for a wide array of communication protocols, including FTP, JMS, HTTP, STOMP, SOAP, REST, RSocket and even email.&lt;/p&gt;
&lt;p&gt;And by no means is this list exhaustive.&lt;/p&gt;
&lt;p&gt;This extensive support makes it possible to “glue” together disparate systems in a powerful and flexible way.&lt;/p&gt;
&lt;p&gt;You can easily consume data from an HTTP endpoint, route it through your processor, transform the data into a finished product, and publish it on STOMP channel for someone’s WebSocket to consume.&lt;/p&gt;
&lt;p&gt;This arguably the real charm of Spring Integration. We’ve all done web apps. But the real challenge comes when the system architect waltzes into our office and pulls out a giant diagram showing all the components we need to talk to each other.&lt;/p&gt;
&lt;p&gt;When you are just thinking about web calls and what not, this looks intimidating.&lt;/p&gt;
&lt;p&gt;But when you put Spring Integration into your application, that diagram looks like a design document! That’s because one of Spring Integration’s building blocks is the MessageChannel:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*1IESFJQDP3IMtMIozbE2Ew.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Every Producer and every Consumer can either be one of YOUR components…or it could be another system as mentioned at the beginning of this section.&lt;/p&gt;
&lt;p&gt;You can either setup a gateway to that remote endpoint, or simply hook in to one of YOUR custom components.&lt;/p&gt;
&lt;p&gt;It’s this unified framework a la Spring Integration that enables you to build robust integration solutions that can bridge the gap between different systems and technologies. This capability is particularly valuable in complex, heterogeneous environments where multiple systems need to communicate with one another.&lt;/p&gt;
&lt;p&gt;Speaking of learning about Spring, check out the sponsor of this article:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*6C3UryuuSs4070z7.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Do you want to build a Java app without wasting time?&lt;/p&gt;
&lt;p&gt;Do you need to create a web layer backed by a powerful yet intuitive data layer?&lt;/p&gt;
&lt;p&gt;Do you want to protect your users with the most up-to-date and widely used security tools?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/71j2&quot;&gt;&lt;em&gt;&lt;strong&gt;Learning Spring Boot 3.0 3rd Edition&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; will show you the way. Loaded with top-notch content and written by yours truly, this is the &lt;em&gt;&lt;strong&gt;only&lt;/strong&gt;&lt;/em&gt; book on Spring Boot 3.0 on the market written by a member of Spring team!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/71j2&quot;&gt;&lt;em&gt;&lt;strong&gt;Check it out!&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3enterprise-integration-patterns&quot;&gt;3 — Enterprise Integration Patterns&lt;/h3&gt;
&lt;p&gt;Spring Integration is originated as an implementation of (most of) the patterns found in &lt;a href=&quot;https://trnq.st/4oal&quot;&gt;&lt;em&gt;&lt;strong&gt;Enterprise Integration Patterns&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; (by Hohpe and Woolf). This books contains a collection of common integration problems combined with their solutions. These patterns enable developers to tackle non-linear problems by breaking them down into smaller, more manageable pieces.&lt;/p&gt;
&lt;p&gt;Some of the key patterns included in Spring Integration include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Channels&lt;/li&gt;
&lt;li&gt;Aggregators&lt;/li&gt;
&lt;li&gt;Filters&lt;/li&gt;
&lt;li&gt;Transformers&lt;/li&gt;
&lt;li&gt;Control Buses&lt;/li&gt;
&lt;li&gt;Gateways&lt;/li&gt;
&lt;li&gt;Endpoints&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By incorporating these patterns, Spring Integration allows you to build flexible and modular integration flows. What’s even better, this modular approach is a lot easier to adapt to the changes we are ALL familiar with.&lt;/p&gt;
&lt;p&gt;You can design your best solution, but when the customer comes back and indicates they need a change in the overall flow, you may not even have to alter the components themselves…just how they are chained together.&lt;/p&gt;
&lt;p&gt;Of course, you can tune components as well. Sometime all you’ll need is some extra metadata passed along in the headers, allowing different conditions to be passed along.&lt;/p&gt;
&lt;p&gt;It really makes it simply to think on a higher level WHAT each component does and HOW they are all orchestrated with each other.&lt;/p&gt;
&lt;p&gt;This approach not only simplifies the development process but also makes it easier to maintain and evolve solutions over time.&lt;/p&gt;
&lt;h3 id=&quot;4embracing-simplicity&quot;&gt;4 — Embracing Simplicity&lt;/h3&gt;
&lt;p&gt;The power of Spring’s dependency injection framework is another reason why Spring Integration has really charmed me.&lt;/p&gt;
&lt;p&gt;By leveraging dependency injection, you can write clean, modular, and testable code without having to extend interfaces or implement framework-specific classes. Heck, you can define YOUR OWN base interfaces if there is something consistent you want across your code base.&lt;/p&gt;
&lt;p&gt;Spring Integration also enjoys the benefits of Spring Boot in that using spring-boot-starter-integration will activate the core aspects of Spring Integration.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you throw in spring-integration-jmx, then a plethora of messaging metrics will automatically be collected across all your flows and published to JMX endpoints.&lt;/li&gt;
&lt;li&gt;spring-integration-jdbc provides the means to use an underlying JDBC data store as the messaging mechanism.&lt;/li&gt;
&lt;li&gt;spring-integration-amqp makes it possible to use RabbitMQ or any other AMQP-compliant broker as the primary mechanism to send messages between components&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could go on and on, but frankly, there’s too many options! Yikes!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*H4FXdkAJmnMkqJrDbGceKA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This list should give you a hint of EXACTLY how much power Spring Integration has to offer.&lt;/p&gt;
&lt;p&gt;When it comes to building powerful, flexible, and extensible integration solutions, Spring Integration may very well be my favorite Spring project.&lt;/p&gt;
&lt;p&gt;Your ability to build complex business logic flows that serve your customers’ needs while keeping your application’s architecture clean, modular, and scalable its a real sizzler in my book. If you haven’t yet explored the capabilities of Spring Integration, I highly recommend giving it a try — it just might become your favorite Spring project too.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I show you how to use Spring Boot to build an OAuth 2 application…and harvest YouTube data from Google!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="480" height="408" medium="image" url="https://www.procoder.io//_astro/1_Xm8Ut-CwaVj1371JnK-CmA.CoE5Rt-5.png"/></item><item><title>Why Spring Security May Be My Favorite Spring Project</title><link>https://www.procoder.io/articles/2023/2023-03-27_why-spring-security-may-be-my-favorite-spring-project-e0131ae1bb68</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-03-27_why-spring-security-may-be-my-favorite-spring-project-e0131ae1bb68</guid><description>Spring Security is a powerful, flexible, and extensible security framework for Java applications that is part of the larger Spring…</description><pubDate>Mon, 27 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;why-spring-security-may-be-my-favorite-spring-project&quot;&gt;Why Spring Security May Be My Favorite Spring Project&lt;/h1&gt;
&lt;p&gt;Spring Security is a powerful, flexible, and extensible security framework for Java applications that is part of the larger Spring…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-spring-security-may-be-my-favorite-springproject&quot;&gt;Why Spring Security May Be My Favorite Spring Project&lt;/h3&gt;
&lt;p&gt;Spring Security is a powerful, flexible, and extensible security framework for Java applications that is part of the larger Spring ecosystem.&lt;/p&gt;
&lt;p&gt;It is my go-to solution for securing Java-based applications, and I will share with you the reasons it JUST MIGHT be my favorite Spring project.&lt;/p&gt;
&lt;h3 id=&quot;1sensibledefaults&quot;&gt;1 — Sensible Defaults&lt;/h3&gt;
&lt;p&gt;One of the key reasons why Spring Security stands out is its sensible default configurations. The framework is designed to ensure that your app is protected against a wide range of security threats. And one thing I’ve learned from listening to Rob Winch’s many security talks (lead for Spring Security) is that I don’t know 1% of what this guy knows.&lt;/p&gt;
&lt;p&gt;In fact, there’s a common expression amongst security geeks:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don’t implement security on your own.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You and I, mere mortals in application development, don’t grok enough to guard against the many vectors of attacks. We NEED toolkits like Spring Security to apply good, standardized protections.&lt;/p&gt;
&lt;p&gt;For example, if you create a Spring MVC application and hook up a templating engine like Thymeleaf, Spring Security will insert additional HTML directives that are aimed at protecting you. The simplest being that the browser is instructing, when logged-in users are accessing the system, to not hold into cached assets.&lt;/p&gt;
&lt;p&gt;Essentially, when users log out, the browser shouldn’t be holding on to what that user accessed in the sense of images, JavaScript, or HTML. Any of this could be used to gain insight and attack the system. When a user logs out, the browser needs to REALLY log them out.&lt;/p&gt;
&lt;p&gt;Betcha didn’t even KNOW that one. Well gear up…there a whole bunch of actions just like that that Spring Security stuffs into web pages to ALSO protect you.&lt;/p&gt;
&lt;p&gt;Simply put, neither you nor I have the chops to understand all these attack vectors. But Spring Security DOES. Do you know about the following?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CSRF?&lt;/li&gt;
&lt;li&gt;Session Fixation?&lt;/li&gt;
&lt;li&gt;Clickjacking?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even if you’ve HEARD of them, could you explain them in detail to your manager?&lt;/p&gt;
&lt;p&gt;Integrate Spring Security into your application and you already have a strong foundation for a secure application without needing to be an expert in security.&lt;/p&gt;
&lt;h3 id=&quot;2customizable-user-sources-and-accessrules&quot;&gt;2 — Customizable User Sources and Access Rules&lt;/h3&gt;
&lt;p&gt;Spring Security makes it easy to integrate custom user sources and define access rules for your application. It provides a straightforward and intuitive way to configure how users are authenticated and authorized, allowing developers to quickly implement their desired security policies.&lt;/p&gt;
&lt;p&gt;How easily can you define a user source? Check out the code below:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*jJBTBK5d2fBWA34o1AEwtQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;All you have to do is define a &lt;strong&gt;UserDetailsService&lt;/strong&gt; bean, just like that, and Spring Security will pick it up through the magic of &lt;em&gt;Dependency Injection&lt;/em&gt;. In this scenario (courtesy of &lt;em&gt;&lt;strong&gt;Learning Spring Boot 3.0 3rd Edition’s 4th Chapter code&lt;/strong&gt;&lt;/em&gt;), by leveraging a Spring Data repository.&lt;/p&gt;
&lt;p&gt;I won’t delve into the details of the repository, but essentially, by using a simple relational database, you can easily store your users. And an accessor like this grants Spring Security the ability to leverage it.&lt;/p&gt;
&lt;p&gt;You can easily hook in other user sources such as LDAP directories, or other third-party identity providers. Spring Security provides easy-to-implement interfaces (UserDetailsService) where you can reach into any identity provider’s API and seamlessly link them.&lt;/p&gt;
&lt;p&gt;This flexibility ensures that your application can easily adapt to your organization’s specific security requirements and infrastructure.&lt;/p&gt;
&lt;p&gt;Speaking of learning Spring Boot 3.0, check out the sponsor of this article:&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*onj32Q_vwCRub1wC0ws3BA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Do you want to build a Java app without wasting time?&lt;/p&gt;
&lt;p&gt;Do you need to create a web layer backed by a powerful yet intuitive data layer?&lt;/p&gt;
&lt;p&gt;Do you want to protect your users with the most up-to-date and widely used security tools?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/71j2&quot;&gt;&lt;em&gt;&lt;strong&gt;Learning Spring Boot 3.0 3rd Edition&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; will show you the way. Loaded with top-notch content and written by yours truly, this is the &lt;em&gt;&lt;strong&gt;only&lt;/strong&gt;&lt;/em&gt; book on Spring Boot 3.0 on the market written by a member of Spring team!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/71j2&quot;&gt;&lt;em&gt;&lt;strong&gt;Check it out!&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3extensible-authentication-and-authorization&quot;&gt;3 — Extensible Authentication and Authorization&lt;/h3&gt;
&lt;p&gt;The extensible architecture of Spring Security enables developers to use a variety of authentication and authorization mechanisms.&lt;/p&gt;
&lt;p&gt;Yes, username and password authentication are THE MOST POPULAR solutions on the planet.&lt;/p&gt;
&lt;p&gt;Yes, OAuth 2 has risen in ridiculous popularity.&lt;/p&gt;
&lt;p&gt;Nevertheless, I’ve spoken to enough people to understand that almost EVERY SINGLE SYSTEM developers have to deal with are slightly…different.&lt;/p&gt;
&lt;p&gt;Whether you have to deal with X.509 certificates, Kerberos, or LDAP, Spring Security can help. Regardless of your organization’s preferred security standard, you can easily integrate Spring Security into your application.&lt;/p&gt;
&lt;p&gt;Furthermore, the framework’s extensibility ensures that, as new security standards emerge, Spring Security can adapt and incorporate them, providing you with that little thing we in the industry like to call &lt;em&gt;future-proof&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;4custom-extensions&quot;&gt;4 — Custom Extensions&lt;/h3&gt;
&lt;p&gt;There is a slim chance that YOUR system has some unique never-before seen security hook. And Spring Security isn’t ready to help you.&lt;/p&gt;
&lt;p&gt;Except…it is.&lt;/p&gt;
&lt;p&gt;You see, Spring Security’s architecture is modular enough that you can code your own extension. We’ve also seen the ability to look up user data earlier through UserDetailsService.&lt;/p&gt;
&lt;p&gt;To implement your custom authorization hook, all you must do is implement Spring Security’s &lt;strong&gt;AuthorizationManager&lt;/strong&gt;. This API only requires that you it’s single &lt;strong&gt;check()&lt;/strong&gt; method. This gives you the chance to tie in to your new fangled authorization manager.&lt;/p&gt;
&lt;p&gt;Once done, you are ready to go!&lt;/p&gt;
&lt;p&gt;But that’s not the ONLY thing that makes Spring Security my favorite Spring portfolio project. Keep reading…&lt;/p&gt;
&lt;h3 id=&quot;5integration-with-templating-engines&quot;&gt;5 — Integration with Templating Engines&lt;/h3&gt;
&lt;p&gt;Spring Security integrates seamlessly with popular templating engines like Thymeleaf, providing developers with an easy way to secure various portions of their web applications.&lt;/p&gt;
&lt;p&gt;Thymeleaf, for example, comes with built-in Spring Security hooks that enable you to apply sophisticated security features to your web pages. Just check out the fragment below:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*1w3JV3FphphWz_OX2hSl1w.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;By leveraging hooks like this, it becomes mind-numbingly simply to show various fragments of HTML on the page based upon the current user’s roles and access.&lt;/p&gt;
&lt;p&gt;It becomes much simpler to imagine a read-only version vs. a updatable version of a web page. Buttons that only ADMINs should see can exist. All sorts of goodies.&lt;/p&gt;
&lt;p&gt;This ensures that sensitive information is only accessible to authorized users, further enhancing the security of your application. When your manager asks you to “do this”, it becomes easy to meet.&lt;/p&gt;
&lt;p&gt;While I’ve been a fan of Mustache’s simplicity as a templating engine, and Spring Boot’s keen support for it, any moderately complex system that has multiple security roles, would push me quickly toward Thymeleaf as the templating engine of choice.&lt;/p&gt;
&lt;h3 id=&quot;6spring-boot-compatibility&quot;&gt;6 — Spring Boot Compatibility&lt;/h3&gt;
&lt;p&gt;Spring Boot combined with Spring Security makes it easy to secure any type of Java application, be it web apps built on templates, JSON APIs, business-to-business systems, and SOAP-based services.&lt;/p&gt;
&lt;p&gt;This allows us to quickly and easily add security features to our applications, regardless of the app’s architectural style. Whether we’re building a simple web application or a complex, multi-tiered system, Spring Security and Spring Boot can work together to provide a secure foundation for your project.&lt;/p&gt;
&lt;p&gt;That’s why it’s easy for me to that Spring Security quickly become my favorite Spring project. In fact, long ago, I met the founder of Spring Security (Acegi Security at the time), Ben Alex. A shrewd coder, Spring Security was probably the first Spring project whose code I read top-to-bottom.&lt;/p&gt;
&lt;p&gt;(Yours truly even implement a Python-based variant called Spring Python with a security module heavily built out of Spring Security’s architecture!)&lt;/p&gt;
&lt;p&gt;And over its entire lifetime, Spring Security has been built in the open, by some of the sharpest security experts in the field.&lt;/p&gt;
&lt;p&gt;If you’re looking to secure your Java application, I highly recommend giving Spring Security a try. Its combination of powerful features and ease of use make it an invaluable tool for developers seeking to protect their applications while focusing on delivering their core functionalities.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I go into details about the pros and cons of JDBC vs. JPA.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="183" medium="image" url="https://www.procoder.io//_astro/1_jJBTBK5d2fBWA34o1AEwtQ.DsbQeLW2.png"/></item><item><title>Are test fixtures worth it in your automated testing strategy?</title><link>https://www.procoder.io/articles/2023/2023-03-12_are-test-fixtures-worth-it-in-your-automated-testing-strategy--efd24d44d37d</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-03-12_are-test-fixtures-worth-it-in-your-automated-testing-strategy--efd24d44d37d</guid><description>Building automated tests for green field projects is a breeze.</description><pubDate>Sun, 12 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;are-test-fixtures-worth-it-in-your-automated-testing-strategy&quot;&gt;Are test fixtures worth it in your automated testing strategy?&lt;/h1&gt;
&lt;p&gt;Building automated tests for green field projects is a breeze.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;are-test-fixtures-worth-it-in-your-automated-testing-strategy-1&quot;&gt;Are test fixtures worth it in your automated testing strategy?&lt;/h3&gt;
&lt;p&gt;Building automated tests for green field projects is a breeze.&lt;/p&gt;
&lt;p&gt;Or at least…it’s &lt;strong&gt;not as hard&lt;/strong&gt; as taking code written by someone &lt;em&gt;not even on the team anymore&lt;/em&gt;, and attempting to test it.&lt;/p&gt;
&lt;p&gt;Legacy systems can make you sweat. Raise your hand if you know EXACTLY what I’m talking about. (And raise &lt;em&gt;&lt;strong&gt;two hands&lt;/strong&gt;&lt;/em&gt; if that part of the system gives you nightmares from time to time!)&lt;/p&gt;
&lt;p&gt;Have you invested any time in coding &lt;strong&gt;test fixtures&lt;/strong&gt; to automate your tests? Or do you work at one of those shops that STILL have a 27-page test manual that has you CLICKING THROUGH WEB PAGES to verify your code?&lt;/p&gt;
&lt;p&gt;As a pro coder, it’s &lt;em&gt;imperative&lt;/em&gt; that you invest in building &lt;strong&gt;test fixtures&lt;/strong&gt; to improve the efficiency of your testing process.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*HkFHinqCB74i53A5saY9_w.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;What is a test fixture?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s a code construct that provides a fixed environment for testing. It includes everything required for a particular test, such as a setup routine, test data, and sometimes utilities methods to help manage it all. It’s the foundation upon which you build some, if not all, of your automated tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One more thing to build in order to engage with automated testing? Yikes!&lt;/p&gt;
&lt;p&gt;Yes, it’s true that building test fixtures for legacy systems can be time-consuming. But it’s a valuable investment that will eventually pay off.&lt;/p&gt;
&lt;p&gt;For instance, think of a system that scans electronic invoices and stores the results in a database. To automate testing for a system like that, a suitable test fixture might do something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cleans out the appropriate database tables.&lt;/li&gt;
&lt;li&gt;Creates a new database schema that avoids collisions with other developers.&lt;/li&gt;
&lt;li&gt;Stages the test file in a specific location so that the parser can find it.&lt;/li&gt;
&lt;li&gt;Invokes the system.&lt;/li&gt;
&lt;li&gt;Waits (fixed time, or looks for some signal).&lt;/li&gt;
&lt;li&gt;Reads the final results from the database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(BTW, this is EXACTLY one type of test fixture I built at my previous job, before joining the Spring team. It was quite painful to build.)&lt;/p&gt;
&lt;p&gt;What worse is that more complex systems may require even MORE steps to properly handle a test run!&lt;/p&gt;
&lt;p&gt;Just to be clear, my example above wasn’t about &lt;em&gt;&lt;strong&gt;setting up databases&lt;/strong&gt;&lt;/em&gt;. Instead, it’s about the fact that sometimes we have to write some extra machinery to make the systems we work with do our bidding in automated test scenarios.&lt;/p&gt;
&lt;p&gt;If your system interacts with an LDAP server, for example, you may need to code a fixture that cleans out the directory structure and loads it up with test data, and then handles cleanup after the test is complete.&lt;/p&gt;
&lt;p&gt;Writing any such test fixture can be quite daunting, but the investment will payoff as you write more and more test cases.&lt;/p&gt;
&lt;p&gt;It will sharpen your skill set as a pro coder. (BTW don’t forget to update your LinkedIn profile!)&lt;/p&gt;
&lt;p&gt;Building fixtures like the one above (or that LDAP one) may not seem like the fastest or most efficient way to test your system. But investing the time to build them empowers you to write automated tests.&lt;/p&gt;
&lt;p&gt;And who knows?&lt;/p&gt;
&lt;p&gt;Maybe with enough tests, enough time over target, and enough accumulated awareness of your own system, you’ll eventually be able to you to refactor your code to totally decouple it from the database or LDAP server?&lt;/p&gt;
&lt;p&gt;Investing time in test fixtures is a valuable investment for automated testing. It’s the foundation upon which you build your tests, and it pays off in the long run by improving your efficiency and sharpening your skill set as a pro coder.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I show you exactly what you need to do to land that dream job!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_HkFHinqCB74i53A5saY9_w.BbhPJf-x.jpeg"/></item><item><title>Why Coverage Isn’t Everything: Rethinking Your Testing Approach</title><link>https://www.procoder.io/articles/2023/2023-03-05_why-coverage-isn-t-everything--rethinking-your-testing-approach-a0da98846418</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-03-05_why-coverage-isn-t-everything--rethinking-your-testing-approach-a0da98846418</guid><description>Do you take pride in high coverage scores? Do you compare coverage percentages with colleagues to see who is doing better?</description><pubDate>Sun, 05 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;why-coverage-isnt-everything-rethinking-your-testing-approach&quot;&gt;Why Coverage Isn’t Everything: Rethinking Your Testing Approach&lt;/h1&gt;
&lt;p&gt;Do you take pride in high coverage scores? Do you compare coverage percentages with colleagues to see who is doing better?&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-coverage-isnt-everything-rethinking-your-testingapproach&quot;&gt;Why Coverage Isn’t Everything: Rethinking Your Testing Approach&lt;/h3&gt;
&lt;p&gt;Do you take pride in high coverage scores? Do you compare coverage percentages with colleagues to see who is doing better?&lt;/p&gt;
&lt;p&gt;This is probably wrong.&lt;/p&gt;
&lt;p&gt;Unequivocally, undeniably, ecumenically wrong.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*iZXK7YMgtfOM7Gnn4-KBeQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And probably time to rethink your approach.&lt;/p&gt;
&lt;p&gt;Coverage reports are useful, but they aren’t everything. The goal of testing is not just to have high coverage scores, but to ensure that the code works as expected in real-world scenarios.&lt;/p&gt;
&lt;p&gt;What does this mean exactly?&lt;/p&gt;
&lt;p&gt;Those that get &lt;em&gt;over&lt;/em&gt;focused on coverage reports are probably sacrificing test quality to achieve those numbers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And sacrificing test quality for the sake of coverage is a recipe for disaster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Coverage reports can give us insights into what is being exercised and what is not, but they don’t tell the whole story. Simply because a line of code is being exercised doesn’t mean it is doing what it’s supposed to do.&lt;/p&gt;
&lt;p&gt;How can we solve this?&lt;/p&gt;
&lt;p&gt;We need not only generate the coverage reports, but must also &lt;em&gt;&lt;strong&gt;analyze&lt;/strong&gt;&lt;/em&gt; &lt;em&gt;&lt;strong&gt;what they mean&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We need to analyze what is being covered and how well it is being tested. For instance, if a module has 70% coverage, it doesn’t mean that the remaining 30% is unimportant or that we need to write more tests that specifically target the uncovered parts.&lt;/p&gt;
&lt;p&gt;Think of it like this…there are two schools of thought on how to approach this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first approach is to write new tests that target the uncovered parts &lt;strong&gt;without overlapping&lt;/strong&gt; the original 70%. That’s because if we end up testing code that has already been covered in another test, we’re wasting time and resources!&lt;/li&gt;
&lt;li&gt;The second approach is to write new tests that target scenarios that the code is expected to handle but haven’t been tackled yet. What was not covered should give us clues about &lt;strong&gt;what scenarios haven’t been tested yet&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second approach is the better one. And yes, I wrote that in a rather leading fashion. But you get my point, yeah?&lt;/p&gt;
&lt;p&gt;It’s important to write tests that are based on real-world scenarios rather than simply trying to increase coverage percentages. If we lean too much into mocking, stubbing, and other parlor tricks to exercise the uncovered code, we risk writing brittle test cases that will come back to bite us in the long run.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New tests could be a lot more brittle when not based on sound scenarios.&lt;/li&gt;
&lt;li&gt;A major change to any of our algorithms could require us to totally rewrite these tests.&lt;/li&gt;
&lt;li&gt;With mocking, it’s possible to mock the “real” system away and ultimately be testing the mock itself!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We should focus on improving the quality of our tests, covering more scenarios, and removing code that is no longer supported. Increasing coverage for the sake of coverage doesn’t lend itself to improving the quality of our system.&lt;/p&gt;
&lt;p&gt;So, next time you are tempted to celebrate high coverage scores or compare coverage percentages between projects without any context, take a step back and reflect on your motives.&lt;/p&gt;
&lt;p&gt;Are you doing it to improve the quality of your system…or just for the sake of coverage?&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*HN1RO_tcI5al8ionba0nxA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Remember, the goal of testing is not just to have high coverage scores, but to ensure the system is fully armed and operational!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where we learn how to test various security aspects of a Spring Boot application!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_iZXK7YMgtfOM7Gnn4-KBeQ.D9PETthh.jpeg"/></item><item><title>Testing Code: From Spaghetti to Safety</title><link>https://www.procoder.io/articles/2023/2023-02-26_testing-code--from-spaghetti-to-safety-5b6d4d96bb4f</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-02-26_testing-code--from-spaghetti-to-safety-5b6d4d96bb4f</guid><description>The world of software development is constantly evolving. New tools, techniques, and technologies are being introduced every day, and it…</description><pubDate>Sun, 26 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;testing-code-from-spaghetti-to-safety&quot;&gt;Testing Code: From Spaghetti to Safety&lt;/h1&gt;
&lt;p&gt;The world of software development is constantly evolving. New tools, techniques, and technologies are being introduced every day, and it…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;testing-code-from-spaghetti-tosafety&quot;&gt;Testing Code: From Spaghetti to Safety&lt;/h3&gt;
&lt;p&gt;The world of software development is constantly evolving. New tools, techniques, and technologies are being introduced every day, and it can be challenging to keep up with the latest trends.&lt;/p&gt;
&lt;p&gt;However, there are some issues that never seem to go away, no matter how much progress we make: legacy code.&lt;/p&gt;
&lt;p&gt;Yuck.&lt;/p&gt;
&lt;p&gt;Can I get a high-five if you’ve ever dealt with legacy code?&lt;/p&gt;
&lt;p&gt;Legacy code is something we’ve all had to had to deal with at one time or another. The code may be poorly documented, contain chunks of commented-out code, or have no comments at all. Often, there are few automated tests, making it challenging to know if the code is working as intended.&lt;/p&gt;
&lt;p&gt;So, what do you do when you find yourself in this situation?&lt;/p&gt;
&lt;p&gt;Easy: Start testing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What??! That’s your whole thing? “Start testing?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let me clarify. It’s easy WHAT you must do and that’s to start testing. Before you alter any features, if possible, if you can hold off the minions of management and community and before you “fix” a single thing and first write a test case, that would be perfect. (I understand if you can’t.)&lt;/p&gt;
&lt;p&gt;But deciding to “start testing” will not be easy to CARRY OUT. Believe me, I know.&lt;/p&gt;
&lt;p&gt;In fact, it will be very VERY hard. So continue reading if you want to some tips that at least give you a decent shot and moving that boulder up the hill.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*qS8l1dFbTjUkeJ0BzyPIcw.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;To start off, don’t get caught up in the purity of total isolation or worry about obscure test methods. Just start writing tests. It doesn’t matter if you use the right name or if you’re writing a unit test, a thread test, or an integration test. What matters is that you’re &lt;em&gt;writing a test&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;For example, consider a system I once dealt with that parsed electronic invoices and stored the parsed results in a database. The parsed results weren’t handed back through any API, so I had to write a test that checked the results &lt;strong&gt;in the database&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Yes, that’s ugly as all get out. It’s often &lt;em&gt;un-recommended&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And sometimes…it’s EXACTLY what you must do.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I started my test case by programmatically emptying all the tables relevant to the application (test database NOT production!)&lt;/li&gt;
&lt;li&gt;Then Ifound a user who had one of these electronic invoices and got a copy of it.&lt;/li&gt;
&lt;li&gt;I added code to the test that invoked the top-level API to ingest that file.&lt;/li&gt;
&lt;li&gt;Finally added some more code that pulled data out of the database and checked the results.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Whew! This took me a couple weeks to carry out these steps, but I did it. And it worked. And the test case took 2–5 minutes to run.&lt;/p&gt;
&lt;p&gt;That was no unit test, but it was better than no test at all. And it was my first step forward. My first toward taming this beast.&lt;/p&gt;
&lt;p&gt;And so I continued like this, one step at a time. Now here are some additional things to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Since the database is where you assert results, you need to have a cleaned-out version before every run of your test. This is going to require coordination if other developers are using some of the same tables. You may need your schema allocated to you, so you can empty tables at will.&lt;/li&gt;
&lt;li&gt;It’s important to recognize that if you try to jump immediately into “proper” unit-level testing, you’ll QUICKLY discover that refactoring is required to make the various modules support you. With little or no test suite safety net, the risk becomes incredibly HIGH. Does that make you nervous? Well it &lt;em&gt;&lt;strong&gt;should&lt;/strong&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In fact, if you try to stick to textbook unit testing, you’ll probably give up and deem automated testing as an impossibility.&lt;/p&gt;
&lt;p&gt;Instead, take the first step and write the expensive, end-to-end automated test to build the first link in a chain. That test may take a long time to run and not be very comprehensive in what you can assert, but it’s a start.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*0rB8-xXYOGsfdFO8pLlp-Q.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Like I said, the concept of “just write a test” may sound simple, but the work is going to be hard. You’ll be forced to crawl through lots of APIs and find out exactly how they work. You probably won’t be handed lots of intermediate results to assert.&lt;/p&gt;
&lt;p&gt;And just to be clear, understanding the API at first is more likely to just understand what is going where so you can track down the final destination of your data.&lt;/p&gt;
&lt;p&gt;Now as you continue to write more tests, you will begin to build up a safety net. And the more tests you write, the easier it will be to refactor chunks of code. You’ll actually have an epiphany of realizing “I know how that part works! And I know how to change it!”&lt;/p&gt;
&lt;p&gt;And…you’ll then have the suite of tests to support you as you make that change.&lt;/p&gt;
&lt;p&gt;You will have built up confidence and accumulated a working knowledge of how the app does its thing.&lt;/p&gt;
&lt;p&gt;So when you set out and the process feels slow, never let anyone tell you that you’re wasting your time building a long-running test case. An automated test suite that takes an hour to run and is exercised at least once a day will instill more confidence than clicking through the app’s web pages manually.&lt;/p&gt;
&lt;p&gt;Something is better than nothing.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I give you some of the most important tips you need to know to become a pro coder.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="534" medium="image" url="https://www.procoder.io//_astro/1_qS8l1dFbTjUkeJ0BzyPIcw.BxcqzQtn.jpeg"/></item><item><title>4 Ways to Energize your Software Team</title><link>https://www.procoder.io/articles/2023/2023-02-18_4-ways-to-energize-your-software-team-4628015e3703</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-02-18_4-ways-to-energize-your-software-team-4628015e3703</guid><description>This past week, the Spring Data team had a face-to-face meeting. And it was fan-TASTIC! I had entered the meeting with sort of an…</description><pubDate>Sat, 18 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;4-ways-to-energize-your-software-team&quot;&gt;4 Ways to Energize your Software Team&lt;/h1&gt;
&lt;p&gt;This past week, the Spring Data team had a face-to-face meeting. And it was fan-TASTIC! I had entered the meeting with sort of an…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-ways-to-energize-your-softwareteam&quot;&gt;4 Ways to Energize your Software Team&lt;/h3&gt;
&lt;p&gt;This past week, the Spring Data team had a face-to-face meeting. And it was fan-TASTIC! I had entered the meeting with sort of an average-to-below average
feeling and left feeling energized, excited, and with a stronger sense of purpose than I had felt in a while.&lt;/p&gt;
&lt;p&gt;So what happened? Did our team leader tell jokes? Did we spend the whole time telling war stories of past and present work life? Did our team manager promise us
a rich bounty of double bonus pay and equity grants?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;We did something very different. We connected on a HUMAN level. And in the rest of this article, I’ll share with you some of the tactics we used to do that.&lt;/p&gt;
&lt;h3 id=&quot;1put-the-technology-away&quot;&gt;1 — Put the technology away&lt;/h3&gt;
&lt;p&gt;For a software development team distributed around the world, we sure love our tech. Zoom chats, Slack channels, M1 Macs on standing desks, and cloud-based SaaS
tools.&lt;/p&gt;
&lt;p&gt;All of it is incredibly empowering from a tools perspective. And I can do my job from literally anywhere I can find an internet connection.&lt;/p&gt;
&lt;p&gt;And for this week, we set it all aside. Instead, we used a whiteboard, giant sticky pin-up sheets with cute doodles (courtesy of our team leader!), and
back-and-forth talking.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*pv0oq-eY9I2hen6g3yQclQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Tech is cool, but sometimes you need to get your head out of all that and connect with
your fellow humans. And human interaction is one of those things that when given the opportunity, you should spend the time to invest in. The lot of us (United
States, United Kingdom, Germany, and Austria) were all in one room for just a week.&lt;/p&gt;
&lt;p&gt;Don’t squander this opportunity by spending it all doing coding and ticket management.&lt;/p&gt;
&lt;p&gt;We spent a LOT of the time voicing thoughts and feelings. But what, exactly, did we say? Keep reading to find out!&lt;/p&gt;
&lt;h3 id=&quot;2take-the-time-for-a-retrospective&quot;&gt;2 — Take the time for a retrospective&lt;/h3&gt;
&lt;p&gt;Once-a-month we try to have an online retrospective. This is a change to reflect on things done in the past and ponder what’s coming. Online we usually confine
it to an hour, but during our face-to-face meeting, we ended up spending two hours.&lt;/p&gt;
&lt;p&gt;What, exactly, is a retrospective? Simply put, everything writes down on sticky cards topics which they either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I’m glad that…&lt;/li&gt;
&lt;li&gt;I wonder about…&lt;/li&gt;
&lt;li&gt;It wasn’t so great…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also +1 someone else’s card. Basically, this is a chance to vent about things, pose questions, and also express the stuff that excites you. Then, each
card is discussed by the team.&lt;/p&gt;
&lt;p&gt;Typically, you give each card five minutes. In some cases, if there’s a lot to dig out, you can keep bumping the timer up. (Our team leader had a KickStarter
clock that had things like 1 minute, 5 minutes, 10 minutes, and even 25 minute pomodora-style timers!)&lt;/p&gt;
&lt;p&gt;The point is to get all those concerns out there. Not to solve. Sometimes, simply espousing concerns can rob them of their energy. Other things can result in
action items gathered to deal with later.&lt;/p&gt;
&lt;p&gt;This sort of self reflection is good for the team, and a 2-hour session was a GREAT way for all of us to truly get on the same page.&lt;/p&gt;
&lt;p&gt;But that wasn’t the only thing we did face-to-face!&lt;/p&gt;
&lt;h3 id=&quot;3getting-to-know-your-teammates&quot;&gt;3 — Getting to know your teammates&lt;/h3&gt;
&lt;p&gt;Another thing we did was everyone was invited to write down various aspects about themselves including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How I joined the Spring team&lt;/li&gt;
&lt;li&gt;Things that excite me&lt;/li&gt;
&lt;li&gt;Favorite movie/book/TV show&lt;/li&gt;
&lt;li&gt;Sad times&lt;/li&gt;
&lt;li&gt;Scary moments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s fun to hear all your teammates and learn how they discovered Spring and what drew them to join the team. It exposes their personal experiences, a hint of
their skills, and sometimes…the things they were frustrated with.&lt;/p&gt;
&lt;p&gt;But it’s ALSO cool discovering personal desires like TV shows and movies. These types of discoveries turn what may seem like a flat, impersonal avatar from Zoom
into a real, multi-dimensional human that is closer to yourself.&lt;/p&gt;
&lt;p&gt;You see, one thing that I learned in the midst of all this that we ALL struggle with some amount of &lt;em&gt;&lt;strong&gt;imposter syndrome&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Impostor syndrome&lt;/strong&gt; is a psychological occurrence in which an individual doubts their skills, talents, or accomplishments and has a persistent internalized
fear of being exposed as a fraud.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sharing more of yourself, including not just the “good” stuff but also the struggles and challenges, made it clear that all my teammates struggled. A lot like
me. It drew me closer and quickly dissipated whatever imposter syndrome I was feeling.&lt;/p&gt;
&lt;p&gt;One thing I was able to express to my teammates was one of my personalf ears. While I had 10+ years of experience writing SQL queries such that I can left outer
joins and correlated subqueries in my sleep. My knowledge of JPA was NOT so tall. I had, in fact, watched my teammate’s 2018 SpringOne talk on JPA and was
dumbfounded when he challenged the audience to guess how Hibernate would react in the certain situations.&lt;/p&gt;
&lt;p&gt;Yikes!&lt;/p&gt;
&lt;p&gt;Sharing that vulnerability was hard. But I’m glad that I did.&lt;/p&gt;
&lt;p&gt;At the same time, my team leader had asked me to bring a proposal for a critical issue we were facing with Spring Data JPA. I had spent the previous week
building a proof of concept and a presentation. By the end of my pitch, I had learned that I was the only one with the exact skills to implement it. And my
experience in this area allowed me to assuage all of my teams’ concerns so much that they are EXCITED to see me implement it!&lt;/p&gt;
&lt;p&gt;Imposter syndrome — gone!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*q4RZTGDBJbFubxM0SvUlpQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;4--take-time-off&quot;&gt;4 — Take time off&lt;/h3&gt;
&lt;p&gt;I can’t stress this enough. Not everything has to involve work stuff. One night, our team leader met us in the lobby of the hotel…with a bag full of Rubik’s
cubes!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*NxtbFq3xANu_iIsFNK03hg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Mark showed us the basics. Christoph threw in the towel pretty quickly. Ilaya tried
hard. John, while he seemed challenged, apparently went back to his room and conquered it!&lt;/p&gt;
&lt;p&gt;Me? I figured out how to solve the first two layers. And that was it for me.&lt;/p&gt;
&lt;p&gt;My point is that spending time together doing non-work stuff during a team meeting is constructive and prepares you for working hard together in the coming
year!&lt;/p&gt;
&lt;p&gt;Whether you have a face-to-face time with your teammates, or you are working over Zoom, these tactics can help YOU build a better bridge. Better communication,
better understanding, better support for each other. Let me know in the comments what YOU plan to do!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video
below where I share everything you need to know to conduct a code review.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY
NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="600" medium="image" url="https://www.procoder.io//_astro/1_pv0oq-eY9I2hen6g3yQclQ.CiXWlZID.jpeg"/></item><item><title>Code comments are DEAD…or ARE they??</title><link>https://www.procoder.io/articles/2023/2023-02-02_code-comments-are-dead-or-are-they---aebaf6237605</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-02-02_code-comments-are-dead-or-are-they---aebaf6237605</guid><description>We’ve all dabbled with code comments. In fact, when learning programming, it’s one of the first little things you learn.</description><pubDate>Thu, 02 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;code-comments-are-deador-are-they&quot;&gt;Code comments are DEAD…or ARE they??&lt;/h1&gt;
&lt;p&gt;We’ve all dabbled with code comments. In fact, when learning programming, it’s one of the first little things you learn.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;code-comments-are-deador-arethey&quot;&gt;Code comments are DEAD…or ARE they??&lt;/h3&gt;
&lt;p&gt;We’ve all dabbled with code comments. In fact, when learning programming, it’s one of the first little things you learn.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/**  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; * We were all shown how to add our own comments to code,   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; * perhaps on Day 1.  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; */  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class MyExample {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; public static void main(String[] args) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; System.out.println(&quot;Really cool, ehh?&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Stuff like this is something coding instructors love to show. And it’s cool, right? Write all the commentary you want about your code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How it works&lt;/li&gt;
&lt;li&gt;Why you picked this algorithm&lt;/li&gt;
&lt;li&gt;Detailed explanation about HOW that algorithm works, to help you out the NEXT time you have to read that chunk&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last one is key. Why?&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*mggauh-56OWg6f_mzf-ngA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Because our ability to read code ebbs and flows. Sometimes, when we revisit a chunk we haven’t seen for six months, getting back up to speed can be tough. A comment explaining the algorithm in HUMAN can be vital.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And this is where comments can sabotage us.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because what happens when we ALTER the code? What happens when we write a detailed explanation about how it works, but then we change it five times. And when the other person on our team makes a few tweaks of their own?&lt;/p&gt;
&lt;p&gt;And that wonderful, beautiful comment was NEVER updated.&lt;/p&gt;
&lt;p&gt;When it’s time to get up-to-speed, the comment may be worthless. It may flat out wrong. Or…it may actually be more insidious than that. What if the code had corner cases later fixed, but the comment doesn’t cover that?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is the reason the sofware development community has generally declared comments to have little redeeming value. Talk to any pro coder with more than a few years under their belt, and they’ll tell you not to sink your hopes into code comments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And such a sweeping generalization, would turn to be wrong.&lt;/p&gt;
&lt;p&gt;Comments have a vital, critical value in our code. But they must be used judiciously.&lt;/p&gt;
&lt;h3 id=&quot;licensing-andcredit&quot;&gt;Licensing and credit&lt;/h3&gt;
&lt;p&gt;Every file in your codebase should have its shorthand license in a comment at the top of the file. When people run into your code, the terms of interacting with it should be plain and clear. After all, it’s your moral duty.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*1OiYe-CeaU8CHYTblLh8sA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This is information unlikely to change despite dozens of changes. And so there is little risk of drift.&lt;/p&gt;
&lt;p&gt;But that is not all. I’m a fan of crediting people with contributions to source code. After all, Java has the @author tag. If someone contributes a patch, and don’t include their name on impacted files, I’m prone to add them to the credits with a &lt;a href=&quot;/articles/medium/2023-01-26_what-is-code-polishing-and-why-you-should-be-doing-it--bed546355417&quot;&gt;polishing commit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*g7HfVM1MTOXsKYzjp6tfHQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Yes, the list of contributors will grow over time. &lt;em&gt;But that’s okay&lt;/em&gt;. There is nothing directly tied to the code’s functionality, so again, no risk of drift.&lt;/p&gt;
&lt;p&gt;But that is not all. There are even more ways to apply comments to your code the doesn’t risk them falling out of date. Check it out below:&lt;/p&gt;
&lt;h3 id=&quot;linking-back-totickets&quot;&gt;Linking back to tickets&lt;/h3&gt;
&lt;p&gt;One of the issues in software management is the fact the use tickets to manage change. Tickets are where we usually host any conversation about a given change.&lt;/p&gt;
&lt;p&gt;So it makes sense for our code to point back to the ticket.&lt;/p&gt;
&lt;p&gt;But not in the way you’re think. Yes, I mentioned linking to the ticket when crafting your commit message, but today we’re talking about comments. And your operational code shouldn’t be cluttered with comments.&lt;/p&gt;
&lt;p&gt;Instead, you should be writing test cases that capture the various behaviors agreed to in the ticket. And those test cases can mention the ticket that brought them into existence in the comments.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*ZbDRMxU9hHQmOMhkHTmBJA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This test case links back to &lt;a href=&quot;https://jira.spring.io/browse/DATAJPA-253&quot;&gt;https://jira.spring.io/browse/DATAJPA-253&lt;/a&gt;, where all the details behind this test class (and the code it exercises) can be found.&lt;/p&gt;
&lt;p&gt;Pretty effective way to build the record between code and tickets.&lt;/p&gt;
&lt;h3 id=&quot;fundamental-concept-behind-thecode&quot;&gt;Fundamental concept behind the code&lt;/h3&gt;
&lt;p&gt;Your code may shift and adjust HOW it implements something. But WHAT it does should not. At least, not on a fundamental basis.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*pJibeUZ6lFKNTllRQeqYwQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;At the top of a Java class, you can mention the class’s overall purpose. And one thing Java is really great at are all its links, such as connecting to related classes (&lt;strong&gt;CrudRepository&lt;/strong&gt; and &lt;strong&gt;EntityManager&lt;/strong&gt;) among other things.&lt;/p&gt;
&lt;p&gt;So writing comments that describe WHAT a class or method does, its inputs &amp;#x26; outputs, and even listing WHEN a function was added to the codebase using the @since tag, you can create a very practical batch of documentation.&lt;/p&gt;
&lt;h3 id=&quot;deprecations&quot;&gt;Deprecations&lt;/h3&gt;
&lt;p&gt;One of the most vital things we need to engage in is API management. Public-facing methods and classes need to be sustained. At any time, if you need to migrate to a newer class or replacement method, you need to deploy Java’s @Depracated annotation.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*MQ6GPYc1M6wFYChKgDo_Eg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Not only do you need to flag the method (or class) itself. But the Javadoc comment is your way to signal to your community HOW to migrate away from this API that you may remove in a future release.&lt;/p&gt;
&lt;p&gt;Explaining what to use and how to use it is a splendid way to comment.&lt;/p&gt;
&lt;p&gt;These are all good ways to use comments. To give your users key information to consume, interact, and use your code. And where, exactly, the guardrails are.&lt;/p&gt;
&lt;p&gt;But trust me.&lt;/p&gt;
&lt;p&gt;The minute you start trying to explain why you are having to sort the thingamabobs and push them onto a stack of whachamadigits, you’re in trouble. Because your code will change. Quickly. Rapidly.&lt;/p&gt;
&lt;p&gt;Don’t do it. Comments like THAT are DEAD!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I dive into how to write your version-controlled commit messages and most important what to NEVER put in a commit!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_mggauh-56OWg6f_mzf-ngA.CqBCGI-E.jpeg"/></item><item><title>What is code polishing…and why YOU should be doing it!</title><link>https://www.procoder.io/articles/2023/2023-01-26_what-is-code-polishing-and-why-you-should-be-doing-it--bed546355417</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-01-26_what-is-code-polishing-and-why-you-should-be-doing-it--bed546355417</guid><description>One of the most amazing things I’ve discovered since joining the Spring team…was their affinity for polishing code. In fact, at the 2014…</description><pubDate>Thu, 26 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;what-is-code-polishingand-why-you-should-be-doing-it&quot;&gt;What is code polishing…and why YOU should be doing it!&lt;/h1&gt;
&lt;p&gt;One of the most amazing things I’ve discovered since joining the Spring team…was their affinity for polishing code. In fact, at the 2014…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-is-code-polishingand-why-you-should-be-doingit&quot;&gt;What is code polishing…and why YOU should be doing it!&lt;/h3&gt;
&lt;p&gt;One of the most amazing things I’ve discovered since joining the Spring team…was their affinity for polishing code. In fact, at the 2014 GOTO conference, Rod Johnson mentioned Juergen Holler’s “unearthly commitment to code quality”.&lt;/p&gt;
&lt;p&gt;What, exactly, is that? And by the end of this article, I hope you’ll realize not just WHAT this is…but why you should take up this mantle.&lt;/p&gt;
&lt;p&gt;In its simplest incarnation “code polishing” is when you ensure that your entire code base has a consistent, equivalent, uniform nature. Speaking of Java code, this can include things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consistent sorting of import statements&lt;/li&gt;
&lt;li&gt;If you use wildcards in import statements, expand at the same amount (Spring Data requires 11+ imports before using a wildcard)&lt;/li&gt;
&lt;li&gt;Curly braces begin and end at the same place, everywhere&lt;/li&gt;
&lt;li&gt;Wrap ALL code blocks with braces (no single-line/no braces)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s not the whole list, but you perhaps can see the value in having every Java classfile adopt this same style. Thankfully, like many of software’s challenges, there are tools to help with that. The Spring Data team uses the Adapter for Eclipse Code Formatter, a plugin that lets us read an Eclipse code formatting file and apply it inside IntelliJ. This lets us share a common set of formatting choices.&lt;/p&gt;
&lt;p&gt;If we’re all using the same formatting choices, it becomes a hotkey combo to reformat any source file we’re editing. And anytime we receive a community contribution, we can quickly apply our styling.&lt;/p&gt;
&lt;p&gt;But why do we need to do this?&lt;/p&gt;
&lt;p&gt;Because of physics.&lt;/p&gt;
&lt;p&gt;You may not know this, but one of my hobbies when I’m not slinging code is physics and advanced math. I actually find it soothing to watch a video of a college math professor hammering out an incredibly complex piece of calculus. The math fascinates me!&lt;/p&gt;
&lt;p&gt;But it doesn’t just stop there. I have become enamored with learning the math behind such complex things like General Relativity, to the point that I’ve watched hours of videos where they prove Einstein’s Field Equations, and then use them to solve complex problems.&lt;/p&gt;
&lt;p&gt;To the point at hand, one of the most amazing things discovered in the past 200+ years is entropy. This is where things essentially fall into decay. The concept is simple and elegant, yet lack of awareness for entropy can allow things to go really badly.&lt;/p&gt;
&lt;p&gt;Not paying attention to code can allow it to fall apart. If you accept contributions into your project from the community, it’s quite natural for the entire codebase to decay into an unmanageable mess.&lt;/p&gt;
&lt;p&gt;Mathematically speaking, if you don’t expend energy to move it toward order it WILL move toward chaos. In other words, you simply HAVE to budget in time to clean and polish your code, or eventually it will fall into ruin.&lt;/p&gt;
&lt;p&gt;Maybe not today. Maybe not tomorrow. But over time.&lt;/p&gt;
&lt;p&gt;Several years ago, I participated in a joint effort with Netflix, Google, and some other big shot software companies. The codebase was owned by Netflix, but a certain section of it was ours. And after having worked on the Spring team for several years, I NOTICED the lack of consistent styling in the Netflix codebase.&lt;/p&gt;
&lt;p&gt;I don’t mean to besmirch the Netflixers nor anyone else. However, on Day 1, I could see it, perceive it, and it tugged at me. Maybe that’s a bit nebulous. Nevertheless, everyday that I contributed to that codebase, it had a negative effect on me.&lt;/p&gt;
&lt;p&gt;Going back to Spring’s codebase was a breath of fresh air.&lt;/p&gt;
&lt;p&gt;Perhaps this is a personal problem, you say? Maybe. But there is something to be said for investing a little extra energy to clean things up and ensure a consistent formatting. On the Spring Data team, not only do we have the code formatting mentioned above, but we have additional rules that can’t be directly enforced by tools, so we must do them manually:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Favor default visibility (classes and methods being package-private) over “public” (which tends to be the default in IDEs)&lt;/li&gt;
&lt;li&gt;Every method, if it has two more lines of code, must include a blank line at the beginning.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We spend a fair amount of time adding double-slash (//) comments at the END of lines of code so that our code formatter will nicely line things up on our behalf!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*6xcFwzDXUepvnZROnVY5VQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;em&gt;&lt;strong&gt;(BTW, that chunk of code from a contributor was later polished to add the extra blank line above flushTestUser!)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;All of this helps A) increase readability, B) reduce cognitive overload, and C) make everything neater, tidier, and ultimately, staves off the decay of the source code.&lt;/p&gt;
&lt;p&gt;Investing extra time and making your code more consistent, more readable is a worthy investment. It’s why I chuckled on Reddit a couple weeks ago, when someone asked the following question:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*aQhzvJDn8Pfc4S0x0vpdPw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;I get it. Not everyone likes the Spring Way™. But whether or not you agree with how our framework operates, you certainly can NOT impugn us on code formatting! I reckon it’s why my check on the OP’s question got 26 upvotes!&lt;/p&gt;
&lt;p&gt;We have an expression for what happens when your code contribution to the Spring portfolio get polished. Over time, through repeated polishings, you adapt. You strive to get that contribution into a given Spring project WITHOUT NEEDING A POLISHING COMMIT. You try to buff it up yourself on the way in.&lt;/p&gt;
&lt;p&gt;You run the same tools. You squint to see it as Juergen would (or mini-Juergen a.k.a. Oliver Drotbohm). You seek to make your work impeccable.&lt;/p&gt;
&lt;p&gt;We call this “juergenization”. Because it’s ultimately YOU that is transformed. Not just your code. And then you start to do it in other places (like &lt;a href=&quot;/books/learning-spring-boot-3-0&quot;&gt;my book&lt;/a&gt;!) And the world of software development, a world that may be caught up in an exponential explosion, may have a fighting chance if we all seek to beat back the forces of entropy!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I talk about the various things you must do to carry out a code review.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="315" medium="image" url="https://www.procoder.io//_astro/1_6xcFwzDXUepvnZROnVY5VQ.C6SSGdCv.png"/></item><item><title>As we move into January of 2023, it’s time to entertain some new ideas, new ways to streamline your…</title><link>https://www.procoder.io/articles/2023/2023-01-20_as-we-move-into-january-of-2023--it-s-time-to-entertain-some-new-ideas--new-ways-to-streamline-your--e9ba634392b0</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-01-20_as-we-move-into-january-of-2023--it-s-time-to-entertain-some-new-ideas--new-ways-to-streamline-your--e9ba634392b0</guid><description>I have a Google Doc where I basically track my daily work. I paste in linked to GitHub tickets I worked on. To be clear, I write down every ticket I so much as glance at.</description><pubDate>Fri, 20 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;as-we-move-into-january-of-2023-its-time-to-entertain-some-new-ideas-new-ways-to-streamline-your&quot;&gt;As we move into January of 2023, it’s time to entertain some new ideas, new ways to streamline your…&lt;/h1&gt;
&lt;p&gt;1 — Create a worklog&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-ways-to-streamline-your-daily-codinggrind&quot;&gt;4 Ways to Streamline Your Daily Coding Grind&lt;/h3&gt;
&lt;p&gt;As we move into January of 2023, it’s time to entertain some new ideas, new ways to streamline your coding lifestyle. I’ve gathered some of the easiest-to-use tips that have helped me. Maybe they can help you as well.&lt;/p&gt;
&lt;h3 id=&quot;1create-aworklog&quot;&gt;1 — Create a worklog&lt;/h3&gt;
&lt;p&gt;I have a Google Doc where I basically track my daily work. I paste in linked to GitHub tickets I worked on. To be clear, I write down every ticket I so much as glance at.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*g_ojTh6VlXiWp_Ql67JwIA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;A day where I actually knocked out some Spring WS ticketsMaybe this sounds like a lot of EXTRA work you don’t need to take on. I get your point. I started doing this last year and it has actually helped me focus my thoughts.&lt;/p&gt;
&lt;p&gt;Some days, when I feel my focus isn’t quite there, going back and reading a couple of the previous days really jobs my memory and helps pull me into a developer mindset. Which has helped me get cracking a lot faster.&lt;/p&gt;
&lt;p&gt;So indeed, while the task itself can feel tedious at first, the payoff by committing to this adjustment to my process has been positive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;BONUS: There are many times when I feel like a couple weeks simply flew by. Being able to remember EVERYTHING I had done simply didn’t happen. But opening the worklog at the beginning of the day would refresh me memory on everything I HAD done recently. And seeing a stack of completed work at the end of the day also gave me a stronger feeling of accomplishment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I should also note that you don’t have to write reams of content by each issue. Or summarize it. This is an activity log. The actual comments on each ticket belong, well, in the ticket!&lt;/p&gt;
&lt;h3 id=&quot;2pick-out-a-30-minute-playlist-and-use-it-as-a-clock-forbreaks&quot;&gt;2 — Pick out a 30-minute playlist and use it as a clock for breaks&lt;/h3&gt;
&lt;p&gt;Something else I started doing was exercising my playlist. (Use &lt;a href=&quot;https://www.epidemicsound.com/playlist/zichxen4wuz8ik8xai8n4u656vrc0yae&quot;&gt;mine if you want a synth-heavy instrumental playlist&lt;/a&gt;!)&lt;/p&gt;
&lt;p&gt;Not only does listening to TRON-ish style music warm me up to writing code, but when the playlist is over, I know it’s time to take a break. My playlist is about 37 minutes, but you get the idea.&lt;/p&gt;
&lt;p&gt;When the playlist is done:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;stop&lt;/li&gt;
&lt;li&gt;walk around&lt;/li&gt;
&lt;li&gt;walk the dog&lt;/li&gt;
&lt;li&gt;watch a YouTube video&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A five-minute break following by another coding stint will do wonders at refreshing your mind and resetting your fatigue.&lt;/p&gt;
&lt;p&gt;Yes there are times when I play the list twice in a row. Sometimes, I’m really in the zone and don’t want to lose my groove. But twice through the playlist, and I’m stopping FOR SURE! (If you have a playlist, share it in the comments!)&lt;/p&gt;
&lt;h3 id=&quot;3permit-yourself-to-do-some-non-workthings&quot;&gt;3 — Permit yourself to do some non-work things&lt;/h3&gt;
&lt;p&gt;Something I used to feel quite guilty about was, when I would take a break from work stuff and watch some video. Whether that was a Mr. Beast video or some video where I watch a math professor solve a devilishly complex calculus problem (yes I watch them!)&lt;/p&gt;
&lt;p&gt;Either way, I felt bad doing it “on company time”. But now, with my playlist-as-the-pomodoro-method, I actually go and do ANYTHING I WANT for that short break between my coding stints.&lt;/p&gt;
&lt;p&gt;Want to watch a YT vid? Do it! Want to visit Twitter/Facebook/Reddit?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I hereby give you permission to visit your favorite site and splurge as you relax for your 5-minutes break!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s no biggie.&lt;/p&gt;
&lt;p&gt;Just don’t take a 5-minute break and let it turn into watching an entire season of &lt;em&gt;For All Mankind&lt;/em&gt;! Heh.&lt;/p&gt;
&lt;h3 id=&quot;4have-a-worksheet-to-focuson&quot;&gt;4 — Have a worksheet to focus on&lt;/h3&gt;
&lt;p&gt;A challenging thing can be when you’re ready to get cracking…but you have no sense of what to do. Having a worksheet of agreed upon tasks is the simplest way to do this.&lt;/p&gt;
&lt;p&gt;There are different ways to approach this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maintain a &lt;strong&gt;Google Worksheet&lt;/strong&gt;, where you write down every task someone asks you to do. As you complete the task, mark it off the list (vs. simply deleting)&lt;/li&gt;
&lt;li&gt;Use GitHub’s &lt;strong&gt;Project Board&lt;/strong&gt; as a way to manage the flow of tickets in your org. It’s quite easy to go in and filter down to only see YOUR tickets.&lt;/li&gt;
&lt;li&gt;Check your project’s &lt;strong&gt;issues&lt;/strong&gt; or &lt;strong&gt;pull requests&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key here is to focus on actions that move the needle. And a great way is to either be knocking out tickets/pull requests that are getting opened on your project. Or to work off an action item list everyone is aware you are using.&lt;/p&gt;
&lt;p&gt;The important thing to remember is that if you get stuck on one issue and are waiting for a response, be it on Slack or in a GitHub issue, you want to switch to a different task. That’s when you &lt;em&gt;&lt;strong&gt;go back to your worksheet of choice, and pick up a different task&lt;/strong&gt;&lt;/em&gt;. Maybe the ticket you started working on today simply isn’t going to be completed today. Doesn’t mean you can’t knock out a couple OTHER ones. (BTW, don’t forget to put note that ticket in your &lt;em&gt;worklog&lt;/em&gt;!)&lt;/p&gt;
&lt;p&gt;Worksheets are nice because you can easily apply some priority value, sort everything, and work off the top. Completed tasks can be pushed to the bottom. Once-a-week, you simply go in and readjust any priority’s. This gives you a list of what to work on next.&lt;/p&gt;
&lt;p&gt;And as a bonus, if you get stuck on one particular task and are waiting on someone to come back to you, you can pivot to the task #2, and maintain your velocity!&lt;/p&gt;
&lt;p&gt;These are just a handful of ideas to help increase your efficiency as a pro coder. Are there some tactics YOU have used that helps you? Share it below in the comments.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video below where I have a nice mix of music you can play in the background while you chew through your stack of work!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="778" medium="image" url="https://www.procoder.io//_astro/1_g_ojTh6VlXiWp_Ql67JwIA.B3z49IHM.png"/></item><item><title>Diving into 2023 as a Spring developer</title><link>https://www.procoder.io/articles/2023/2023-01-12_diving-into-2023-as-a-spring-developer-301c90abaefd</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-01-12_diving-into-2023-as-a-spring-developer-301c90abaefd</guid><description>2022 is gone. 2023 is here. To be honest, I’m not fan of New Year’s Resolutions. After all, if something is good, why not just go head and…</description><pubDate>Thu, 12 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2022 is gone. 2023 is here. To be honest, I’m not fan of New Year’s Resolutions. After all, if something is good, why not just go head and DO IT?&lt;/p&gt;
&lt;p&gt;That being said, the break time away from work at the end of 2022 and warming up to things in 2023, why not take advantage of this lull and figure out some SOLID THINGS to evolve in 2023 to make writing Spring apps easier?&lt;/p&gt;
&lt;h3 id=&quot;1cleaning-out-thecruft&quot;&gt;1 — Cleaning out the cruft&lt;/h3&gt;
&lt;p&gt;Once a year it’s good to go through your work environment and clean out junk you don’t use.&lt;/p&gt;
&lt;p&gt;And I mean it.&lt;/p&gt;
&lt;p&gt;Physically touch everything on your desk and ask, “Did I use this last year? At all?” If not, take it down. If you used it once, take it down. If you used it every week, keep it. But anything less frequent than that, and you should take it down.&lt;/p&gt;
&lt;p&gt;How to sort everything?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Things you use at least once a month can be gathered somewhere else, like your closet, a sorter, whatever. The point is, don’t clutter your daily environment with it.&lt;/li&gt;
&lt;li&gt;Some things can be either sold off of given away to others that WILL use them.&lt;/li&gt;
&lt;li&gt;Stuff that you worked with but won’t anymore can be archived. Got a storage room/closet? Maybe a file bin? Anywhere that you can put it away and access it should you need it.&lt;/li&gt;
&lt;li&gt;Finally, some things simply should be thrown away. Even if it was once cool. Even if it was once very useful. If that’s no longer the case, it’s OKAY TO THROW IT AWAY.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You won’t believe the peace it brings to clear out junk that has no bearing on your daily tasks.&lt;/p&gt;
&lt;h3 id=&quot;2streamline-your-processes&quot;&gt;2 — Streamline your processes&lt;/h3&gt;
&lt;p&gt;Whether you’re writing code, shooting content for a YouTube channel, writing novels full time, whatever, one of the most effective strategies to increase your throughput is streamlining things.&lt;/p&gt;
&lt;p&gt;The things you use every day should be easy to access from your desk. If they’re digital, like files, then it makes sense to create virtual shortcuts. I’ve been honing my list of shortcuts in my Mac’s Finder window for years.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*R4V-xWJ_hXdIJVXyUVp8FA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;You can see the most common things I access on the left-hand side. (The right-hand side is where I have all my source repositories checked out.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do you have gobs of projects checked out, all across your machine? I check almost all of them out in &lt;strong&gt;~/src&lt;/strong&gt;, while certain personal projects are at &lt;strong&gt;~/personal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Do you have an established flow of how you check out projects, how you download content off the Internet, how you capture images? (I changed the folder where screen captures go so I don’t have my Desktop getting cluttered!) If not, maybe you should consider it.&lt;/li&gt;
&lt;li&gt;Anything you are doing over and over, stop and spend ten minutes asking, “How can I simplify this process?” It could take a few hours to actually implement these changes, but if it ends up saving you THOUSANDS of hours over the long term, then it will have been worth it!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3set-it-uponce&quot;&gt;3 — Set it up once&lt;/h3&gt;
&lt;p&gt;In case you didn’t know, I make YouTube videos in my spare time about Spring Boot, how to be a pro coder, and other topics. And one thing that has made this simpler is to simply have everything ALREADY SET UP.&lt;/p&gt;
&lt;p&gt;Are you working up toward becoming a pro coder? Did you just finish your Uni/Boot Camp program and are shooting to get on a team (or maybe you just did)?&lt;/p&gt;
&lt;p&gt;Then take the time to setup your work environment. And then LEAVE IT there. (This is why I encourage people to carve out a dedicated space to writing code!)&lt;/p&gt;
&lt;p&gt;It’s okay here and there to take your machine to the dining table or the couch to do some coding. But in general, go to your dedicated space. Plus, it’s EASIER to go there if everything is ALREADY setup!&lt;/p&gt;
&lt;p&gt;Last summer, I carved out the time in my studio space to setup my camera’s tripod, all the lights, and the microphone stand. I worked out exactly where they need to be such that I could A) setup a shoot real fast, and B) not have to move things around when I was done.&lt;/p&gt;
&lt;p&gt;This made it SO EASY to simply go and shoot a video.&lt;/p&gt;
&lt;p&gt;And doing the same for whatever YOU do is vital to increasing your own throughput.&lt;/p&gt;
&lt;h3 id=&quot;4review-revise-and-revisit-every-sixmonths&quot;&gt;4 — Review, revise, and revisit every six months&lt;/h3&gt;
&lt;p&gt;The odds that things will be perfect on Day 1 are pretty much nil.&lt;/p&gt;
&lt;p&gt;But that doesn’t mean the steps I’ve mentioned won’t work. They could VERY WELL help you increase your throughput with out overloading you. But a critical thing is to plan on reviewing your setup six months from now.&lt;/p&gt;
&lt;p&gt;Look at what worked, and what DIDN’T work.&lt;/p&gt;
&lt;p&gt;Then revise your setup. Revise your streamlining. Adjust what is in your daily workspace and what is stowed in your closet. Tune things.&lt;/p&gt;
&lt;p&gt;And then be willing to revisit it six months later. Small steps that you’re willing to take and later review to see if they worked can lead to real, positive change.&lt;/p&gt;
&lt;p&gt;There’s a saying: Don’t try to make huge changes. Shoot for a 1% improvement. If you can improve just 1%, five days a week, 50 weeks a year (take a couple weeks off for pure rest), the resulting change can be huge.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*8fRLpxw-g9sDFeeFMI0r7Q.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;That’s right. Improving things by 1%, only on weekdays, in a year’s time, can lead to a &lt;strong&gt;12x improvement&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And if that sounds a bit aggressive, know this: improving things by 1%, 100 times over the next year can lead to a 2.7x improvement, a significant improvement nonetheless.&lt;/p&gt;
&lt;p&gt;You see, it’s tiny, deliberate actions, taken consistently over time that can change our lives. We just have to think ahead and take them. And knowing that you have permission to pivot six months later means nothing it set in stone.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot and learning about being a pro coder, then please stay tuned for my next article. But if you simply can’t wait, then check out this video I outline several steps in how to take that first step toward becoming a pro coder!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="818" medium="image" url="https://www.procoder.io//_astro/1_R4V-xWJ_hXdIJVXyUVp8FA.BjbDu9cr.png"/></item><item><title>5 reasons to pick up Java 17 today!</title><link>https://www.procoder.io/articles/2023/2023-01-05_5-reasons-to-pick-up-java-17-today--a54b4bdcc62e</link><guid isPermaLink="true">https://www.procoder.io/articles/2023/2023-01-05_5-reasons-to-pick-up-java-17-today--a54b4bdcc62e</guid><description>Java 17 is the latest version of one of the most popular programming languages out there. Being a core requirement to using Spring Boot…</description><pubDate>Thu, 05 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Java 17 is the latest version of one of the most popular programming languages out there. Being a core requirement to using Spring Boot 3.0, the de facto standard Java toolkit, it’s important understand some of Java 17’s most valuable features!&lt;/p&gt;
&lt;p&gt;In this article, we will explore some of the key features of Java 17 and how to use them in your own projects.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*dFjBIYovv4cJjr3RRAprtA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Java 17 is here…and it’s awesome.### 1— Installing and Setting Up Java 17&lt;/p&gt;
&lt;p&gt;Before you can start using Java 17, you will need to install it on your computer. It’s easiest to visit &lt;a href=&quot;https://sdkman.io,&quot;&gt;https://sdkman.io,&lt;/a&gt; install their JDK management tool, and then pick a distribution of Java 17 to install on your machine.&lt;/p&gt;
&lt;p&gt;I have used either OpenJDK’s Adoptium Temurin distribution or BellSoft’s Liberica distribution. There are many others to pick from, but these two definitely are TCK-verified and rock solid.&lt;/p&gt;
&lt;p&gt;If you have need to commercial support or more reliabilitity, you may need to investigate these distributions further and compare them to some of the others.&lt;/p&gt;
&lt;h3 id=&quot;2key-features-in-java17&quot;&gt;2 — Key Features in Java 17&lt;/h3&gt;
&lt;p&gt;Java 17 includes a number of new features and improvements that make it easier to write code and build applications. Some of the key features of Java 17 include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sealed Classes&lt;/strong&gt;: Sealed classes allow you to specify which subclasses are allowed to extend a particular class, making it easier to maintain type-safety and control over your class hierarchy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text Blocks&lt;/strong&gt;: Text blocks are a new type of string literal that makes it easier to write multi-line strings in your code. They automatically handle line breaks and indentation, making it easier to write and read code that includes large blocks of text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Records&lt;/strong&gt;: Records are a new type of data structure that make it easier to define simple classes that act as data containers. They provide a concise syntax for defining classes with a fixed number of fields, and automatically generate common methods such as equals and toString.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why are &lt;em&gt;&lt;strong&gt;sealed classes&lt;/strong&gt;&lt;/em&gt; so cool?&lt;/p&gt;
&lt;p&gt;In the past, you either kept your classes and interfaces basically public or private. There are differing flavors of this such as package private, which simply means public within a given package, but private beyond that. Once you open up a class or interface to public consumption, you open yourself up to risk.&lt;/p&gt;
&lt;p&gt;If someone either extends your class or implements your interface, you may be seeing new tickets if you didn’t design it properly. Why do you think the purveyors of the JDK made java.lang.String final? Simple: they don’t want anyone extending any of its methods and mucking up their careful refinements.&lt;/p&gt;
&lt;p&gt;The truth is, sealed classes gives you the ability to have something in between private and public. You are able to create a publicly visible interface…and define EXACTLY who can extend/implement it.&lt;/p&gt;
&lt;p&gt;Sealed classes let you define a well-defined group of implementations and revise that down the road without opening the door to OTHER people extending it beyond your control. And that’s cool. True, it’s a bit early for us to see the full benefits, but I anticipate cool enhancements in the land of framework code.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Fbrgq3HGOXQokS_NhiUriQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/a/69218715/28214&quot;&gt;https://stackoverflow.com/a/69218715/28214&lt;/a&gt;&lt;em&gt;&lt;strong&gt;Text blocks&lt;/strong&gt;&lt;/em&gt; move us closer to Pythonic apps. Python has had multiline text blocks for years. It lets you more stream-of-consciousness lay out description blocks, populate String-based annotation fields, and other stuff. No more fiddling with line breaks and “plussing” them together.&lt;/p&gt;
&lt;p&gt;Finally, &lt;a href=&quot;/articles/medium/2022-12-22_tis--the-season-to-spring-boot-3-0-353de48e7540&quot;&gt;Java 17 records are the new way to model&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Seriously, I built a handy utility in just a few days to help me parse an app I use in my off hours that generate XML for Final Cut Pro. Using Java 17 records, I was able to model the source AND the transformed output in minutes.&lt;/p&gt;
&lt;p&gt;Give it a spin!&lt;/p&gt;
&lt;h3 id=&quot;3-pattern-matching-switch-statements&quot;&gt;3— Pattern matching switch statements&lt;/h3&gt;
&lt;p&gt;It used to be in the olden days, in the days of yesteryear, switch statements were clunky and tended toward code smells. That is, the limited usage of switch statements could often be rewritten into an OOP pattern.&lt;/p&gt;
&lt;p&gt;If you didn’t, the pattern tended to get copied around.&lt;/p&gt;
&lt;p&gt;However, Java 17 expands the power greatly, allowing slicker, more usable patterns. Check out the code block below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;return switch (obj) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; case Rectangle r -&gt; 2 * r.length() + 2 * r.width();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; case Circle c -&gt; 2 * c.radius() * Math.PI;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; default -&gt; throw new IllegalArgumentException(&quot;unrecognized shape&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of being a statement, it’s now an expression whose operative feature is it can “returned”. In addition to that, we now have the arrow notation and no more need for break clauses.&lt;/p&gt;
&lt;p&gt;Finally, notice how type support is now supported. This allows matching on class patterns, which further encourages algebraic types as discussed earlier.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: If the type of the switched object is a sealed class and all the types are covered, there would no need for a default clause. And your IDE can help you handle this!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;4pattern-matching-instancechecks&quot;&gt;4 — Pattern matching instance checks&lt;/h3&gt;
&lt;p&gt;One of the smaller features that really tickles my fancy is the ability to do an instanceof check with a built-in downcast. Look at the somewhat contrived code block below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Object obj = &quot;Hello World&quot;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if (obj instanceof String s) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; System.out.println(s.toUpperCase());  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A somewhat common pattern that has permeated code for ages is the need to test if a given object is a particular subtype. If so, downcase to it. This chunk of code introduces a name after the type in the instanceof check, granting us access to the downcast object.&lt;/p&gt;
&lt;p&gt;Yes, it trims that single line which would have been &lt;code&gt;String s = (String) obj&lt;/code&gt;, and yes, that simply ain’t a lot to get excited about.&lt;/p&gt;
&lt;p&gt;But it’s a such a simple, elegant way to capture intent without the overload of casting, that I simply love it.&lt;/p&gt;
&lt;p&gt;It’s tiny stuff like this that enriches a language to code the stuff we need.&lt;/p&gt;
&lt;h3 id=&quot;5conclusion&quot;&gt;5 — Conclusion&lt;/h3&gt;
&lt;p&gt;Java 17 is a powerful and feature-rich programming language that makes it easy to write code and build applications. With its new features and improvements, it is a great choice for developers looking to take their skills to the next level. Whether you are a beginner or an experienced programmer, there is something in Java 17 for everyone.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;SIGN UP FOR MY NEWSLETTER&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="800" medium="image" url="https://www.procoder.io//_astro/1_dFjBIYovv4cJjr3RRAprtA.CdYfySqE.png"/></item><item><title>Tis’ the season to Spring Boot 3.0</title><link>https://www.procoder.io/articles/2022/2022-12-22_tis--the-season-to-spring-boot-3-0-353de48e7540</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-12-22_tis--the-season-to-spring-boot-3-0-353de48e7540</guid><description>As the yuletide season is upon is, this may be the time to not only pour yourself a glass of eggnog, but to give YOURSELF the gift of…</description><pubDate>Thu, 22 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As the yuletide season is upon is, this may be the time to not only pour yourself a glass of eggnog, but to give YOURSELF the gift of Spring Boot 3.0.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*26yAM3srNHnntS6Odb9wQA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Spring Boot 3 has some of the most wickedly cool features out there. A boost in performance. And some reduced codebases overall. But I’m getting ahead of myself.&lt;/p&gt;
&lt;h3 id=&quot;1record-types-are-the-new-way-tomodel&quot;&gt;1 — Record types are the NEW way to model&lt;/h3&gt;
&lt;p&gt;When you start working on your delicious app, it’s time to pick up and run with Java records. This is courtesy of Java 17, Spring Boot 3’s new baseline.&lt;/p&gt;
&lt;p&gt;Java records are something we’ve been asking for for years. It’s one of the features than any non-Java JVM-based language seems to lead with in any presentation. The old setter/getter paradigm may be hard to let go of, but once you do, it’s glorious.&lt;/p&gt;
&lt;p&gt;I once hosted a live stream coding an OAuth 2 service that talked to YouTube’s API. Modeling every domain type I needed to deserialize their JSON (there were a lot), instead of being cringe-worthy became effortless.&lt;/p&gt;
&lt;p&gt;Once I had rigged up the machinery to make remote calls to YouTube and had hooked in the OAuth credentials, surfing through their data types became FUN!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchThumbnail(String url, Integer width, Integer height) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Java 17 records are immutable. They don’t have getters like getUrl(), but instead field accessor like url(). Don’t worry! JavaBean-based tools like Thmyeleaf and Mustache still work just the same.&lt;/p&gt;
&lt;p&gt;You can write methods as needed to provide virtual fields and other things. But all in all, they are slim and trim. You can EVEN use them for your Spring Boot configuration property objects!&lt;/p&gt;
&lt;p&gt;Simply put, try to use them as much as possible. There is simply no need to go back to the days of yesteryear, using clunky old POJOs.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;WARNING: Any toolkit built on MUTABILITY won’t work with Java records. (I’m looking at you, JPA!) There are some tricks where you can use them as DTOs, and JPQL indeed supports DTO-based queries. But if you try to twist them into entity types, you’ll only bruise your ego.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Speaking of remoting services, Spring Boot 3 has a slick feature…&lt;/p&gt;
&lt;h3 id=&quot;2httpserviceproxyfactory-is-the-new-way-to-speak-to-remoteservices&quot;&gt;2 — HttpServiceProxyFactory is the NEW way to speak to remote services&lt;/h3&gt;
&lt;p&gt;We’ve all had to connect with remote services. RestTemplate has been there for ages and now we have WebClient as well. They both can ease the process.&lt;/p&gt;
&lt;p&gt;But did you know that there’s a better way?&lt;/p&gt;
&lt;p&gt;Spring Framework 6, the versiong underlying Spring Boot 3, brings us a way to implement interface-based remoting.&lt;/p&gt;
&lt;p&gt;First, you must define your API as a Java interface:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;interface YouTube {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @GetExchange(&quot;/search?part=snippet&amp;#x26;type=video&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; SearchListResponse channelVideos( //  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @RequestParam String channelId, //  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @RequestParam int maxResults);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This interface defines the paths, params, and types involved in the exchange. The @GetExchange, analogous to Spring MVC’s @GetMapping annotation, defines the remote calls that are made. (There are matching annotations for other HTTP verbs). But the real magic is in HOW this interface is implemented.&lt;/p&gt;
&lt;p&gt;Go into your @Configuration class and add this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @Bean  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; HttpServiceProxyFactory proxyFactory(WebClient webClient) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; return HttpServiceProxyFactory.builder() //  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; .clientAdapter(WebClientAdapter.forClient(webClient)) //  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; .build();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This bean will take your injected WebClient and use it as the engine for the proxy factory bean. (There’s also support for RestTemplate if you need it.)&lt;/p&gt;
&lt;p&gt;Finally, you can link the two together, like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Bean  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;YouTube client(HttpServiceProxyFactory factory) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; return factory.createClient(YouTube.class);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This little factory will create a proxy that honors the contract defined in the interface. Now, you need merely inject the YouTube object into any Spring bean, and &lt;strong&gt;POOF&lt;/strong&gt; you can access remote services.&lt;/p&gt;
&lt;p&gt;If you didn’t catch it, the WebClient that gets injected up above can be decorated in all kinds of ways. In &lt;a href=&quot;/books/learning-spring-boot-3-0&quot;&gt;&lt;em&gt;Learning Spring Boot 3.0 3rd Edition&lt;/em&gt;&lt;/a&gt;, we explore how to register OAuth 2 handlers, allowing for remote calls to OAuth-protected APIs.&lt;/p&gt;
&lt;h3 id=&quot;3native-applications&quot;&gt;3 — Native applications&lt;/h3&gt;
&lt;p&gt;One of the biggest bumps in power and productivity is the emergence of &lt;strong&gt;native applications&lt;/strong&gt;. Native applications are apps where you trade in Java’s long-standing promise of write-once/run-anywhere in exchange for compile-to-platform/dial-up-performance.&lt;/p&gt;
&lt;p&gt;Native apps can switch from 30-second startups to sub-second startups. While not an issue for classic web server apps that are up all the time, for command line utilities, it’s revolutionary. If you’re using AWS Lambda Functions, you’ve shifted the cold-start time to virtually nothing.&lt;/p&gt;
&lt;p&gt;And if you’re running 10,000 instances in the cloud, you can shave HOURS off your cloud bill, a real game changer in savings if you are also pushing out 100 commits a day.&lt;/p&gt;
&lt;p&gt;The secret to unlocking native apps is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install GraalVM CE using sdkman on your local machine by typing &lt;code&gt;sdk install java 22.3.r17-grl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Using start.spring.io, add all your existing app’s dependencies + &lt;strong&gt;GraalVM Native Support&lt;/strong&gt;. Hit the &lt;strong&gt;EXPLORE&lt;/strong&gt; button and copy the changes from the build file into your own project. Refresh your project.&lt;/li&gt;
&lt;li&gt;After switching over to the GraalVM CE JDK, build your app natively by typing &lt;code&gt;./mvnw -Pnative clean native:compile&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once completed, instead of an uber JAR, you’ll have a native app compiled right into your target folder.&lt;/p&gt;
&lt;p&gt;If you want to know how epic this is, my friend Maciej Walkowiak just released a new Spring tool called “just”. It’s a CLI that does Spring stuff for you. And he built it using Spring Boot + native app development.&lt;/p&gt;
&lt;p&gt;With all these changes at your fingers, I wish you a cup of cheer as you embrace these latest changes from Spring Boot 3.0!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out this video where I live stream configuring a Spring Boot app to talk to YouTube and make our own video-serving app, using the very techniques listed above!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_26yAM3srNHnntS6Odb9wQA.CZMUaa1z.jpeg"/></item><item><title>When should I call for help as a software developer?</title><link>https://www.procoder.io/articles/2022/2022-12-15_when-should-i-call-for-help-as-a-software-developer--dcfc3e9cfed2</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-12-15_when-should-i-call-for-help-as-a-software-developer--dcfc3e9cfed2</guid><description>If you’re here, I’ll go right along and assume you are a Spring developer. You’re either building apps with Spring Boot, or you’re learning…</description><pubDate>Thu, 15 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you’re here, I’ll go right along and assume you are a Spring developer. You’re either building apps with Spring Boot, or you’re learning about Spring in your Uni/bootcamp program, or perhaps you’re responding to questions on stackoverflow.com.&lt;/p&gt;
&lt;p&gt;If you are, great!&lt;/p&gt;
&lt;p&gt;Spring is popular…for a reason. Spring has a long history of solving problems. Of COURSE people want to use it. But maybe you’re staring at a chunk of code and wondering, “what do I NOW??”&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*NvIqqOhdy_9JYtTbWpFgjg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;You’re beleaguered from moving forward because something stumps you. If you haven’t felt that yet, don’t worry. It will happen some day. ALL software developers run into this. And not just once. I have.&lt;/p&gt;
&lt;p&gt;That’s why we need lifelines. One of the most powerful tools we as software geeks can have in our possession is a collection of fellow coders we can reach out to and ask for assistance.&lt;/p&gt;
&lt;p&gt;Not only can getting help move us along…it’s one of our best instructional tools available.&lt;/p&gt;
&lt;p&gt;When something goes wrong, and we make it then go right, we learn in the moment. The NEXT time we encounter something similar, we may solve it faster. Or perhaps we may spot it before it becomes a problem, and head it off.&lt;/p&gt;
&lt;p&gt;But asking for help is hard. It requires surrendering our personal ego. A certain amount of vulnerability is communicated when we say, “I need help.”&lt;/p&gt;
&lt;p&gt;At a previous position, I once inherited a Java Swing app. It “worked”, but was fraught with bad design practices, had horrible performance, and anytime someone hit the SAVE button, it would take 20 minutes to complete. I have shared this war story so many times, it ridiculous. I spent something like three weeks SIMPLY TRYING TO GROK the database operation behind that SAVE button.&lt;/p&gt;
&lt;p&gt;There were no tests. No notes. Just a view and a UI.&lt;/p&gt;
&lt;p&gt;I figured it out eventually. The original developer had reached for multiple database views that had what he needed, and had joined them together. If you didn’t know it, join views is BAD. The mega-query at work ended up joining the same table TWENTY TIMES.&lt;/p&gt;
&lt;p&gt;After unravelling what it did, I wrote a fresh query that did the same…and it went sub-second. I rolled out that patch to the users, and alerted them to this small change, a change that probably saved them from thousands of hours of wasted time in the future.&lt;/p&gt;
&lt;p&gt;This developer had worked EVERY hard to implement it. But didn’t pause and ask for help. I don’t know the story behind this person. Maybe they indeed were too proud? Or maybe help was simply short at the time.&lt;/p&gt;
&lt;p&gt;My point is that this instance has reminded me over and over, throughout my career, that it’s usually better in the end if we check out pride at the door and instead reach out for feedback and inputs more often. If when things get a bit challenging, we reach out for help.&lt;/p&gt;
&lt;p&gt;And if at all possible, don’t work silently, in a corner, in isolation, avoiding all the opportunities to learn and grow as a software developer.&lt;/p&gt;
&lt;p&gt;So anytime YOU are challenged in a situation, reach out for assistance. Anytime YOU are given a task, you can simply share what you are doing, whether it’s with your instructor, your manager, or your technical leader.&lt;/p&gt;
&lt;p&gt;Sharing what you’re doing in a consistent fashion opens up the lines of communication and makes it easier to THEN say, “You know that thing I’ve been working on for the past three days? I seem to have hit a wall. Can we Zoom for 15 minutes where I share what’s happening?”&lt;/p&gt;
&lt;p&gt;The person you share with may not even say a word in the whole Zoom chat. Sometimes…simply enunciating the struggle you are facing can put the answer into focus.&lt;/p&gt;
&lt;p&gt;My nephew who is about to graduate high school, has called me late at night in the midst of coding projects. And there has been more than one occasion where simply talking to me over the phone while are both looking at the same code, he figures it out. With little more than a “what’s that?” from me.&lt;/p&gt;
&lt;p&gt;But even if you DO need actionable advice for a colleague, it’s okay. This is software REALLY works.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*R_qmZSoslbOKjROc9O6eTA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;None of us REALLY survive by working weeks on end in a secret room all by our lonesome selves.&lt;/p&gt;
&lt;p&gt;Nope.&lt;/p&gt;
&lt;p&gt;We REALLY thrive when we work together. Everyone has different talents. Different skills. Different things &lt;em&gt;we have a certain nose for&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;One member of our team is REALLY good with JDK-type classfile-based stuff. We also experts on some of the deepest, most intricate details of the Java programming language. My super power is being able to hack my way through server-side dev-ops-ish type stuff and bending CI systems to do my bidding.&lt;/p&gt;
&lt;p&gt;Understanding what you can (and CAN’T do) is a point of self awareness. And recognizing that while I’m great at relational databases and can write left outer joins and correlated subqueries in my sleep, I’m still growing my my knowledge of the depths of JPA. (Thankfully I’m surrounded by several experts!)&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*EwhVdmuO7Tlg3x4Y0AQGXQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;When we harness our strengths and reach out for others’, that’s when we thrive. And that’s when everyone thrives.&lt;/p&gt;
&lt;p&gt;If you want to see more articles about Spring Boot in general, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can learn the differences between JDBC and JPA, and when to use what!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="400" medium="image" url="https://www.procoder.io//_astro/1_NvIqqOhdy_9JYtTbWpFgjg.DEmAeKCQ.png"/></item><item><title>What to do on your first day/week/month/year as a Spring developer!</title><link>https://www.procoder.io/articles/2022/2022-12-09_what-to-do-on-your-first-day-week-month-year-as-a-spring-developer--5801fb601c3c</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-12-09_what-to-do-on-your-first-day-week-month-year-as-a-spring-developer--5801fb601c3c</guid><description>So you’ve finally done it! You landed that dream position writing Spring Boot apps for a cool software company.</description><pubDate>Fri, 09 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So you’ve finally done it! You landed that dream position writing Spring Boot apps for a cool software company.&lt;/p&gt;
&lt;p&gt;And then the shock of it hits you…what do you DO? Are you ready? Are you prepared? What should you be doing?&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*H_-psmWyX739YohlIF0Z8g.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 1 — What to do on your first day&lt;/p&gt;
&lt;p&gt;It’s fair to assume that IT will onboard you access to email and whatever IM tool the team is using, be it Slack, HipChat, whatever.&lt;/p&gt;
&lt;p&gt;Make a point of finding out who your immediate manager is as well as your immediate team mates. &lt;strong&gt;Write down their names.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That’s right. Be it a little sticky note, your iPhone’s Notes app, whatever. Write down these people’s names. You may never read that note again, but the very act of writing down this information will help commit it to memory. And knowing who your immediate teammates are is key.&lt;/p&gt;
&lt;p&gt;You may get invited to a particular room/channel pertinent to the team you’ve joined. As you see messages posted, take note of WHO has written those messages. You can probably click on the person’s avatar and ideally see a picture of them as well.&lt;/p&gt;
&lt;p&gt;That is not all.&lt;/p&gt;
&lt;p&gt;While you are reading a flurry of messages, &lt;em&gt;&lt;strong&gt;take it easy&lt;/strong&gt;&lt;/em&gt;. No one is expecting you to solve the world’s problems on your first day. &lt;strong&gt;Just try to drink it all in&lt;/strong&gt;. Read every message. If there’s a link to a blog post with comments, go read that article. If there is a link to a fragment of code, click on it and start reading the code.&lt;/p&gt;
&lt;p&gt;Absorbing code starts with reading it. If you’re lucky, it could be something you’re already semi-familiar with. But that’s not always the case.&lt;/p&gt;
&lt;p&gt;Also, your new manager may have a set of actions for you to carry out including: &lt;em&gt;registration with various systems&lt;/em&gt;, &lt;em&gt;filling out some e-forms&lt;/em&gt;, and other &lt;em&gt;“paperwork”&lt;/em&gt;. Do it. It’s time to start showing you’re a team player by carrying out your immediate assignments.&lt;/p&gt;
&lt;p&gt;And above all…&lt;strong&gt;listen&lt;/strong&gt;. You’ll be getting fed a firehouse of information. Don’t sweat it, and simply listen and read. (And if you’re smiling with excitement at your new position, that’s okay as well.)&lt;/p&gt;
&lt;h3 id=&quot;2what-to-do-on-your-firstweek&quot;&gt;2 — What to do on your first week&lt;/h3&gt;
&lt;p&gt;We talked about what to do on your &lt;strong&gt;first day&lt;/strong&gt;. But what are some key things to do on your &lt;strong&gt;first week&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;Have you gotten in touch with the system adminstrator and &lt;em&gt;&lt;strong&gt;registered your github id&lt;/strong&gt;&lt;/em&gt;? Sophisticated teams may have already covered this in their onboarding procedures, but not everyone is this deft. Giving them your github id will enable them to grant you access to the repositories you will be working on.&lt;/p&gt;
&lt;p&gt;Here’s a biggie: have they sent you a work machine yet? If you’re working remotely from home, maybe not. Make sure the provisioning department &lt;em&gt;&lt;strong&gt;has your mailing address&lt;/strong&gt;&lt;/em&gt; so nothing on your end delays sending you a work machine. (If you don’t even know who to contact in the provisioning department, this is a great time to reach out to your manager.)&lt;/p&gt;
&lt;p&gt;Assuming you DO have a work machine, have you cloned the immediate repository you are assigned to and:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Started reading the code?&lt;/li&gt;
&lt;li&gt;Installed the right tools to build it? (Java, Maven, Gradle, sdkman)&lt;/li&gt;
&lt;li&gt;Inspected any CI tools used to build it? (Jenkinsfile, .circleci/&lt;em&gt;, .github/&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, the idea isn’t to start building epic features, but to instead become familiar with how to build the systems.&lt;/p&gt;
&lt;p&gt;Also, carve out plenty of time to start reading the code.&lt;/p&gt;
&lt;p&gt;BONUS: After the first week, you may want to start reading the backlog of tickets. Start getting familiar with the problems the users are running into. One again, this isn’t so that you’re ready to solve them. Instead, to start getting a feel for the pain points the community is hitting.&lt;/p&gt;
&lt;h3 id=&quot;3what-to-do-on-your-firstmonth&quot;&gt;3 — What to do on your first month&lt;/h3&gt;
&lt;p&gt;I have often seen a month as the MINIMUM amount of time for me to start getting the hang of a given project. This presumes I have been reading the code, building the artifacts (e.g., &lt;em&gt;./mvnw clean package&lt;/em&gt;), and trying to nudge little things here and there.&lt;/p&gt;
&lt;p&gt;I mentioned earlier to start reading the code. This should include the reference docs, which many projects include inside the source code. If not, find out where they are and start reading that as well.&lt;/p&gt;
&lt;p&gt;Because one of the first things you can “do” in your first month, is to submit a pull request (PR) patching the ref docs. Fixing a typo, rewording a sentence. Anything along these lines. BONUS: Learn how to render the docs and inspect your handiwork. (You can often find this is you read the CI files.)&lt;/p&gt;
&lt;p&gt;Other stuff you can be doing within the first month is spotting any sloppy code, old patterns (e.g., missing generic parameters, missing usage of the diamond operator, etc.), or unused import statements. Anything that simply “cleaning up” the code without actually changing the code.&lt;/p&gt;
&lt;p&gt;And you should be learning exactly how your team handles change. Have they given you free reign to simply commit to the main branch? (Unlikely) Or do they want you to submit a pull request to GitHub and then request a review? And do they let you merge the change, or does someone else handle that?&lt;/p&gt;
&lt;p&gt;Finally, something else you should be taking notes on is exactly HOW your team curates the change log. In other words, how does your team format commit messages? And how do they DO merges? Create a branch, rebase, then merge back? Cherry picking? What about multiple supported versions? Are you supposed to work against the latest and backport…or work against the oldest and merge forward?&lt;/p&gt;
&lt;p&gt;If this is starting to sound overwhelming, that’s cool. Learning HOW your team does commits may be more of a Month 2 or Month 3 thing. And this doesn’t mean you are DOING the process. I’m just asking you to BECOME FAMILIAR with how they are doing it. If you have an approved change, you can also ask to do a pairing session to help you walk through the process.&lt;/p&gt;
&lt;h3 id=&quot;4what-to-do-on-your-6thmonth&quot;&gt;4 — What to do on your 6th month&lt;/h3&gt;
&lt;p&gt;By this stage, I hope you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learned how your team handles changes, be they new features or bugs.&lt;/li&gt;
&lt;li&gt;Become familiar with how they use CI and work with it, not against it.&lt;/li&gt;
&lt;li&gt;Gotten ramped up on how tickets are managed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Six months in, and you should be making changes. You may not be building the biggest stuff (yet), or maybe you are? However, what’s more important than implementing the biggest features is learning how the rhythm of your team.&lt;/p&gt;
&lt;p&gt;Learning how to bring value to the table calmly and consistently. They hired you for a reason. It wasn’t to be combative, but instead contribute to the team. While implementing Big Stuff is cool, closing out a dozen tiny tickets with small stuff is always a good idea and will earn you some well-deserved allies.&lt;/p&gt;
&lt;p&gt;We all make mistakes (myself included). If you have shown your ability to knock bugs and patches, teammates are willing to work through mistakes. If you aren’t pulling your weight, mistakes can turn against you much faster.&lt;/p&gt;
&lt;p&gt;Again, focus on your team’s process and strive to contribute to it every day.&lt;/p&gt;
&lt;h3 id=&quot;5what-to-do-on-your-firstyear&quot;&gt;5 — What to do on your first year&lt;/h3&gt;
&lt;p&gt;Your anniversary of your new position rolls around. It might surprise you when it does! This is a time to celebrate.&lt;/p&gt;
&lt;p&gt;And hopefully, it’s also a time to push forward with providing even more value. And ideally, at this stage, you have built up a sense of the tools and apps you are assigned to.&lt;/p&gt;
&lt;p&gt;But don’t settle for that. Because you should also have a feel for the types of requests and bugs the community has been reporting. You need to start looking to the future, and asking, “What should we add that would support the community the best?”&lt;/p&gt;
&lt;p&gt;You can’t always ask people what they want. They don’t always know. This is Apple’s mantra — building visionary products. Sketch out some ideas and discuss them with your team. This is the future, not just fixing bugs but instead figuring out where the app will go!&lt;/p&gt;
&lt;p&gt;Also, you should be looking at ways your apps interact with other apps you don’t work with directly. The Spring team has multiple sub-teams, each working on various parts of the portfolio. And all these sub-teams work with each other to make all the tools work together. You should be seeking to do the same.&lt;/p&gt;
&lt;p&gt;And with a year under your built, don’t stop. Because you’re just getting started. Where are you in your current journey? Share it in the comments below!&lt;/p&gt;
&lt;p&gt;If you want to see more articles about Spring Boot in general, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can double check that you’re doing all you can to bring value to your team in these challenging economic times.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="534" medium="image" url="https://www.procoder.io//_astro/1_H_-psmWyX739YohlIF0Z8g.Dl8gOYzr.jpeg"/></item><item><title>Using Micrometer to trace your Spring Data JPA application</title><link>https://www.procoder.io/articles/2022/2022-12-01_using-micrometer-to-trace-your-spring-data-jpa-application-aab5c6449900</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-12-01_using-micrometer-to-trace-your-spring-data-jpa-application-aab5c6449900</guid><description>In a previous article, we saw the goodness of stirring a little Micrometer into our Spring Boot 3 application to trace what our application…</description><pubDate>Thu, 01 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;/articles/2022/2022-11-10_using-micrometer-to-trace-your-spring-boot-app-1fe6ff9982ae/&quot;&gt;In a previous article&lt;/a&gt;, we saw the goodness of stirring a little Micrometer into our Spring Boot 3 application to trace what our application did. We saw how to activate the Micrometer bindings buried deep in Spring Boot for web calls. And we piped all those good metrics into Zipkin, the open source distributed tracing system thanks to Docker.&lt;/p&gt;
&lt;p&gt;But that wasn’t very “realistic” cuz we didn’t have a “real” database underneath it.&lt;/p&gt;
&lt;p&gt;Everyone know that real apps have data, right? So why not put something together!&lt;/p&gt;
&lt;p&gt;To kick things off, after fashioning an app using &lt;strong&gt;start.spring.io&lt;/strong&gt;, &lt;strong&gt;Spring Data JPA&lt;/strong&gt;, and &lt;strong&gt;H2&lt;/strong&gt;, we need a domain object. Let’s craft something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Entity  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class Employee {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @Id  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @GeneratedValue private Long id;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; private String name;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; private String role;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;//...constructors/getters/setters ommitted for brevity...  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A basic domain object that lets us model the &lt;strong&gt;Employees&lt;/strong&gt; in our payroll system. This entity class is properly annotated with @jakarta.persistence.Entity (remember Spring Boot 3 is on Jakarta EE 10!). It also has the id field marked up as the primary key using @jakarta.persistence.Id. We will also let the JPA persistence provider handle primary key generation by using @jakarta.persistence.GeneratedValue.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Even though Spring Data provides some cool features, we STILL have to model our entity classes properly for things to come together!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since we’re using Spring Data JPA, we also need to define a repository. So let’s do something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public interface EmployeeRepository extends JpaRepository&amp;#x3C;Employee, Long&gt; {}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This barebones interface definition extends Spring Data JPA’s &lt;strong&gt;JpaRepository&lt;/strong&gt; and defines its domain type as &lt;strong&gt;Employee&lt;/strong&gt; and the primary key type as &lt;strong&gt;Long&lt;/strong&gt;. Even though our interface definition is empty, it still comes packed with LOTS of options. (Just visit &lt;strong&gt;JpaRepository&lt;/strong&gt; and its parent interfaces inside your IDE to see exactly what you get!)&lt;/p&gt;
&lt;p&gt;The rest of the application is just a Spring MVC @RestController, much like what we had in the previous article, shown below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@RestController  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class EmployeeController {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; private final EmployeeRepository repository;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; public EmployeeController(EmployeeRepository repository) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; this.repository = repository;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @GetMapping(&quot;/api/employees&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; List&amp;#x3C;Employee&gt; all() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; return repository.findAll();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; @GetMapping(&quot;/api/employees/{id}&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; Employee one(@PathVariable Long id) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; return repository.findById(id) //  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; .orElseThrow(() -&gt; new RuntimeException(&quot;Employee &quot; + id + &quot; not found!&quot;));  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This REST controller will inject our &lt;strong&gt;EmployeeRepository&lt;/strong&gt; bean into the controller and then use it to either find ALL employees, or just one.&lt;/p&gt;
&lt;h3 id=&quot;so-where-is-all-this-magicaltracing&quot;&gt;So where is all this magical tracing?&lt;/h3&gt;
&lt;p&gt;Good question. The answer is…it’s not here yet. That’s because we need a few additional things in our project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When building our app inside start.spring.io, we must also include &lt;strong&gt;Spring Boot Actuator&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We also need to add &lt;strong&gt;Micrometer&lt;/strong&gt; and its bridge for &lt;strong&gt;Zipkin&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;groupId&gt;io.micrometer&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;artifactId&gt;micrometer-observation&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;groupId&gt;io.micrometer&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;artifactId&gt;micrometer-tracing-bridge-brave&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;groupId&gt;io.zipkin.reporter2&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;artifactId&gt;zipkin-reporter-brave&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Almost there. We just need one &lt;em&gt;teensy&lt;/em&gt; little dependency:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;groupId&gt;net.ttddyy.observation&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;artifactId&gt;datasource-micrometer-spring-boot&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &amp;#x3C;version&gt;1.0.0-SNAPSHOT&amp;#x3C;/version&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This last dependency is a special module that will wrap ANY &lt;strong&gt;DataSource&lt;/strong&gt; bean with a proxy that uses Micrometer APIs to log actions.&lt;/p&gt;
&lt;h3 id=&quot;jpa-speaks-datasource&quot;&gt;JPA speaks DataSource?&lt;/h3&gt;
&lt;p&gt;Yup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DataSource&lt;/strong&gt; is an interface from the &lt;strong&gt;JDBC&lt;/strong&gt; spec. And &lt;strong&gt;JDBC&lt;/strong&gt; is the standard through which ALL Java applications speak to database. So every &lt;strong&gt;JPA&lt;/strong&gt; app, every &lt;strong&gt;jOOQ&lt;/strong&gt; app, every &lt;strong&gt;Querydsl&lt;/strong&gt; app speaks &lt;strong&gt;JDBC&lt;/strong&gt; when it comes to linking up with relational databases.&lt;/p&gt;
&lt;p&gt;Wrap a &lt;strong&gt;DataSource&lt;/strong&gt; bean and you can trace ANY relational database application with Micrometer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;BTW, &lt;strong&gt;R2DBC&lt;/strong&gt; is another Java standard used to talk to relational databases, and that is ONLY for reactive applications, not what we’re doing today.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Apply these settings to our &lt;strong&gt;application.properties&lt;/strong&gt; file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Trace every action  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;management.tracing.sampling.probability=1.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…and we’re set! Time to launch the app and give it a spin. (Don’t forget to be running Zipkin from Docker Desktop).&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*jer_c4PwRC0m8IcrDYyBDg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Query the endpoint, and we have our outputs from that controller class we just built. Now let’s go see what it says in Zipkin.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*4DkmscoeY1tTxa7FaEvrew.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Querying for traced, we can see &lt;strong&gt;http get /api/employees&lt;/strong&gt;. Looks like what we want. Click on &lt;strong&gt;SHOW&lt;/strong&gt; and we should see this:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*qK8eZ1cf22CtCcVMU18g4g.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;We can see from the left-hand side, that Spring MVC traced the call to &lt;strong&gt;http get /api/employees&lt;/strong&gt;. From there a connection was opened. Then a query was made against the database followed by processing a result set.&lt;/p&gt;
&lt;p&gt;By clicking on the query box, we can see the tags on the right hand side, including the &lt;strong&gt;jdbc.query&lt;/strong&gt; that was executed. And we see that a JPA query, fashioned for by Spring Data JPA’s query derivation layer, was ultimately transformed into a JDBC query by Hibernate’s Entity Manager.&lt;/p&gt;
&lt;p&gt;And the query itself only took &lt;strong&gt;270 microseconds&lt;/strong&gt;. Looks like this query doesn’t much in the way of tuning, ehh?&lt;/p&gt;
&lt;p&gt;But these tools now provide the means to track down what DOES take a long time. Maybe one of the queries you build is just not every efficient and needs to be rewritten? Or perhaps something else is fault in the assumptions made.&lt;/p&gt;
&lt;p&gt;Either way, these give us some nifty tools to measure results and effect change!&lt;/p&gt;
&lt;p&gt;If you want to see more articles about Spring Boot in general, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where we learn a little more of what JDBC is all about.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="675" medium="image" url="https://www.procoder.io//_astro/1_jer_c4PwRC0m8IcrDYyBDg.C8Wldbpi.png"/></item><item><title>Twas the night before Spring Boot 3.0 went GA…</title><link>https://www.procoder.io/articles/2022/2022-11-24_twas-the-night-before-spring-boot-3-0-went-ga--f0b51c1b0a7b</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-11-24_twas-the-night-before-spring-boot-3-0-went-ga--f0b51c1b0a7b</guid><description>Spring Boot 3.0 goes GA tomorrow.</description><pubDate>Thu, 24 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Spring Boot 3.0 goes GA tomorrow.&lt;/p&gt;
&lt;p&gt;That is EXCITING! Why? Because this is another of those epic releases where the raw power of Java will again leapfrog forward. And the Spring team, once again, is there to help bring it to your fingertips…with ease.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*9gtSA7pLmSCFfsUEEzJKOg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 1 — Java 17, baby!&lt;/p&gt;
&lt;p&gt;Java for the longest time came in what seemed like tiny increments. But when Oracle took over and began making releases every six months, it suddenly got crazy…and fun, starting with Java 9.&lt;/p&gt;
&lt;p&gt;While Java 8 has been a powerhouse including things like lambda functions, the Stream API, and other slick features, it’s time to move up to uber awesome Java 17.&lt;/p&gt;
&lt;p&gt;Java 17 brings a fistful of enhancement including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New and improved methods to the Collections library, e.g. List.of(1,2,3) (immutable!), List.copyOf(otherList) (again, immutable), and more.&lt;/li&gt;
&lt;li&gt;Record types — build data types and DTOs with minimal effort&lt;/li&gt;
&lt;li&gt;One of my favorite…types instanceof. Are you tired of doing an instanceof check against a variable and then downcasting to that type? Java lets you do that one statement. &lt;code&gt;if (shape instanceof Rectangle r) /* refer to r as a Rectangle! */&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Performance speed ups&lt;/li&gt;
&lt;li&gt;&lt;code&gt;var&lt;/code&gt; — ALERT: Use sparingly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is certainly more, but this should already whet your appetite. Spring Boot 3.0 and the rest of the matching portfolio will be moving up to Java 17. Of course, older versions of Spring are still based on Java 8.&lt;/p&gt;
&lt;h3 id=&quot;2jakarta-ee9&quot;&gt;2 — Jakarta EE 9+&lt;/h3&gt;
&lt;p&gt;After Oracle turned the Java EE specs over to the Eclipse Foundation, they have since rebranded it as Jakarta EE. This includes &lt;strong&gt;servlets&lt;/strong&gt;, &lt;strong&gt;JMS&lt;/strong&gt;, &lt;strong&gt;JPA&lt;/strong&gt;, and many others. What was once &lt;em&gt;&lt;strong&gt;Java Messaging Service&lt;/strong&gt;&lt;/em&gt; is now &lt;em&gt;&lt;strong&gt;Jakarta Messaging Service&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And Jakarta EE 9 is the version where all these specs changes their package prefix from &lt;strong&gt;javax&lt;/strong&gt; to &lt;strong&gt;jakarta&lt;/strong&gt;. (Oracle wouldn’t grant Eclipse the javax prefix nor give them any sort of license).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fun fact, Apache Tomcat 10 reached end of life sometime last month. To pick up the next iteration of Tomcat, Spring Boot has adopted Jakarta EE 10 regarding servlets. However, there isn’t a lot of differences between Jakarta EE 9 and 10, so various parts of the portfolio work with both.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yours truly had to really work over the last few months to make Spring Web Services catch up to Jakarta EE 9+ considering SOAP stuff probably has the most hooks into Java…err…&lt;em&gt;Jakarta&lt;/em&gt; specs.&lt;/p&gt;
&lt;p&gt;But that is not all that is coming with Spring Boot 3.0.&lt;/p&gt;
&lt;h3 id=&quot;3graalvm-and-nativeimages&quot;&gt;3 — GraalVM and native images&lt;/h3&gt;
&lt;p&gt;The Spring team has been working for over a year at adding support for building native images so that your Spring Boot application could run in the mega-fast GraalVM, an alternative to the JVM.&lt;/p&gt;
&lt;p&gt;It started as an experimental module called Spring Native, to be added to Spring Boot 2.7 apps. But with Spring Boot 3.0, GraalVM support has been brought into the portfolio projects themselves.&lt;/p&gt;
&lt;p&gt;No Spring Native project needed.&lt;/p&gt;
&lt;p&gt;The team has worked to ensure Spring apps of all flavors are easy to build for GraalVM. Why? Because GraalVM is mind numbingly fast and very saavy with memory management.&lt;/p&gt;
&lt;p&gt;Again, why is this important? If you are running 1000 instances in your favorite cloud provider and you roll out a change, then 30 seconds of startup began to really add up (compared to native apps, which is for the sake of calculation, next to 0).&lt;/p&gt;
&lt;p&gt;Trimming off that 30 seconds of startup time can result in over 8 hours of startup time shaved off your monthly cloud bill.&lt;/p&gt;
&lt;p&gt;Imaging paying an 8 hour surtax for every commit! What if you pushed out a patch twice/week? That becomes 64 hours of needless time just to start up your app. The savings really kick in.&lt;/p&gt;
&lt;p&gt;But these aren’t the only things coming with Spring Boot 3.0. Each portfolio project has some really cool changes, which I’m not going to dive into in this article. Tell me in the comments which Spring projects YOU use the most!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out this video where you learn what Jakarta EE is and why it’s so important to the Spring portfolio.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_9gtSA7pLmSCFfsUEEzJKOg.B9q-WKPy.jpeg"/></item><item><title>Deleting code is the way to go!</title><link>https://www.procoder.io/articles/2022/2022-11-17_deleting-code-is-the-way-to-go--380454ba2971</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-11-17_deleting-code-is-the-way-to-go--380454ba2971</guid><description>I spotted a fun tweet earlier today that brought up one of the happiest moments in my coding career.</description><pubDate>Thu, 17 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I spotted a fun tweet earlier today that brought up one of the happiest moments in my coding career.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*J4N910uEhSmNL2PheuG56A.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;The celebration is over a couple Spring geeks having ripped out a HUGE and unnecessary bunch of bloat known as Node.&lt;/p&gt;
&lt;p&gt;Now before you laugh and howl (or cry and shout), this has nothing to do with Node. Instead, it’s about what’s needed vs. what’s cool. We ALL have a tendency to write using our favorite toolkits. It’s hard to shake!&lt;/p&gt;
&lt;p&gt;In fact, I recently wrote an article about &lt;a href=&quot;https://medium.com/@springbootlearning/when-to-not-use-spring-boot-96a64574497d&quot;&gt;&lt;em&gt;When to NOT use Spring Boot&lt;/em&gt;&lt;/a&gt;. This problem we software developers have is universal. I like Spring Boot, I tend to use it everywhere I go. Node devs like Node, they tend to use it everywhere they go.&lt;/p&gt;
&lt;p&gt;A veteran software developer must learn to rise above such strong emotional desires to run with our favorite toolkit, and ask the question, “What is BEST in this scenario?” And oftentimes, the corollary question, “What will the readers/users of this most likely know/not know?”&lt;/p&gt;
&lt;p&gt;Back when we published all the guides at &lt;a href=&quot;https://spring.io/guides,&quot;&gt;https://spring.io/guides,&lt;/a&gt; we put forth a guiding vision that each guide in and of itself would be self-contained. A guide wouldn’t be much of a guide if someone had to read three other side articles to finish it. And it also wouldn’t help if they had to complete some other guide first.&lt;/p&gt;
&lt;p&gt;No, none of that would fly. So we made the decision to make each guide self-contained, and to explain all the key bits by the end. Someone giving away their lunch break to try and grow their Spring knowledge needed to be rewarded with a feeling of accomplishment. And that’s exactly what we did.&lt;/p&gt;
&lt;p&gt;At the top of this article I mentioned “one of the happiest moments of my career”. That would be the time before I joined the Spring team. I took over someone else’s back office application. Something that had cost literally MILLIONS in invested time (six previous developers had apparently handled it). And it was NON-OPERATIONAL.&lt;/p&gt;
&lt;p&gt;This app, meant to digest about 300 monthly invoices and spot discrepancies, had been gobbled up in “patternization”. (Patternization is a word I just made up to indicate usage of patterns exceeds value of patterns.)&lt;/p&gt;
&lt;p&gt;This app’s purpose for the accounting department to go through statements, spot problems, and issue corrections so we could not pay so much. And we’re MILLIONS of dollars. Every month.&lt;/p&gt;
&lt;p&gt;The app simply didn’t work.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*5M35jB8OgYCu0FlqAMO9Xw.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;These invoices were spreadsheets and the app had a beautiful abstraction for rows and columns. But it simply didn’t work.&lt;/p&gt;
&lt;p&gt;These 300 invoices actually had about five special formats (not 300), so they weren’t unpredictable. But it simply didn’t work.&lt;/p&gt;
&lt;p&gt;The requirements were almost unchanging. But it simply didn’t work.&lt;/p&gt;
&lt;p&gt;For something so small in scope, so simple in requirements, and so slow to change, it was strange (to me) that it didn’t work.&lt;/p&gt;
&lt;p&gt;When I picked it up, I vowed to not change a single line of code without writing a test case first. (The app had next to NO test cases). And so I got busy.&lt;/p&gt;
&lt;p&gt;I wrote painstaking test cases. And edited code. Another test case, another patch. Another test case, another tweak. And soon, in the span of 1–2 months, I built up a suite of tests.&lt;/p&gt;
&lt;p&gt;And I reached a point of awareness where I KNEW that spreadsheet abstraction served no purpose. And I also knew I could rip it out without anything being damaged.&lt;/p&gt;
&lt;p&gt;And so I did.&lt;/p&gt;
&lt;p&gt;I deleted a chunk of code, and suddenly the whole app leaped forward in speed. I was running this test suite at least once a day. It would often take 30 minutes to execute. It would also creep up toward an hour, and I’d spend a day tracking down what needed to be fixed, be it tests or production code.&lt;/p&gt;
&lt;p&gt;The spreadsheet abstraction wasn’t the only thing I ripped out. I yanked other stuff that my test suite exposed as unnecessary.&lt;/p&gt;
&lt;p&gt;I also started meeting with program managers, the users, and others. I started to implement features they needed. I also kept writing tests.&lt;/p&gt;
&lt;p&gt;Once, I ripped out a HUGE chunk of code…&lt;/p&gt;
&lt;p&gt;…and break half the tests. Three hours later, it still didn’t work. So I scrapped all the changes I’d made for the day and went home worn out.&lt;/p&gt;
&lt;p&gt;Next day, I started fresh, and moved in a different way. The tests had told me that I had gone too far, and gave me the confidence to back up and start over.&lt;/p&gt;
&lt;p&gt;Merrily moving along over the next six months, I was meeting weekly with the users. The application was working. The users were actually doing their jobs much faster. We would get together, brainstorm new ideas which I’d collect in a slideshow. One page per “idea”.&lt;/p&gt;
&lt;p&gt;And I’d go back to my desk, translate these slides into test cases (one test case per slide) using the lingo we had spoken in the meeting. And I’d code the corresponding solution.&lt;/p&gt;
&lt;p&gt;Tests STILL took about 30 minutes to run. But then something happened.&lt;/p&gt;
&lt;p&gt;My manager called me into his office. He was preparing for the next quarterly meeting with the VP of engineering and was putting together his report.&lt;/p&gt;
&lt;p&gt;He showed me the lines of code they ran, and pointed at my application. Instead of having an exponential GROWTH curve, it instead had an upside-down PARABOLA shape. Indeed, I had REDUCED the total amount of code in this application by a HUGE amount.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*6tWyricDm4Migrr8XAVQ5g.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And the application did more than EVER. And…&lt;/p&gt;
&lt;p&gt;…it worked.&lt;/p&gt;
&lt;p&gt;The application simply worked. It met the needs of the users. They were getting through monthly invoice reconciliation at a slim and trim speed. Considering these users operated on overhead, this had caught the attention of upper management.&lt;/p&gt;
&lt;p&gt;And they couldn’t be more pleased. Total cost of maintenance was DOWN while throughput was UP.&lt;/p&gt;
&lt;p&gt;All because of a solemn promise I made to myself.&lt;/p&gt;
&lt;p&gt;Don’t fix anything without writing a test case to capture it.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out this video where you can learn EXACTLY what you need to do to increase the value you present to your team and how to cushion yourself from these economic challenges.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="310" height="86" medium="image" url="https://www.procoder.io//_astro/1_J4N910uEhSmNL2PheuG56A.BnQy3p28.png"/></item><item><title>Using Micrometer to trace your Spring Boot app</title><link>https://www.procoder.io/articles/2022/2022-11-10_using-micrometer-to-trace-your-spring-boot-app-1fe6ff9982ae</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-11-10_using-micrometer-to-trace-your-spring-boot-app-1fe6ff9982ae</guid><description>If there’s one thing that eventually sneaks up on you after building and releasing an application, it’s that something breaks. Yup…</description><pubDate>Thu, 10 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If there’s one thing that eventually sneaks up on you after building and releasing an application, it’s that something breaks. Yup, applications break and not long after, our manager is asking, “What happened?”&lt;/p&gt;
&lt;p&gt;That’s not the only thing we encounter in the Land of Production. We also sometimes see performance degrade. Certain parts of our system seem bogged down. And once again, the question arises, “What’s going on?”&lt;/p&gt;
&lt;p&gt;This is what tracing affords us. A means to trace an operation through our application combined with metrics showing us what’s eating up all the time. And for this we turn to &lt;strong&gt;Micrometer&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Micrometer, launched in 2017 by the Spring team, it a metrics facade. It supports a whole host of tools, but for today we’ll use the open source distributed tracing system Zipkin.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-a-spring-boot-3-application&quot;&gt;Setting up a Spring Boot 3 application&lt;/h3&gt;
&lt;p&gt;Do you already have a Spring Boot 3 app you’d like to instrument? Great! You can skip on to the next section. In case you don’t, you’ll want to file some very simple steps.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Visit &lt;a href=&quot;https://start.spring.io&quot;&gt;https://start.spring.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pick your favorite build tool. (I’ll be using &lt;strong&gt;Maven&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Pick the latest version of &lt;strong&gt;Spring Boot 3&lt;/strong&gt;. (I’ll be using 3.0.0-SNAPSHOT).&lt;/li&gt;
&lt;li&gt;Just leave the project metadata as is.&lt;/li&gt;
&lt;li&gt;From the dependencies panel on the right, pick &lt;strong&gt;Spring Web&lt;/strong&gt; and &lt;strong&gt;Actuator&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;GENERATE&lt;/strong&gt; button, download the ZIP file, unpack it, and import it into your favorite IDE!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With that in place, you’re all set to get going!&lt;/p&gt;
&lt;h3 id=&quot;adding-micrometer-to-your-spring-boot-3-application&quot;&gt;Adding Micrometer to your Spring Boot 3 application&lt;/h3&gt;
&lt;p&gt;The first step to instrumenting your application is to add Micrometer. Now it’s important to understand that Micrometer actually has two key aspects: &lt;strong&gt;tracing&lt;/strong&gt; and &lt;strong&gt;metrics&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tracing — seeing WHAT happened&lt;/li&gt;
&lt;li&gt;Metrics — seeing HOW LONG it took to happen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sometimes people want one of the other. But for this article, we’ll do both. And to do that, you need to add the following to your build file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;groupId&gt;io.micrometer&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;artifactId&gt;micrometer-observation&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;groupId&gt;io.micrometer&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;artifactId&gt;micrometer-tracing-bridge-brave&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;dependency&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;groupId&gt;io.zipkin.reporter2&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;artifactId&gt;zipkin-reporter-brave&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/dependency&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;micrometer-observation — this pulls in the Micrometer code responsible for making Observations.&lt;/li&gt;
&lt;li&gt;micrometer-tracing-bridge-brave — this pulls in the Micrometer Tracing facade along with glue code to use Brave, the tracing solution from the Zipkin team.&lt;/li&gt;
&lt;li&gt;zipking-reporter-brave — a little more glue code to adapt Zipkin with Brave.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There’s a lot of terms thrown in there, so let’s discuss a little further. Micrometer has a concept called an &lt;strong&gt;Observation&lt;/strong&gt;. This is when you essentially want to “see” what has happened during a key operation. This could be when a web request is made. Or when a database is accessed. The idea is that you A) start the Observation, B) do the action, and C) stop the Observation.&lt;/p&gt;
&lt;p&gt;What if you wrap an &lt;strong&gt;Observation&lt;/strong&gt; around a web method in your Spring MVC controller? Does this mean, that if inside the web controller, a Spring Data repository is invoked, we’d have to repeat the SAME PATTERN there too?&lt;/p&gt;
&lt;p&gt;Yes…and no.&lt;/p&gt;
&lt;h3 id=&quot;instrumenting-yourcode&quot;&gt;Instrumenting your code&lt;/h3&gt;
&lt;p&gt;Micrometer’s APIs are carefully designed such that when you start an Observation, the context of the scenario is stored and then passed along. For a a classic Spring MVC app, thread locals are used. This is done in a way such that every method in the call stack is able to grab the &lt;strong&gt;Observation&lt;/strong&gt; and add to it. Essentially, more information can be gathered.&lt;/p&gt;
&lt;p&gt;So this is the “yes” part of the answer. To trace every step in a call stack, you need to do this pattern in every method.&lt;/p&gt;
&lt;p&gt;But the “no” part is that YOU DON’T HAVE to.&lt;/p&gt;
&lt;p&gt;The Spring team has been working diligently at instrumenting all levels of the portfolio such that it’s already done. Building a Spring MVC controller? The &lt;strong&gt;DispatcherServlet&lt;/strong&gt; and all its components will have already started an &lt;strong&gt;Observation&lt;/strong&gt; before you web method is called.&lt;/p&gt;
&lt;p&gt;Making a remote HTTP call to a 3rd party service? The Spring Framework team has instrumented &lt;strong&gt;RestTemplate&lt;/strong&gt; and &lt;strong&gt;WebClient&lt;/strong&gt; so the &lt;strong&gt;Observation&lt;/strong&gt; pattern wraps around every remote call made. (And Micrometer is slick enough to pass along the tracing context over network boundaries!)&lt;/p&gt;
&lt;h3 id=&quot;running-your-own-copy-ofzipkin&quot;&gt;Running your own copy of Zipkin&lt;/h3&gt;
&lt;p&gt;To make the magic happen, you need to run your own copy of Zipkin. Using Docker, this is a snap. Just execute the following command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker run -d -p 9411 openzipkin/zipkin:latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you execute this, you can then visit the it at localhost:9411.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*bJFzH6OQVsiajWKnPeNWhQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;With that in place, you just need to do some final tweaking to get your application ready to go.&lt;/p&gt;
&lt;h3 id=&quot;configuring-your-spring-boot-application-fortracing&quot;&gt;Configuring your Spring Boot application for tracing&lt;/h3&gt;
&lt;p&gt;It doesn’t take much.&lt;/p&gt;
&lt;p&gt;For starters, does your application include spring-boot-starter-actuator? The Actuator module is required for tracing to operate. If not, go update your build file. I’ll wait.&lt;/p&gt;
&lt;p&gt;Now add the following attribute to your &lt;strong&gt;application.properties&lt;/strong&gt; file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;*# Trace every action*management.tracing.sampling.probability=1.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, Micrometer only traces 10% or 0.1 of the time. This is to avoid taxing your system too much. (Actually a problem I’ve seen in my career is that tracing can get WAY out of control.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We’re ONLY dialing up the levels to make it easier to see the tracing. For a real world, production system, you may want to back off to 0.1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;coding-a-spring-mvc-controller&quot;&gt;Coding a Spring MVC controller&lt;/h3&gt;
&lt;p&gt;If you already have a controller, then you’re all set. If not, you can borrow mine!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@RestController  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class EmployeeController {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   private static final List&amp;#x3C;Employee&gt; *DB* = new ArrayList&amp;#x3C;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   static {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      *DB*.add(new Employee(&quot;1&quot;, &quot;Frodo&quot;, &quot;ring bearer&quot;));  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      *DB*.add(new Employee(&quot;2&quot;, &quot;Bilbo&quot;, &quot;burglar&quot;));  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   @GetMapping(&quot;/api/employees&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   List&amp;#x3C;Employee&gt; all() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      return *DB*;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   @GetMapping(&quot;/api/employees/{id}&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Employee one(@PathVariable String id) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      return *DB*.stream() *//* .filter(employee -&gt; employee.getId().equals(id)) *//* .findFirst() *//* .orElseThrow(() -&gt; new RuntimeException(&quot;Couldn&apos;t find &quot; + id));  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With all this, we’re ready to do some tracing!&lt;/p&gt;
&lt;h3 id=&quot;tracing-the-application&quot;&gt;Tracing the application&lt;/h3&gt;
&lt;p&gt;Fire up the application by running the class that has the @SpringBootApplication annotation. Now on the command line, run this command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;curl -v localhost:8080/api/employees&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*eGp8fCLFLWe76Fx-UO32Wg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;(I actually use &lt;code&gt;brew install jq&lt;/code&gt; and pipe the outputs through that, to make it easier to read)&lt;/p&gt;
&lt;p&gt;This shows our little demo data being nicely printed out on the command line. But what can we expect to see if we hop on over to Zipkin at localhost:9411?&lt;/p&gt;
&lt;p&gt;Hit the RUN QUERY button, and you should something like printed out below:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*FlTVhX-d0_aFPcB_sEj6hA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This is the Spring MVC web call just made. The whole duration of that Observation was about 18 ms.&lt;/p&gt;
&lt;p&gt;Click on SHOW and you can see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*c2yqneG1r7Jt-ek3rDV4lQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;You can see the same duration at the top. It’s also tagged contextually as an “application”.&lt;/p&gt;
&lt;p&gt;You can see bonus tags that context additional content about the web request including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;exception: &lt;strong&gt;none&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;http.url: &lt;strong&gt;/api/employees&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;method: &lt;strong&gt;GET&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;status: &lt;strong&gt;200&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is more.&lt;/p&gt;
&lt;p&gt;You may also be interested to know that there is a movement afoot known as OpenTelemetry that strives to have a consistent set of tag names such that ALL tracing tools can offer a more consistent dialect, making it easier for you and I to consume this type of output.&lt;/p&gt;
&lt;p&gt;Micrometer strives to uphold this standard and has shifted many of its tags to fit this nomenclature.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In fine print, you can find its Span ID. A Span ID is kind of a decoder ring issued by Micrometer. They are automatically generated every time you create a new Observation. And they are passed along in thread locals, in web request headers to remote services, returned in web response headers, and even propagated through reactive subscriber contexts. These spans and their IDs make it possible to track the performance of every hop along the way and bring home all the data to trace your app.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With all this, you are able to start tracing your application and see what’s happening.&lt;/p&gt;
&lt;p&gt;Now if this felt a little contrived because there was no database layer or remote web service layer, I hear you. However, this article has gotten a little long, but I’m working on another one, where we will see how to hook in a REAL database!&lt;/p&gt;
&lt;p&gt;If you want to see more articles about Micrometer and Spring Boot in general, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where we explore how to serve up web templates using Spring Boot 3!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="566" medium="image" url="https://www.procoder.io//_astro/1_bJFzH6OQVsiajWKnPeNWhQ.Cj0NSIJP.png"/></item><item><title>How to serve a web template with Spring Boot</title><link>https://www.procoder.io/articles/2022/2022-11-03_how-to-serve-a-web-template-with-spring-boot-bbbf7bbf6e2f</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-11-03_how-to-serve-a-web-template-with-spring-boot-bbbf7bbf6e2f</guid><description>If you’re building a Spring Boot application, then odds are, you’re building a web app. Web apps have been on the rise for twenty years…</description><pubDate>Thu, 03 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;how-to-serve-a-web-template-with-spring-boot&quot;&gt;How to serve a web template with Spring Boot&lt;/h1&gt;
&lt;p&gt;If you’re building a Spring Boot application, then odds are, you’re building a web app. Web apps have been on the rise for twenty years…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-to-serve-a-web-template-with-springboot&quot;&gt;How to serve a web template with Spring Boot&lt;/h3&gt;
&lt;p&gt;If you’re building a Spring Boot application, then odds are, you’re building a web app. Web apps have been on the rise for twenty years. And with Spring Boot, it’s easier than EVER to build one!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*MiR1XP-icX6K4CpFSgqU3g.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;So let’s get to it!&lt;/p&gt;
&lt;h3 id=&quot;1gettingstarted&quot;&gt;1 — Getting started&lt;/h3&gt;
&lt;p&gt;To build ANY Spring Boot application, you’ll want to visit &lt;a href=&quot;https://start.spring.io.&quot;&gt;https://start.spring.io.&lt;/a&gt; This magical web site lets you grab everything you need to build an app. Pick the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build system: Pick your favorite. I like Maven, but many love Gradle.&lt;/li&gt;
&lt;li&gt;Language: Leave this on &lt;strong&gt;Java&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Spring Boot: Pick &lt;strong&gt;3.0.0-SNAPSHOT&lt;/strong&gt; (living on the edge!)&lt;/li&gt;
&lt;li&gt;Project Metadata: Leave it be.&lt;/li&gt;
&lt;li&gt;Dependencies: &lt;strong&gt;Spring Web&lt;/strong&gt; and &lt;strong&gt;Mustache&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With all this selection, click GENERATE. You’ll get a ZIP download. Unpack it and then import that new folder into your favorite IDE.&lt;/p&gt;
&lt;h3 id=&quot;2building-a-domain-of-knowledge&quot;&gt;2 — Building a domain of knowledge&lt;/h3&gt;
&lt;p&gt;We need SOMETHING to put on it. Since this is Spring Boot 3 and we’re on Java 17, we can use records to define a nice simple type:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record Video(String name) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’ll create a one-field record type that represents a YouTube video. (Why not?)&lt;/p&gt;
&lt;p&gt;Java 17 records don’t require constructors, equals, hashCode, or toString methods. They come fully loaded. Yes, it’s possible to augment them, but for the simplest of POJOs, this is all it takes!&lt;/p&gt;
&lt;h3 id=&quot;3assembling-a-controller&quot;&gt;3 — Assembling a controller&lt;/h3&gt;
&lt;p&gt;Controllers are classes that process web requests. And so, to serve up a web template, we’ll need one!&lt;/p&gt;
&lt;p&gt;Make a &lt;strong&gt;HomeController&lt;/strong&gt; class like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Controller  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class HomeController {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;private List&amp;#x3C;Video&gt; videos = List.*of*( *//* new Video(&quot;Need HELP with your SPRING BOOT 3 App?&quot;), *//* new Video(&quot;Don&apos;t do THIS to your own CODE!&quot;), *//* new Video(&quot;SECRETS to fix BROKEN CODE!&quot;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @GetMapping(&quot;/&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  public String index(Model model) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    model.addAttribute(&quot;videos&quot;, videos);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return &quot;index&quot;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;@Controller&lt;/strong&gt; annotation lets Spring Boot know that this class handles web requests and uses a templating engine.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;@GetMapping(“/”)&lt;/strong&gt; annotation signals that this &lt;strong&gt;index()&lt;/strong&gt; method will process &lt;strong&gt;HTTP GET /&lt;/strong&gt; calls. Since we want to populate the template with data (well, canned data in this article), we have injected a Spring Model object.&lt;/p&gt;
&lt;p&gt;We set attribute “videos” with the actual values from our little List of Video objects. Anything assigned to this model will be merged with the generated web page.&lt;/p&gt;
&lt;p&gt;Finally, we return the name of the template we wish to render. Now Spring Boot will take this name and marry it with the templating engine of choice to actually find the template, which we’ll cover in the next section.&lt;/p&gt;
&lt;h3 id=&quot;4crafting-a-templating&quot;&gt;4 — Crafting a templating&lt;/h3&gt;
&lt;p&gt;Since we used Mustache, Spring Boot will expand the name “index” into src/main/resources/templates/index.mustache. Create a file of that name and add the following:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;h1&gt;Greetings Spring Boot Learning readers!&amp;#x3C;/h1&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;ul&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  {{#videos}}  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;li&gt;{{name}}&amp;#x3C;/li&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  {{/videos}}  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/ul&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;form action=&quot;/new-video&quot; method=&quot;post&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;input type=&quot;text&quot; name=&quot;name&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;button type=&quot;submit&quot;&gt;Submit&amp;#x3C;/button&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/form&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mustache is incredibly lightweight. The &lt;strong&gt;{{#videos}}&lt;/strong&gt; tag (notice the sideways mustaches?) is the directive to expand the list of the “videos” attribute into a separate &lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;li&gt; element for each entry in that list.&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Each entry is then accessible by property name. Given our Video object has a “name” field, we can reach each it using &lt;strong&gt;{{name}}&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The rest is a simple HTML form with one text input for the “name” and a submit button.&lt;/p&gt;
&lt;h3 id=&quot;5processing-a-newentry&quot;&gt;5 — Processing a new entry&lt;/h3&gt;
&lt;p&gt;To consume this form, we need to go back to the &lt;strong&gt;HomeController&lt;/strong&gt; and another web method handler, like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@PostMapping(&quot;/new-video&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public String newVideo(@ModelAttribute Video newVideo) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  List&amp;#x3C;Video&gt; extend = new ArrayList&amp;#x3C;&gt;(videos);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  extend.add(newVideo);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  this.videos = List.*copyOf*(extend);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return &quot;redirect:/&quot;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Spring Web’s &lt;strong&gt;@PostMapping&lt;/strong&gt; annotation maps the &lt;strong&gt;HTTP POST /new-video&lt;/strong&gt; call onto this method. And the &lt;strong&gt;@ModelAttribute&lt;/strong&gt; will deserialize the incoming data from the HTML form into another Video object.&lt;/p&gt;
&lt;p&gt;Earlier in this article, we initialized videos using &lt;strong&gt;List.of()&lt;/strong&gt;, which creates an immutable list. To expand it, we have to effectively replace it with a bigger one. And so create a new list, add the new entry, and then use &lt;strong&gt;List.copyOf()&lt;/strong&gt; to produce a new, immutable one.&lt;/p&gt;
&lt;p&gt;Finally, with the new entry added, we can return back a &lt;strong&gt;“redirect:/”&lt;/strong&gt;, which will tell the browser to redirect back to &lt;strong&gt;“/”&lt;/strong&gt;, which should hit our first web method coded earlier, causing it to re-render the original template but with our new data.&lt;/p&gt;
&lt;p&gt;With all this in place, we can now run the class original generated by start.spring.io that has the &lt;strong&gt;@SpringBootApplication&lt;/strong&gt; annotation applied and take our application for a spin.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can get a deeper dive with the fun that is Spring MVC!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;</content:encoded><media:content type="image/png" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_MiR1XP-icX6K4CpFSgqU3g.UhRtyAQ4.png"/></item><item><title>Spring Boot 3.0 approaches!</title><link>https://www.procoder.io/articles/2022/2022-10-27_spring-boot-3-0-approaches--b19b5e66f3fd</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-10-27_spring-boot-3-0-approaches--b19b5e66f3fd</guid><description>We’re getting into the home stretch. With Spring Boot 3.0.0-RC1 coming out last week, some wickedly cool stuff is headed your way.</description><pubDate>Thu, 27 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We’re getting into the home stretch. With Spring Boot 3.0.0-RC1 coming out last week, some wickedly cool stuff is headed your way.&lt;/p&gt;
&lt;h3 id=&quot;1jakarta-ee9&quot;&gt;1 — Jakarta EE 9&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*ZjlDJpdmM58gNUuznfXQ9A.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;I recently created a video on exactly what Jakarta EE is in the grand scheme of Java, but the nugget to chew on is that Spring Boot 3.0 will be bearer of Jakarta EE 9.&lt;/p&gt;
&lt;p&gt;This is the version where all the enterprise specs migrate from &lt;code&gt;javax.*&lt;/code&gt; to &lt;code&gt;jakarta.*&lt;/code&gt; .&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some specs are part of the Java SE and never were part of Java EE, so they are not part of Jakarta EE 9. This includes stuff like JDBC, which I flubbed my recent video by mentioning it as one of the standards that migrates. It does not. But JMS, servlets, JNDI, and most everything else is!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And it’s not just that the package names are moving. The latest releases for our most favorite packages will be there, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apache Tomcat 10&lt;/li&gt;
&lt;li&gt;Jetty 11&lt;/li&gt;
&lt;li&gt;Hibernate ORM 6.1&lt;/li&gt;
&lt;li&gt;ActiveMQ Artemis&lt;/li&gt;
&lt;li&gt;more!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To keep up with the hottest, most popular Java packages out there, it’s time to pick up and run with Jakarta EE 9.&lt;/p&gt;
&lt;h3 id=&quot;2native-applications-ongraalvm&quot;&gt;2 — Native applications on GraalVM&lt;/h3&gt;
&lt;p&gt;GraalVM is an alternative to the JVM and allows you to run “native” applications. This means faster start up times, more efficient memory usage, and other slick benefits.&lt;/p&gt;
&lt;p&gt;To help you pick up and run with it, Spring Native was released as an extra package to ease usage with Spring Boot 2.7.&lt;/p&gt;
&lt;p&gt;With Spring Boot 3.0, that support is built in. No Spring Native module required. And the rest of the Spring portfolio is also adopting the needed tweaks and adjustments to make Spring native-ready.&lt;/p&gt;
&lt;p&gt;On top of that, the Spring team has been working hand-in-hand with Oracle, the purveyors of GraalVM, to ensure the entire experience is smooth and operational.&lt;/p&gt;
&lt;p&gt;If you haven’t explored native applications, Spring Boot 3.0 may be the place to give it a go.&lt;/p&gt;
&lt;h3 id=&quot;3java-17lts&quot;&gt;3 — Java 17 LTS&lt;/h3&gt;
&lt;p&gt;Spring Boot 3.0/Spring Framework 6.0 is moving the baseline of Java support up to the latest LTS (Long Term Support) version 17.&lt;/p&gt;
&lt;p&gt;Now Spring has always been cautious to avoid forcing people to jump too soon to a newer version of Java. That’s why, in the past, there has been ample support for features found in newer versions of the JDK, without forcing their adoption.&lt;/p&gt;
&lt;p&gt;But with Java 17 having gone GA in September of 2021, support from vendors like Oracle all the way into 2026 (and extended support off to 2029), Java 17 is a safe bet for your next Spring Boot application.&lt;/p&gt;
&lt;p&gt;Java 17 also come chock full of some of the coolest features as well. Not only is it much more performant than Java 8, there are lots of cool features including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pattern matching for instanceof checks&lt;/li&gt;
&lt;li&gt;Records&lt;/li&gt;
&lt;li&gt;Sealed classes&lt;/li&gt;
&lt;li&gt;Text blocks&lt;/li&gt;
&lt;li&gt;Switch expressions&lt;/li&gt;
&lt;li&gt;A huge bump in the various Collections operations (including things like List.of, Map.of, Set.of, etc.)&lt;/li&gt;
&lt;li&gt;Pattern matching with switch operations (preview feature)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this fully armed and operational JDK, who can say no?&lt;/p&gt;
&lt;h3 id=&quot;4project-loomarrives&quot;&gt;4 — Project Loom arrives&lt;/h3&gt;
&lt;p&gt;Project Loom, through JEP-425, brings lightweight Virtual Threads as a new concurrency model to build applications on top of.&lt;/p&gt;
&lt;p&gt;We’ve heard lots of rumors, promises, and even some strong back-and-forth. JEP-425 has landed Project Loom as a preview feature in Java 19.&lt;/p&gt;
&lt;p&gt;Project Loom isn’t specifically a Spring Boot 3.0 feature. Instead, it’s an easy to grab thing since you’ll already be starting any new Spring Boot 3.0 application using Java 17. It’s as easy as &lt;code&gt;sdk install java &amp;#x3C;your favorite vendor&apos;s v.19 JDK&gt;&lt;/code&gt; to install, and simply bump &lt;code&gt;java.version&lt;/code&gt;to &lt;code&gt;19&lt;/code&gt;in your build file!&lt;/p&gt;
&lt;p&gt;With that in place, you can easily start exploring. There is a LOT of hunger in the market for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More efficient usage of existing resources.&lt;/li&gt;
&lt;li&gt;Easier ways to scale applications.&lt;/li&gt;
&lt;li&gt;Faster throughput on the whole.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We have been looking for silver bullets for years. Sadly, there are none. Nothing “magically” speeds anything up.&lt;/p&gt;
&lt;p&gt;But there is no better time than now to evaluate which tactics are right for you. That’s why you should read Spring Data team leader Mark Paluch’s article &lt;a href=&quot;https://spring.io/blog/2022/10/11/embracing-virtual-threads&quot;&gt;&lt;strong&gt;Embracing Virtual Threads&lt;/strong&gt;&lt;/a&gt; to get the long and short on what Project Loom ACTUALLY does, how it does it, and whether or not it will help your application scale or not.&lt;/p&gt;
&lt;h3 id=&quot;5springone-is-just-around-thecorner&quot;&gt;5 — SpringOne is just around the corner!&lt;/h3&gt;
&lt;p&gt;Last but not least is the SpringOne conference coming the first week of December in San Francisco. It’s certainly not too late to register at &lt;a href=&quot;https://springone.io/register&quot;&gt;https://springone.io/register&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’ll be there along with the rest of the Spring team, excited to share with you the glory that is Spring Boot 3.0.&lt;/p&gt;
&lt;p&gt;BTW, I’ll be giving my talk &lt;a href=&quot;https://springone.io/2022/sessions/its-10pm-do-you-know-where-your-relational-data-store-is&quot;&gt;&lt;strong&gt;It’s 10 PM: Do You Know Where Your Relational Data Store Is?&lt;/strong&gt;&lt;/a&gt;, so if you’re there, don’t miss it!&lt;/p&gt;
&lt;p&gt;Even if you DON’T sign up for my talk, if you’re in the vicinity, don’t hesitate to say “Hey!”&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can learn EXACTLY what it is about Jakarta EE that makes it so special…and made it controversial in the past!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_ZjlDJpdmM58gNUuznfXQ9A.s6J26Lxk.png"/></item><item><title>The way software will be in the future (or today!)</title><link>https://www.procoder.io/articles/2022/2022-10-20_the-way-software-will-be-in-the-future--or-today---5ddfa6853208</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-10-20_the-way-software-will-be-in-the-future--or-today---5ddfa6853208</guid><description>Software is eating the world. — Marc Andreeessen</description><pubDate>Thu, 20 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Software is eating the world. — Marc Andreeessen&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You’ve probably heard this phrase, whether you read the original article in the Wall Street Journal back in 2011, or you’ve heard it echoed by CEOs, senior vice presidents, or a senior manager.&lt;/p&gt;
&lt;p&gt;But it’s not just that. Not only has EVERY COMPANY had to pivot toward become a software-oriented company. Everyone is having to evolve toward a certain TYPE of software company.&lt;/p&gt;
&lt;p&gt;You see there are several &lt;strong&gt;key factors&lt;/strong&gt; which every software company is feeling the pressure to adopt which we’ll cover in this article.&lt;/p&gt;
&lt;h3 id=&quot;1continuous-delivery-pipelines&quot;&gt;1 — Continuous delivery pipelines&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*YR_8yBKB506IwOxF_YAUig.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;If there’s anything that has evolved over the past 25 years, it’s our ability to move from building our software every three months or twice a year toward a continuous integration/continuous delivery pipeline.&lt;/p&gt;
&lt;p&gt;Shops are picking up and running the ability to have every single commit, when pushed to their source code repository, build the whole app.&lt;/p&gt;
&lt;p&gt;Whether you’re using Jenkins, GitHub Actions, CircleCI, Concourse, or whatever, people want to know if their latest change broke anything.&lt;/p&gt;
&lt;p&gt;Maybe if you’re building an app for a Uni program or some 12-week training program you aren’t doing it. But the shop you join after that PROBABLY is. I’ve &lt;a href=&quot;/articles/medium/2022-08-25_what-no-university-will-teach-but-is-vital-to-your-career--7b78802e72c1&quot;&gt;mentioned this before&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A handy talent to build up is your ability to construct and manage pipelines.&lt;/p&gt;
&lt;p&gt;I happen to be the “guru” for the Spring Data team’s CI operations and manage the pipelines we use for tracking all supported branches of our 17-module system. And if you were to visit Netflix engineering, you’d discover they have an even bigger undertaking as they use Spinnaker to manage the bulk of their online services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Continuous integration&lt;/strong&gt; is what lets you know that your latest patch or feature hasn’t broken the main line system.&lt;/p&gt;
&lt;p&gt;And this is vital.&lt;/p&gt;
&lt;p&gt;Research over the decades has revealed that the faster we can discover a bug and fix it, the lower our development costs will be. So it makes sense to let software…build our software, right?&lt;/p&gt;
&lt;p&gt;On top of that, MANY shops are adopting a &lt;strong&gt;continuous delivery&lt;/strong&gt; approach.&lt;/p&gt;
&lt;p&gt;Continuous delivery is where go one step further than continuous integration and actually RELEASE your newly minted artifacts. This is usually a snapshot, so the people picking this up aren’t USUALLY the people running the most risk averse systems.&lt;/p&gt;
&lt;p&gt;But look at shops like Netflix where they will upgrade their own systems to pick up tweaks and fixes. They even have rolling upgrades so perhaps 10% of the active nodes migrate to the fix, run it for a few hours, see if everything is good, and then let the rest of the nodes upgrade.&lt;/p&gt;
&lt;p&gt;That is the extreme and probably NOT what most shops are doing.&lt;/p&gt;
&lt;p&gt;But the ability to push out snapshots to maven central or artifactory, publish snapshot containers to Docker Hub automatically, and continuously push updates and bug fixes to tentative customers is slowly but surely becoming the norm and NOT the exception.&lt;/p&gt;
&lt;p&gt;Don’t fight it…EMBRACE IT!&lt;/p&gt;
&lt;p&gt;However, you can’t do ANY of this if you don’t do the next thing on the list.&lt;/p&gt;
&lt;h3 id=&quot;2secure-pipelines&quot;&gt;2 — Secure pipelines&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*FFoIZSDrSHShPfeCa_E8MQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Secure pipelines are about controlling all the moving parts in your software release cycle and NOT about your continuous integration pipelines.&lt;/p&gt;
&lt;p&gt;If your shop does NOT control every point between your source code repository all the way to your distribution location like Docker Hub, then you could be vulnerable to attack.&lt;/p&gt;
&lt;p&gt;Maybe you remember the days of Leftpad, a developer that decided to unpublish an 11-line library from npm. A library that apparently was used by LOTS of other small libraries, that ultimately through a chain of tools, was used by some of the biggest JavaScript toolkits out there including ReactJS.&lt;/p&gt;
&lt;p&gt;Secure pipelines isn’t just about managing 3rd party dependencies. It begins to cover the issue of what-happens-if-our-release-engineer-gets-run-over-by-a-bus scenario. If losing one person can take down your system, you’re vulnerable.&lt;/p&gt;
&lt;p&gt;It also extends into the realm of what-if-your-release-machine-were-compromised scenarios.&lt;/p&gt;
&lt;p&gt;The idea is to have controlled machines able to handle your entire release process instead of user-maintained ones. Yes, it’s nice to Do It All Yourself™, but this also makes your personal machine a tasty asset to hackers. Whereas if you can delegate that task to your CI server and entrust security engineering and the sys admins to properly harden and protect your system assets, the risk shrinks.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Risk is NEVER 0. There will ALWAYS be risk. But we shouldn’t be foolhardy and take reasonable measures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If your organization is trying to embrace security pipelines with controlled access to source code, CI servers, and release credentials for Docker Hub, maven central, etc., then don’t fight it. You are swimming upstream.&lt;/p&gt;
&lt;p&gt;And I’m not saying to go along for no good reason.&lt;/p&gt;
&lt;p&gt;Develop software locally on your work machine. But let properly protected and secured servers handle the infrastructure of it all. In the end, automated tooling will pay off and result in less weekend fires you have to put out. And you’ll sleep better at night.&lt;/p&gt;
&lt;p&gt;Because you’ll need that to focus on the next point.&lt;/p&gt;
&lt;h3 id=&quot;3alwaysready&quot;&gt;3 — Always ready&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*GtldMXt83ozu4WRwXvLDfQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Over the past twenty years, the number of around-the-clock always-on systems has grown by leaps and bounds. Having worked on a 24x7x365 Ops center at my previous job, I’m all too familiar with the challenges of keeping things Always On.&lt;/p&gt;
&lt;p&gt;But we live in an international market.&lt;/p&gt;
&lt;p&gt;Just because you’re asleep doesn’t mean your custom is asleep. Your systems need to be up and operational. And this means more testing, more realistic test scenarios, and more 9’s of availability. (Bonus points if you know what 9’s of availability even are. Let me know in the comments below!)&lt;/p&gt;
&lt;p&gt;This is where having continuous integration is awesome.&lt;/p&gt;
&lt;p&gt;This is where testing with things like Testcontainers for more realistic scenarios begins to sizzle.&lt;/p&gt;
&lt;p&gt;This is where being able to delegate to tools like Spring Boot which pour tons of effort into not just coding new features but responding to bug reports and feature requests to constantly be patching and refining your tools.&lt;/p&gt;
&lt;p&gt;(I’ve used other toolkits where the main team mostly focused on new features and much LESS time on patching older stuff. Maybe cuz’ it wasn’t cool?? Who knows?)&lt;/p&gt;
&lt;p&gt;The days of planning a release every three months that requires the whole development team come in at 2:00 AM Sunday morning to minimize impact are GONE. (And yes, I did that once, long ago.) The chances of the systems you are helping to build ALWAYS having SOMEONE using them is here and now.&lt;/p&gt;
&lt;p&gt;So treat your system with respect and don’t balk at sometimes having to fix critical issues at weird times. Instead, learn how to build better processes that let you patch stuff more effectively. And be ready to embrace the fact that There Will Be Bugs, even in your bug patches!&lt;/p&gt;
&lt;p&gt;Which we can do a better job at dealing with in the next section!&lt;/p&gt;
&lt;h3 id=&quot;4realistic-testing&quot;&gt;4 — Realistic testing&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*usw_bKgo942M9zHfdN7z7w.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;The last facet of software development in this decade is the need for more realistic testing.&lt;/p&gt;
&lt;p&gt;Long ago, at the start of my career, it was common fare to manually test software bits. My first assignment was testing other people’s code. I’d fire things up and start clicking buttons. There was even a contracted “manual” that had our official test procedures.&lt;/p&gt;
&lt;p&gt;But these test procedures were always out of date. So trying to reduce my OWN efforts…&lt;/p&gt;
&lt;p&gt;…built something different. I started writing little functions that would call the production code, print out the results, and put them right next to the expect results. (This was before the days of JUnit, and it was Ada anyway.)&lt;/p&gt;
&lt;p&gt;I had basically come up with “automated testing” on my own, and suddenly OTHER devs on the team spotted my cool idea and adopted it for themselves.&lt;/p&gt;
&lt;p&gt;Then I had CRON jobs running at midnight to grab the last source code and exercise them, leaving me a report to inspect every morning.&lt;/p&gt;
&lt;p&gt;But today ain’t like that. Today, we need the ability to spin up the EXACT same database the Op is using. We need the ability to pre-load the EXACT same data they were running. We need the ability to have the EXACT same collection of 3rd party dependencies the Op was using to replicate a bug.&lt;/p&gt;
&lt;p&gt;And we can do that!&lt;/p&gt;
&lt;p&gt;By taking start.spring.io and making a “reproducible example”, mixing in a little Testcontainers to replicate the database/message broker/whatever, feeding Spring Boot an initialization script, and leveraging Spring Boot’s test-oriented options, it’s easier than ever to create a more realistic scenario compared to canned data.&lt;/p&gt;
&lt;p&gt;Yes, it’s okay to use stubs and mocks for unit-level testing. But Testcontainers and Docker have really opened things up for more accurate testing and our ability to code more scalable solutions.&lt;/p&gt;
&lt;p&gt;The future of software is already here, and these tools are here to help us, not hinder us. What is YOUR favorite aspect of modern software development?&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can find out whether or not you have the right skills to survive the current recession!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_YR_8yBKB506IwOxF_YAUig.CT-ZWWdG.jpeg"/></item><item><title>5 way to go to production with Spring Boot</title><link>https://www.procoder.io/articles/2022/2022-10-13_5-way-to-go-to-production-with-spring-boot-9912ef07d965</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-10-13_5-way-to-go-to-production-with-spring-boot-9912ef07d965</guid><description>Spring Boot is pretty cool, what with things like autoconfiguration, property file management, and all. But did you know it’s ALSO really…</description><pubDate>Thu, 13 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Spring Boot is pretty cool, what with things like autoconfiguration, property file management, and all. But did you know it’s ALSO really wicked at the different ways it simplifies taking your application to production?&lt;/p&gt;
&lt;h3 id=&quot;1deploying-with-uberjars&quot;&gt;1 — Deploying with Uber JARs&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Qqz7iUEc9eq2JBUWJnY7og.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;We’ve all created JAR files. In fact, most of the libraries we pick up and use, be it Spring libraries, Apache Commons, whatever, are JAR files.&lt;/p&gt;
&lt;p&gt;But Java is really quirky in the sense that its one of those unique platforms where deployment…isn’t baked right in. Instead, you have to reach for something to host it.&lt;/p&gt;
&lt;p&gt;That is, if you aren’t using Spring Boot.&lt;/p&gt;
&lt;p&gt;Spring Boot brings us something called Uber JARs. It’s a JAR file that includes not just your application code, but also ALL the 3rd party dependencies your app needs to operate.&lt;/p&gt;
&lt;p&gt;When you craft your Spring Boot application using start.spring.io, it will come loaded with the Spring Boot Maven Plugin (or Spring Boot Gradle plugin) which empowers your application during the build lifecycle to not only package up a standard JAR file with your code, but will also add those extra dependencies.&lt;/p&gt;
&lt;p&gt;Since Java itself has never DIRECTLY supported JARs within JARs, the Spring Boot team has crafted a little glue code to handle this job for your. With all that applied, all it takes to run your app is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$ java -jar myapp.jar&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s something that’s always been in Spring Boot, and something that will always be there. And as Oliver Drotbohm once said, all you need on your target machine is a JVM!&lt;/p&gt;
&lt;h3 id=&quot;2docker-containers&quot;&gt;2 — Docker containers&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Mz1QWofPLGFwj8Aiz8r30A.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Something that has risen up FAST is the usage of Docker. Today, you can find just about anything you want, including Oracle databases, wrapped inside Docker containers.&lt;/p&gt;
&lt;p&gt;So it’s natural that people want to bundle up their applications in Docker containers. In the past, this has always been tricky, because there is a certain nuance to “doing it right”.&lt;/p&gt;
&lt;p&gt;Assembling a Docker container can involve a lot of wasted cycles if you mix your continuously changing code together with 3rd party dependencies that don’t.&lt;/p&gt;
&lt;p&gt;It used to be that to put things together, you had to scour the wastelands of Google to find the right way to bundle your application along with JDK inside a container.&lt;/p&gt;
&lt;p&gt;So the Spring Boot team set out to pull together all the right metadata and simplify the process. And now, with that application crafted a la start.spring.io, this is all it takes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$ ./mvnw spring-boot:build-image&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Or gradlew bootBuildImage)&lt;/p&gt;
&lt;p&gt;With this command, Spring Boot will assemble your Uber JAR and then bake a Docker container, ready to be run, pushed to the cloud, or published to Docker Hub.&lt;/p&gt;
&lt;h3 id=&quot;3native-apps-ongraalvm&quot;&gt;3 — Native apps on GraalVM&lt;/h3&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*uatj03MrT8D-e4tBQwa25Q.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;What if startup time is VITAL for your application? Maybe you are running 10,000 copies and all that traditional Java startup time x 10,000 copies = a HUGE cloud bill? Or you are using Amazon’s Serverless Computing platform where spin-up time really NEEDS to be sub-second?&lt;/p&gt;
&lt;p&gt;Say no more. GraalVM, the alternative to the JVM, can run Java apps in sub-second time by leveraging something known as AOT of Ahead of Time Compilation.&lt;/p&gt;
&lt;p&gt;The Spring team has worked hand-in-hand with the GraalVM team to simplify and ease adoption of native applications. It principally involves folding in the right bits to the Spring portfolio making Spring Boot applications native-ready.&lt;/p&gt;
&lt;p&gt;And the Spring team has coordinated with the GraalVM team to make tweaks and adjustments to enhance GraalVM itself.&lt;/p&gt;
&lt;p&gt;For Spring Boot 2.x applications, all you need to do is add Spring Native when setting things up on start.spring.io, and all the right “extra settings” will be picked up in your application. As for Spring Boot 3 apps, native is, well, native! There will be no need. Stay tuned!&lt;/p&gt;
&lt;p&gt;And if you’re wondering HOW to assemble a fully-loaded native Spring Boot application, you just do this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$ ./mvnw spring-boot:build-image&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, the same command used to assemble a Docker container, when you have Spring Native applied, is used here as well. The difference is that Spring Boot’s build plugin will invoke Paketo Buildpacks to roll your a Docker container that has your code compiled via AOT mixed in with a GraalVM-based container.&lt;/p&gt;
&lt;h3 id=&quot;4creating-web-archivefiles&quot;&gt;4 — Creating Web Archive Files&lt;/h3&gt;
&lt;p&gt;Web Archive Files or WAR files are something that’s been around a long time. Everyone knows what they are.&lt;/p&gt;
&lt;p&gt;And if you need a WAR file, all you must do on start.spring.io is click the tiny “War” radio button on the screen, right next to “Jar”. You’ll be setup just right!&lt;/p&gt;
&lt;p&gt;WAR files are classic, work nicely on giant, lumbering application servers. Sluggish, slow to upgrade app servers.&lt;/p&gt;
&lt;p&gt;Come to think of it, maybe we SHOULDN’T be assembling WAR files. This is 2022 and people are running thin, light servlet containers and Docker containers. They’re even using GraalVM, not giant app servers!&lt;/p&gt;
&lt;p&gt;Forget I ever mentioned WAR files. What was I thinking?&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*QT3o74LtYXuQromZtpaB7A.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 5 — Executable JAR files&lt;/p&gt;
&lt;p&gt;One key feature we sometimes need are applications that start when the server starts and stop when the server starts. Linux and BSD users will be somewhat familiar with “init 5” and “init 0”-type scripts used by the OS.&lt;/p&gt;
&lt;p&gt;It shouldn’t surprise you that Spring Boot has a flag setting that lets you turn your JAR file into an executable that will obey the same runlevel settings.&lt;/p&gt;
&lt;p&gt;You can truly make your JAR file executable by applying this tweak:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;project&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;build&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;plugins&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;plugin&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;groupId&gt;org.springframework.boot&amp;#x3C;/groupId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;artifactId&gt;spring-boot-maven-plugin&amp;#x3C;/artifactId&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;configuration&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    &amp;#x3C;executable&gt;true&amp;#x3C;/executable&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;/configuration&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;/plugin&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;/plugins&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/build&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/project&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Just check here for the &lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/&quot;&gt;Gradle&lt;/a&gt; equivalent!)&lt;/p&gt;
&lt;p&gt;A key thing to point out, is that executable JAR files aren’t supported on all cloud platforms. There is a risk that it simply won’t run, so choose wisely.&lt;/p&gt;
&lt;p&gt;And that, my friend, is five ways to take your Spring Boot app to production.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can learn three design patterns that DIED a just and deserved death in 2022!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_Qqz7iUEc9eq2JBUWJnY7og.Cepv-Y83.png"/></item><item><title>3 Java Patterns that died in 2022</title><link>https://www.procoder.io/articles/2022/2022-10-06_3-java-patterns-that-died-in-2022-2896e2f35773</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-10-06_3-java-patterns-that-died-in-2022-2896e2f35773</guid><description>If there’s something we LOVE when it comes to software development, it’s finding ourselves some fun little shortcuts.</description><pubDate>Thu, 06 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If there’s something we LOVE when it comes to software development, it’s finding ourselves some fun little shortcuts.&lt;/p&gt;
&lt;p&gt;Of course, we don’t call them that. We call them patterns. Patterns are like recipes for baking up software solutions. Solutions we see appear more than once. After all, if we’ve solved a problem, why not re-use the solution? Isn’t that what Object-Oriented Programming (OOP) is all about?&lt;/p&gt;
&lt;p&gt;However, some of these patterns we solved for long ago, have turned out to be HORRIBLE and the source of misery. And so we’re going to see some of the most vile patterns that died a deserved death in 2022 starting with…&lt;/p&gt;
&lt;h3 id=&quot;1static-global-objects-aka-singleton-pattern&quot;&gt;1 — Static Global Objects a.k.a. Singleton Pattern&lt;/h3&gt;
&lt;p&gt;This is that beast of a pattern where we use trickery and hacks to ensure that No More Than One of these things could exist. Often, they involved external resources, for which there can be only one!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*RyI3dsN9gBCI1OpT27jUEw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Now what is bad about these things?&lt;/p&gt;
&lt;p&gt;Well, the trickery used to implement them often involved statics and taking advantage of when static initialization happens. HOT TIP: It’s early in an application’s lifecycle when static initialization happens.&lt;/p&gt;
&lt;p&gt;Static objects have certain side effects that make them truly detestable including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard to test&lt;/li&gt;
&lt;li&gt;Not overrideable&lt;/li&gt;
&lt;li&gt;VERY visible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Static, global objects violate some key principles. Being global, it’s hard to override. That’s because EVERYONE could be using it. To override it could break some component YOUR component isn’t even aware of.&lt;/p&gt;
&lt;p&gt;And because they are static (again, to ensure their lifecycle is fixed and under control across the lifetime of the application), automated tests have to deal with that.&lt;/p&gt;
&lt;p&gt;Because they are so hard to mutate, the inevitably adopt another strategy. It was not uncommon to migrate a single-value static global into a map, to afford multi-valued support. And once you start making it possible for everyone to stuff anything they want into it, the thing basically turns into a magical Bag of Holding!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*ZDBmWQaYcvGWIptPVavEmA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And at that point, it’s game over.&lt;/p&gt;
&lt;p&gt;People USUALLY realize the impact on automated tests. And they see how it’s a road of no return. But to remove it is ugly and painful. It requires breaking EVERYONE. And no one wants to be The One that does that.&lt;/p&gt;
&lt;p&gt;So everyone tends to shrug their shoulders and accept the fate.&lt;/p&gt;
&lt;p&gt;And it’s one reason why developers like to escape those apps and get onto something newer and fresher…something that isn’t beleaguered by such ugliness.&lt;/p&gt;
&lt;p&gt;In truth, the best solution is to use injectable types. An interface or a class. This is one of the slickest features baked into the core of Spring. Simply define the bean type you need. Define its operations. And INJECT it into the services, controllers, and repositories you need.&lt;/p&gt;
&lt;p&gt;Need more stuff? Create another bean. Keep those beans somewhat light and focused. Don’t bog them down with too much cross-domain knowledge.&lt;/p&gt;
&lt;p&gt;With Spring in your application, there was no longer any need to “trick” the application into FORCING your ONE THING as it is.&lt;/p&gt;
&lt;p&gt;And with Spring, you then discovered you could inject test mocks. And with Spring Boot, you suddenly gained access to different flavors based on the environment.&lt;/p&gt;
&lt;p&gt;And that’s why in 2022, no one is wanting to use singletons every again. But that’s not the only pattern that died in 2022. Another one that has collapsed is…&lt;/p&gt;
&lt;h3 id=&quot;2skyscraper-class-hierarchies&quot;&gt;2 — Skyscraper Class Hierarchies&lt;/h3&gt;
&lt;p&gt;What in the world is a Skyscraper Class Hierarchy?? Simply put, it’s a series of classes that is so tall its acquired its own name, just like some of the world’s most famous skyscapers seen in the world.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Ns37m6ANpoG-2P-QN-6xLw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Long ago, those of us new to Object-Oriented Programming were all too eager to build that perfect hierarchy of classes. (At least, I was!)&lt;/p&gt;
&lt;p&gt;And no matter how much thought and design we put into the class hierarchy…it would end up being wrong somehow. And then you’re fighting the battle of figuring out where to put that nuance you didn’t predict into the pattern.&lt;/p&gt;
&lt;p&gt;Then a month later, another “tweak” would come, and the process seemed to repeat itself. Class extending class extending class ended up becoming a maxim we’d all repeat: “composition over inheritance”.&lt;/p&gt;
&lt;p&gt;The usage of extensive chains of classes simply isn’t an effective way to write code!&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;Because there are certain assumptions that would be in place when the class structure was crafted that simply couldn’t be captured in the language itself. The existing concrete classes would know this, because they’d be correct. But a “new” class added later on, or a new usage of the hierarchy would introduce some other aspect that broke whatever that “assumption” is.&lt;/p&gt;
&lt;p&gt;This is why it has become MUCH more popular to apply the Open/Closed Principle. The Open/Closed Principle says a software entity should OPEN to extension but CLOSED to modification. My suggestion is to create an interface and implement it with a final class.&lt;/p&gt;
&lt;p&gt;You see the interface is “extendable” while the final class will block any modification.&lt;/p&gt;
&lt;p&gt;Are you wondering “doesn’t a sealed up class that is subclassed meet that definition?” It could, but it’s important to realize that ANY subclass of another class can result in a form of modification.&lt;/p&gt;
&lt;p&gt;And it should be a testimonial that Java’s String class has been final since the early days. The Java team KNEW that locking down such a critical piece of code to prevent subclasses from potentially wrecking things was VITAL.&lt;/p&gt;
&lt;p&gt;You may also be objecting from the perspective of having seen little class hierarchies deep inside the Spring portfolio itself. Those small collections of classes tend to be private or package private, and only serve as a “local” implementation. They usually aren’t publicly visible and open to public extension. Only internal usage, where all parties can meet and discuss changes.&lt;/p&gt;
&lt;p&gt;Changes that extend beyond your team are harder if not impossible to rein in.&lt;/p&gt;
&lt;p&gt;Maybe you STILL think I’m totally wrong on this? Maybe I’ve missed the boat on OOP? Tell me why in the comments below!&lt;/p&gt;
&lt;p&gt;But before we wrap things up, let’s talk about the THIRD design pattern that has died a deserved death in 2022…&lt;/p&gt;
&lt;h3 id=&quot;3designpatterns&quot;&gt;3 — Design Patterns&lt;/h3&gt;
&lt;p&gt;Yes, design patterns THEMSELVES have died a due death.&lt;/p&gt;
&lt;p&gt;You see, design patterns were meant to capture buts of reusable knowledge. But the exceptions for when they don’t apply are either not capture, not written up, or in the situations where they are…we just overlook them.&lt;/p&gt;
&lt;p&gt;There are too many exceptions to the norm to make them as valuable as they were once promised to us.&lt;/p&gt;
&lt;p&gt;In fact, there were so many design pattern books, that it spawned the anti-pattern movement!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*OgkrXQpFDnsjibfO47MVIQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;There’s an old saying…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rules of thumbs work until they don’t.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Design patterns are the software version of rules of thumbs. Yeah, they’re useful, but often times we get in over our head and overengineer something.&lt;/p&gt;
&lt;p&gt;Knowing when NOT to use patterns is usually MORE valuable.&lt;/p&gt;
&lt;p&gt;That’s why one of my recommendations is that when you finish up your Uni or your bootstrap program, to find a seasoned veteran of the industry and try to work with them.&lt;/p&gt;
&lt;p&gt;While software defies fitting COMPLETELY into the trade paradigm, the idea of apprenticing under a seasoned pro is INCREDIBLY valuable. It will help your career far better than any design pattern book, IMHO.&lt;/p&gt;
&lt;p&gt;What patterns do YOU think died a deserved death? Which patterns have you been fed up with? Let me know in the comments.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where you can learn the ONE NINJA SKILL you need to clobber your next interview!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="680" height="403" medium="image" url="https://www.procoder.io//_astro/1_RyI3dsN9gBCI1OpT27jUEw.BSCLqYtP.png"/></item><item><title>5 Ways To Code a Spring MVC Method</title><link>https://www.procoder.io/articles/2022/2022-09-29_5-ways-to-code-a-spring-mvc-method-cfdd221a18c0</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-09-29_5-ways-to-code-a-spring-mvc-method-cfdd221a18c0</guid><description>Building web apps is the name of the game.</description><pubDate>Thu, 29 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Building web apps is the name of the game.&lt;/p&gt;
&lt;p&gt;And when it comes to Spring Boot apps, it’s VITAL that you know how to make those controller methods do your bidding!&lt;/p&gt;
&lt;p&gt;This article contains some of the KEY WAYS to build web controllers with Spring Boot!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Sj-y5XPJG0vBA7Pih6g5WQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 1 — Declaring web controllers&lt;/p&gt;
&lt;p&gt;The first and probably MOST important thing is to alert Spring MVC when you HAVE a web controller. And we do that using Spring’s &lt;strong&gt;@Controller&lt;/strong&gt; annotation:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*wEaLWEuJqFhfGQYgzx3_cQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This little annotation, when applied to a class, will alert Spring Boot to register this class as a Spring bean. And when Spring MVC sees it, will configure it as a candidate for fielding web requests.&lt;/p&gt;
&lt;h3 id=&quot;2mapping-http-calls-to-your-controller-method&quot;&gt;2 — Mapping HTTP calls to your controller method&lt;/h3&gt;
&lt;p&gt;The next key ingredient in building a web controller is mapping the HTTP verb (&lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;PUT&lt;/strong&gt;, etc.) and the path to your method.&lt;/p&gt;
&lt;p&gt;The following controller shows this perfectly:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*DY5Jr2QYG6SgRpvu73Sv_Q.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This controller maps &lt;strong&gt;HTTP GET /items&lt;/strong&gt; calls onto &lt;strong&gt;ItemController.items()&lt;/strong&gt; using Spring MVC’s @GetMapping annotation.&lt;/p&gt;
&lt;p&gt;The default value of the annotation is the path. In this case, if someone visit &lt;a href=&quot;http://localhost:8080/items,&quot;&gt;http://localhost:8080/items,&lt;/a&gt; the “/items” part of the path is extracted and matched up with this annotation, matching the call to this method!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you’ve use Spring MVC for awhile, you may remember using &lt;strong&gt;@RequestMapping&lt;/strong&gt;. That annotation still works. &lt;strong&gt;@GetMapping&lt;/strong&gt; is just a shortcut for &lt;strong&gt;@RequestMapping(method = RequestMethod.&lt;em&gt;GET&lt;/em&gt;)&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For standard controllers, the return value is the name of the template to render. Spring Boot will combine it with a standard prefix of “src/main/resources/templates/” and a suffix based on the templating engine you’ve chosen. If you are using Mustache, for example, then it will apply a suffix of “.mustache”.&lt;/p&gt;
&lt;p&gt;Spring MVC will then render the template using the autoconfigured templating engine!&lt;/p&gt;
&lt;h3 id=&quot;3serving-different-mediatypes&quot;&gt;3 — Serving different media types&lt;/h3&gt;
&lt;p&gt;It’s possible to serve different types of data. For example, you may offer your users the option to render their data as either a &lt;strong&gt;PDF&lt;/strong&gt; or as &lt;strong&gt;XML&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You can do this:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Cun7_kBypyYc5w3JrtogRA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This shows two different controller methods responding to the same path. But they each have a different &lt;strong&gt;produces&lt;/strong&gt; clause.&lt;/p&gt;
&lt;p&gt;If the client submitted an &lt;strong&gt;Accepts: application/pdf header&lt;/strong&gt;, the first method will get picked, and presumably the template will end up rendering a &lt;strong&gt;PDF&lt;/strong&gt; file.&lt;/p&gt;
&lt;p&gt;If the client submitted &lt;strong&gt;Accepts: application/xml&lt;/strong&gt; as a request header, the second method will get picked, and that template should focus on serving up &lt;strong&gt;XML&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;: If you’re going to offer these specific types, you MAY want to consider offering a fallback for clients that don’t specify an &lt;strong&gt;Accept&lt;/strong&gt; header, or ONLY offer this link from ANOTHER page of your own design where the &lt;strong&gt;Accept&lt;/strong&gt; header is baked in.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;4consuming-jsondata&quot;&gt;4 — Consuming JSON data&lt;/h3&gt;
&lt;p&gt;So far, we’ve talked about serving up content. But web apps must also consume data, like JSON inputs.&lt;/p&gt;
&lt;p&gt;Spring Boot will automatically include Jackson for any Spring MVC app, allowing you to ingest JSON data automatically. All you need is the following code:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*EFUSV3H52gIpaVqS7SqeQQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;&lt;strong&gt;@PostMapping&lt;/strong&gt; is the way to flag your Spring MVC method to consume data instead of simply produce it.&lt;/p&gt;
&lt;p&gt;And to get your hands on the incoming data, include an argument for the entire type. In this case, we are using a Java 17 record (not shown) for the &lt;strong&gt;Item&lt;/strong&gt;. Spring MVC’s signal to deserialize incoming JSON data is using the &lt;strong&gt;@RequestBody&lt;/strong&gt; annotation on the argument.&lt;/p&gt;
&lt;h3 id=&quot;5-consuming-an-htmlform&quot;&gt;5— Consuming an HTML form&lt;/h3&gt;
&lt;p&gt;The previous section showed how to consume raw data like for an API call. But to receive a form from an HTML web page, we need something different.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*khy5zJBEvdcWlkrIOxyRkg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This uses the same &lt;strong&gt;@PostMapping&lt;/strong&gt; annotation. But the input argument is instead marked up with Spring MVC’s &lt;strong&gt;@ModelAttribute&lt;/strong&gt; annotation. This is designed to handle forms bounds to Java objects.&lt;/p&gt;
&lt;p&gt;This method also shows that after processing the new Item, it will then issue a redirect back to the home page using “&lt;strong&gt;redirect:/&lt;/strong&gt;”.&lt;/p&gt;
&lt;p&gt;With these tactics in place, you can easily start crafting your own web controllers using Spring Boot!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out the following video where we dig EVEN DEEPER into various Spring MVC annotations and tactics!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_Sj-y5XPJG0vBA7Pih6g5WQ.C0OBAtgm.png"/></item><item><title>How to be prepared for ANY coding interview!</title><link>https://www.procoder.io/articles/2022/2022-09-22_how-to-be-prepared-for-any-coding-interview--9d6bddea8073</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-09-22_how-to-be-prepared-for-any-coding-interview--9d6bddea8073</guid><description>Someone recently shared their struggle with finding a new position as a fresh grad just out of Uni:</description><pubDate>Thu, 22 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Someone recently shared their struggle with finding a new position as a fresh grad just out of Uni:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[F]or 1 year I focused on HTML, css, and JS from the bottom up. Then jumped into &lt;strong&gt;React&lt;/strong&gt;…I learned &lt;strong&gt;React&lt;/strong&gt; because it was most of what the market was looking for. But now it seems it has become &lt;strong&gt;angular&lt;/strong&gt; + Java once again…the interviewer didn’t ask me anything on Spring or Java, and focused exclusively on &lt;strong&gt;Angular&lt;/strong&gt;, despite &lt;strong&gt;React&lt;/strong&gt; and other technologies being listed as requirements.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I frankly don’t get the issue with companies honing in on whether someone knew React or Angular &lt;em&gt;specifically&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As for why they didn’t ask a question about Spring, well, interviewers can tend to carry certain biases. (But not the biases you may be thinking.)&lt;/p&gt;
&lt;p&gt;As someone that has interviewed MANY new hires in the past, most straight out of college, I can tell you that if someone walked into my office with stack of experience in EITHER ONE…I’d entertain hiring them on the spot!&lt;/p&gt;
&lt;p&gt;If there’s ONE THING I’ve learned in my 25-year career as a software engineer, it’s that toolkits, tactics, and patterns evolve. They change. Whatever you used last year may go by the wayside next year.&lt;/p&gt;
&lt;h3 id=&quot;1a-joke-that-reveals-atruth&quot;&gt;1 — A joke that reveals a truth&lt;/h3&gt;
&lt;p&gt;It’s a joke to pick a random noun and then google “&lt;random noun=&quot;&quot;&gt; javascript”, and see if there is, in fact, a JavaScript toolkit by the name.&lt;/random&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Want to have some fun? I’m at a coffee shop writing this article, and I spotted some scones for sale. Let’s google “scone javascript”. First entry?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*RKpB0yXw_NAbTfiXOXu1bQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Heh…and it’s a React library. Somehow fitting for our article, ehh?&lt;/p&gt;
&lt;p&gt;The core point is that toolkits change. A candidate’s ability to effect change through code is WHAT WE’RE LOOKING FOR. So whether your history was building rich web apps with Angular OR building rich web apps with React…&lt;/p&gt;
&lt;p&gt;…it’s the “building rich web apps” that hiring managers really want.&lt;/p&gt;
&lt;p&gt;What does this mean for you?&lt;/p&gt;
&lt;p&gt;Simply put, don’t worry. I know interviews can make you sweat. After all, we’re talking about the process to secure a position that pays the bills. Who WOULDN’T want to hit things off with a bang.&lt;/p&gt;
&lt;h3 id=&quot;2what-are-they-really-looking-in-an-interview&quot;&gt;2 — What are they really looking in an interview?&lt;/h3&gt;
&lt;p&gt;Something you need to be aware of, is that you can interview for a position, not be perfectly aligned with what the interviewer’s question, and still succeed.&lt;/p&gt;
&lt;p&gt;That person you are about to face off with (feels that way, right?) may have entered the meeting room with half a dozen question about your skills of using Angular. And you may have had ZERO runtime on Angular.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*lT2EJ3ICtLo11M8DeLPgPQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;But you can still succeed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How is this even possible?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let me show you. Let’s pull back the curtain a little and reveal what’s REALLY happening so YOU can be better prepared for your next interview.&lt;/p&gt;
&lt;p&gt;Anytime I get ready for an interview, I am generally looking for the following traits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Has some experience with some coding toolkit. That’s because experience will have grown that person’s ability to code patterns and concepts that tend to TRANSCEND the toolkit itself.&lt;/li&gt;
&lt;li&gt;I know that toolkits never have 100% of what we need, and so need some amount of creativity working around such limitations. Someone that has USED a toolkit for some amount of time will have learned this concept and be a great asset.&lt;/li&gt;
&lt;li&gt;A candidate that has worked for some amount of time on a team, be it a professional team or perhaps a senior design project team will have learned the basics of team interactions. The more experience a person has working through communications, tradeoffs, and building a product WITH OTHERS will be able to work with OUR TEAM.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is why experience is valuable. Not for the sake of it, but because you will have learned some of these universal concepts. We’re talking about more than if-then clauses, boolean logic, loops, and inheritance.&lt;/p&gt;
&lt;p&gt;No, we’re talking about dealing with toolkit limitations, developer tool limitations, communication limitations, PEOPLE limitations.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nothing is perfect. And your ability to weather development storms and still produce value for a customer IS WHAT I’M LOOKING FOR.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I just may HAPPEN to be using Angular as my vehicle to probe your experience. Partly because it’s what my team is using. Partly because it’s what I know the best (at least, right now).&lt;/p&gt;
&lt;h3 id=&quot;3how-you-can-know-zero-about-some-toolkitand-still-get-anoffer&quot;&gt;3 — How you can know ZERO about some toolkit…and still get an offer!&lt;/h3&gt;
&lt;p&gt;Want to know how I managed to get on the Spring team back in 2010, despite having ZERO experience with writing servlets, deploying to Java app servers, and having never deployed a Spring bean to save my life?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I talked about how I had led a team of seven engineers in building and deploying a 24x7x365 application to your Ops center.&lt;/li&gt;
&lt;li&gt;I mentioned provided on-call support for several years and coming in to resolve crises (once, I came in 3x in the same night!)&lt;/li&gt;
&lt;li&gt;I shared how I had led the way in using management’s chosen platform to provide around-the-clock uptime to our client.&lt;/li&gt;
&lt;li&gt;I pointed out some of my tactics to build CRON jobs that would monitor the system every 10 minutes and restore nodes that had gone down due to apparent memory leaks.&lt;/li&gt;
&lt;li&gt;I wrapped up by pointing out my future plans to migrate this whole system to a Spring-based solution once management approved my proposal and gave me the green light.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How could it be that someone from the Spring team saw all this and yet extended me an offer?&lt;/p&gt;
&lt;p&gt;To prepare for your next interview, try this: sit down and start listing what all you’ve accomplished. Try to go beyond credentials and certifications and instead think about the biggest &lt;em&gt;&lt;strong&gt;PROBLEMS&lt;/strong&gt;&lt;/em&gt; you solved. Even if it’s a project you did for a class.&lt;/p&gt;
&lt;p&gt;Beside each project, try to list &lt;em&gt;&lt;strong&gt;the value you provided to OTHERS&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The NEXT time you go into an interview, think about the top 3 things on your list and think about how to answer someone’s question that way, okay?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interviewer: Have you ever used Angular to build a production-grade application?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;You: No, but I actually used React to put together a system with two other teammates that is now serving about 10,000 hits every day. We deployed it on AWS thanks to some scripts I crafted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sometimes, interviewers are looking for very specific skills. Perhaps they need someone already ramped up on Angular. It’s possible in this scenario that they could pass on you.&lt;/p&gt;
&lt;p&gt;But it’s MORE LIKELY they are looking for someone to join the team and to help shoulder the workload. They REALLY need someone that capable of learning and growing, and who will make things happen no matter what the challenges.&lt;/p&gt;
&lt;p&gt;The toolkit at hand is often simply a vehicle to get to a deeper understanding of what you can do.&lt;/p&gt;
&lt;p&gt;So either lean into that toolkit because you DO know it…or pivot toward another one and show your skill at SOLVING PROBLEMS.&lt;/p&gt;
&lt;p&gt;Because someone with those types of real world skills will be irresistible!&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. But if you simply can’t wait, then check out the video below where I show you how to prepare for your next interview!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_lT2EJ3ICtLo11M8DeLPgPQ.DPdUNH0a.png"/></item><item><title>6 Ways to Become a SPRING Coder</title><link>https://www.procoder.io/articles/2022/2022-09-15_6-ways-to-become-a-spring-coder-ec2fbd89ca59</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-09-15_6-ways-to-become-a-spring-coder-ec2fbd89ca59</guid><description>So you’ve heard that Spring is the way? In your eagerness to dive into the workforce as a full fledge coder, you want to get crackin’.</description><pubDate>Thu, 15 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So you’ve heard that Spring is the way? In your eagerness to dive into the workforce as a full fledge coder, you want to get crackin’.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Sj-y5XPJG0vBA7Pih6g5WQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And then it hits you…how do you get started?&lt;/p&gt;
&lt;h3 id=&quot;1start-from-thesource&quot;&gt;1 — Start from the source&lt;/h3&gt;
&lt;p&gt;Several years ago, the Spring team released a slew lunchtime-sized guides. They’re free and updated to the latest stable version of Spring Boot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Head over to &lt;a href=&quot;https://spring.io/guides&quot;&gt;https://spring.io/guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pick one and go through it. They are designed to NOT require completing OTHER tutorials or guides.&lt;/li&gt;
&lt;li&gt;The next day, do another.&lt;/li&gt;
&lt;li&gt;Rinse, repeat.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The guides aren’t specific to any Spring project. Instead, they each focus on solving a problem. There are about 60, so in the span of a 2–3 months, your knowledge of Spring can be widened considerably!&lt;/p&gt;
&lt;h3 id=&quot;2start-reading-this-week-inspring&quot;&gt;2 — Start reading &lt;em&gt;This Week in Spring&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;If you want to catch the latest, then visit &lt;a href=&quot;https://spring.io/blog&quot;&gt;https://spring.io/blog&lt;/a&gt;. Not only is chock full of official news, but there’s a weekly post from &lt;a href=&quot;https://twitter.com/starbuxman&quot;&gt;Josh Long a.k.a. starbuxman&lt;/a&gt; dubbed &lt;em&gt;&lt;strong&gt;This Week in Spring&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Josh has been writing this column since he joined the Spring (right after me), and he hasn’t stopped.&lt;/p&gt;
&lt;p&gt;In his weekly roundup, he has some of the hottest news not just from the Spring team, but the Spring community at large.&lt;/p&gt;
&lt;p&gt;And in case you didn’t catch it, the Spring community is HUGE. Which leads to the next way to ramp up your skills as a Spring coder…&lt;/p&gt;
&lt;h3 id=&quot;3tune-in-to-the-latest-from-the-spring-community&quot;&gt;3 — Tune in to the latest from the Spring community&lt;/h3&gt;
&lt;p&gt;There are multiple sources where you can catch interviews, news, and other Spring stuff.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bootifulpodcast.podbean.com/&quot;&gt;&lt;strong&gt;A Bootiful Podcast&lt;/strong&gt;&lt;/a&gt; (Josh Long)&lt;/li&gt;
&lt;li&gt;&lt;del&gt;&lt;strong&gt;The Spring Boot Learning Podcast&lt;/strong&gt; (me!)&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.javapubhouse.com/&quot;&gt;&lt;strong&gt;Java Pub House&lt;/strong&gt;&lt;/a&gt; (Freddy Guime)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;UPDATE: I have since pivoted my podcast to the &lt;a href=&quot;https://podcast.procoder.io&quot; target=&quot;_blank&quot;&gt;Pro Coder Show&lt;/a&gt; and am no longer Spring-specific.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Podcasts are fun and exciting. They have a certain amount of tech knowledge mixed in with entertaining banter.&lt;/p&gt;
&lt;p&gt;And all these podcasts are fun. Check ’em out!&lt;/p&gt;
&lt;h3 id=&quot;4grab-abook&quot;&gt;4 — Grab a book!&lt;/h3&gt;
&lt;p&gt;Podcasts and news articles are great, but sometimes you need the information chained together with coding examples. And that’s where books really shine.&lt;/p&gt;
&lt;p&gt;To get some of the latest check out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://trnq.st/ov25&quot;&gt;&lt;em&gt;Spring Boot: Up &amp;#x26; Running&lt;/em&gt;&lt;/a&gt; (Mark Heckler)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trnq.st/edxn&quot;&gt;&lt;em&gt;Spring in Action&lt;/em&gt;&lt;/a&gt; (Craig Walls)&lt;/li&gt;
&lt;li&gt;Pre-order &lt;a href=&quot;https://trnq.st/71j2&quot;&gt;&lt;em&gt;Learning Spring Boot 3.0 3rd Edition&lt;/em&gt;&lt;/a&gt; (again, me)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(What person doesn’t mention their own book, right?)&lt;/p&gt;
&lt;p&gt;Everyone consumes information in different ways. Whether that’s&lt;/p&gt;
&lt;h3 id=&quot;5check-out-somevideos&quot;&gt;5 — Check out some videos&lt;/h3&gt;
&lt;p&gt;There are multiple YouTube channels where you start learning Spring coding in video format.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/danvega&quot;&gt;Dan Vega&lt;/a&gt; (Spring Developer Advocate)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/user/SpringSourceDev/videos&quot;&gt;Josh Long&lt;/a&gt; (Spring Developer Advocate)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/SpringBootLearning/featured&quot;&gt;Spring Boot Learning&lt;/a&gt; (me!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these videos are 100% free. Check ’em out to see who if they suit your needs.&lt;/p&gt;
&lt;h3 id=&quot;6carve-out-some-space-to-startcoding&quot;&gt;6 — Carve out some space to start CODING!&lt;/h3&gt;
&lt;p&gt;This may sound a bit weird, but if you want to be a pro coder in the land of Spring, then find a place in your home or apartment. Clean it out and make space.&lt;/p&gt;
&lt;p&gt;Don’t just sit around at the dining table or in your living room chair.&lt;/p&gt;
&lt;p&gt;No, find a REAL place to dedicate to writing code. It could be as simple as a small IKEA desk in the corner of a room…or a &lt;a href=&quot;https://trnq.st/bny2&quot;&gt;standing desk if you want&lt;/a&gt;. Making a dedicated space is the first step of commitment to start growing your skills.&lt;/p&gt;
&lt;p&gt;Then…start coding. Use the guides, the books and the videos mentioned above. Whatever it takes.&lt;/p&gt;
&lt;p&gt;Because one thing this all requires…is YOU!&lt;/p&gt;
&lt;p&gt;YOU must commit to digging in and learning.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this video where I talk frankly and openly about what YOU need to be doing as a PRO CODER to raise your value in the midst of a RECESSION.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_Sj-y5XPJG0vBA7Pih6g5WQ.C0OBAtgm.png"/></item><item><title>Thanks!</title><link>https://www.procoder.io/articles/2022/2022-09-15_thanks--4d08ea35a29a</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-09-15_thanks--4d08ea35a29a</guid><description>BTW, I fixed that link so you should now be able to access all the guides.</description><pubDate>Thu, 15 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Thanks!&lt;/p&gt;
&lt;p&gt;BTW, I fixed that link so you should now be able to access all the guides.&lt;/p&gt;</content:encoded><media:content type="image/png" width="1408" height="768" medium="image" url="https://www.procoder.io//_astro/default-hero.D-v8eEMA.jpg"/></item><item><title>5 Tips to Protect Yourself from the RECESSION!</title><link>https://www.procoder.io/articles/2022/2022-09-08_5-tips-to-protect-yourself-from-the-recession--4bb6555e95bf</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-09-08_5-tips-to-protect-yourself-from-the-recession--4bb6555e95bf</guid><description>With a looming recession, are you doing everything you can to solidly your position within your team?</description><pubDate>Thu, 08 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With a looming recession, are you doing everything you can to solidly your position within your team?&lt;/p&gt;
&lt;p&gt;Maybe you’re put off by that question, but in truth, this is one of your stronger moves you could possibly make. Simply out, economic slowdowns can be temporary, but as &lt;a href=&quot;https://trnq.st/x0y4&quot;&gt;Graham Stephan once said&lt;/a&gt;, “Upskilling makes you well positioned for sunny days.”&lt;/p&gt;
&lt;h3 id=&quot;1find-out-what-skills-you-arelacking&quot;&gt;1 — Find out what skills you are lacking&lt;/h3&gt;
&lt;p&gt;For get started, do this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Take some time one evening and scribble down on paper or your tablet the skills you have.&lt;/li&gt;
&lt;li&gt;In another column list the skills they would be useful to pick up.&lt;/li&gt;
&lt;li&gt;The following night, pick one item on your new “wish” list and go find a video or tuturial and DO IT!&lt;/li&gt;
&lt;li&gt;The night after that, do another. Work your way down the list.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In a month’s time, you’ll have grown your skill set in a favorable direction.&lt;/p&gt;
&lt;p&gt;For even more tips on upskilling that fit your current organization (or the one your shooting for), check out this video:&lt;/p&gt;
&lt;h3 id=&quot;2work-on-your-codequality&quot;&gt;2 — Work on your code QUALITY&lt;/h3&gt;
&lt;p&gt;Learning new toolkits that support your current skills is one thing.&lt;/p&gt;
&lt;p&gt;But there’s another skill NOT covered in any Uni class or bootstrap program. It’s called “code polishing”. While this skill doesn’t provide new functions or operational code, this practice can improve your efficiency.&lt;/p&gt;
&lt;p&gt;One of the biggies in code development is our need to go back and read code we’ve written before. And if you’re code is an incoherent mess, then it becomes much HARDER to do so.&lt;/p&gt;
&lt;p&gt;Adopt some of the practices found in the video below, and you can make yourself INCREDIBLY VALUES to ANY team!&lt;/p&gt;
&lt;h3 id=&quot;3look-ma-no-hand-runtests&quot;&gt;3 — Look ma! No hand-run tests!&lt;/h3&gt;
&lt;p&gt;Something else that may get glossed over, if covered at all, is automated testing.&lt;/p&gt;
&lt;p&gt;Indeed, more and more shops are adopting this, but the odds that this was covered in your university or boot strap program is slim. And if covered, may have been only mentioned briefly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;However, it’s one of those skills that will pay you back for years to come. So, why not give yourself an edge by deepening your skills there as well.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Considering how how widely automated has been adopted, I made an entire playlist devoted to it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull up the playlist below.&lt;/li&gt;
&lt;li&gt;Go to the one you know the LEAST about and WATCH it!&lt;/li&gt;
&lt;li&gt;On another night (or during a lunch break), watch the NEXT one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you finish this playlist, you’ll be a LOT more confident to run with automated testing OR EVEN INTRODUCE IT to your team!&lt;/p&gt;
&lt;p&gt;NOTE: A developer that can SHOW a passing test suite is worth a FORTUNE to any manager!&lt;/p&gt;
&lt;h3 id=&quot;4making-your-ninjamove&quot;&gt;4 — Making your ninja move&lt;/h3&gt;
&lt;p&gt;Buried deep in this article we now come to a slick, cool move you SHOULD be making.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Shhh! Don’t tell anyone. This is just between you and me, okay?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now this may sound strange but one the FASTEST places to gain traction with your team is learning to query the database for data.&lt;/p&gt;
&lt;p&gt;Why? It seems just about anyone can write a web controller and everyone and their cousin seems to have had a hand dabbling with JavaScript…&lt;/p&gt;
&lt;p&gt;…but not EVERYONE groks &lt;strong&gt;databases&lt;/strong&gt; and &lt;strong&gt;querying&lt;/strong&gt; them for &lt;strong&gt;real data&lt;/strong&gt; to populate those web forms.&lt;/p&gt;
&lt;p&gt;Everyone around you, whether you’re surrounded by new hires or you’re vying for a position, can probably write a slick web control with some JS toolkit. That’s why YOU must pull the ninja move of being better at &lt;em&gt;database queries&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;If you need to get started, check out this deep dive live stream where we do some real database action:&lt;/p&gt;
&lt;h3 id=&quot;5acing-the-interview&quot;&gt;5 — Acing the interview&lt;/h3&gt;
&lt;p&gt;All these skills are for naught if you don’t land that position, amirite?&lt;/p&gt;
&lt;p&gt;That’s why you need to KNOW what hiring managers are LOOKING for! (And in recessionary times, even if you’re on a team, there is &lt;em&gt;increased risk of being let go&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;I’ve been involved in many hiring decisions. Trust me, you don’t want to get caught flat footed. Even if you’re on a team, you can learn what notes to start keeping so that you’re ready for your NEXT interview (which not happen when YOU want it!)&lt;/p&gt;
&lt;p&gt;So watch this and see what TO do and what NOT to do!&lt;/p&gt;
&lt;p&gt;I’ll wrap this article up with a warning.&lt;/p&gt;
&lt;p&gt;Maybe you sensed it because I made no reference to &lt;strong&gt;security&lt;/strong&gt; and &lt;strong&gt;locking down apps&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Security is a beast. For some it’s a passion. For others, it’s a completely different batch of studies and courses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unless you’re going to devote the time it takes to master security, you’re better off spending your present time on the other stuff mentioned in this thread. Yes, it’s beneficial for ALL software developers to grok security, but this article is about tactics to “upskill” yourself, quickly.&lt;/p&gt;
&lt;p&gt;Security is a MAJOR time sink and something that would require SACRIFICING the other things mentioned.&lt;/p&gt;
&lt;p&gt;So my super secret advice is to &lt;em&gt;let one of your competitors&lt;/em&gt; be the person that excels at security while you succeed at the things listed above.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. Normally I like to include a link to a relevant video at the bottom, but if you visit even ONE of the videos above, your skills will improve.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="1408" height="768" medium="image" url="https://www.procoder.io//_astro/default-hero.D-v8eEMA.jpg"/></item><item><title>Why Reactive Streams are the SECRET to CUTTING your monthly cloud bill!</title><link>https://www.procoder.io/articles/2022/2022-09-01_why-reactive-streams-are-the-secret-to-cutting-your-monthly-cloud-bill--c75cf2f328ce</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-09-01_why-reactive-streams-are-the-secret-to-cutting-your-monthly-cloud-bill--c75cf2f328ce</guid><description>In the world of software development, we are FOREVER battling two competing forces: bigger demands vs. more powerful machines.</description><pubDate>Thu, 01 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the world of software development, we are FOREVER battling two competing forces: &lt;strong&gt;bigger demands&lt;/strong&gt; vs. &lt;strong&gt;more powerful machines&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now this may SOUND like NOT an actual competition. In fact, it may sound like perfect alignment, because wouldn’t the &lt;strong&gt;more powerful machines&lt;/strong&gt; meet the &lt;strong&gt;bigger demands&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;Amazingly…no.&lt;/p&gt;
&lt;p&gt;Because what &lt;strong&gt;REALLY&lt;/strong&gt; happens is a little like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Demands for more users and more data come in.&lt;/li&gt;
&lt;li&gt;We get bigger/more servers.&lt;/li&gt;
&lt;li&gt;We catch up to the demands of step (1).&lt;/li&gt;
&lt;li&gt;In the time span of steps (2) and (3), the demand increases another 25%, which simply repeats this vicious loop.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In fact, this is a KEY reason cloud computing &lt;strong&gt;took off like crazy&lt;/strong&gt;. In previous decades, the very thought of growing your own data center was expensive, time consuming, and laborious. There was legit pushback when someone would say “we need more servers!”&lt;/p&gt;
&lt;p&gt;But call up your favorite cloud vendor to say “we need 25% more than last month”, and instead of dread you’ll hear excitement!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Of course your cloud bill is going up 25% as well. But the capacity you need is readily available!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That’s great…if 25% more server power yields 25% &lt;em&gt;or more&lt;/em&gt; sales. But what if it doesn’t? What if your cost-to-profit ratio isn’t like that? A growing monthly cloud bill doesn’t always translate to enough profit. And thus, you need to start looking for ways to CUT COSTS.&lt;/p&gt;
&lt;p&gt;What if I told you…that you’re already wasting precious time. (And in the cloud, time is literally money.)&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*yiNL2fQmeflwBLXJtGIxJw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;You have idle threads sitting around, waiting for a response. And when you scale to any appreciable size, the idle cost will kill you.&lt;/p&gt;
&lt;p&gt;10,000 server processes, each with 100 threads sporting some appreciable amount of lingering idle time…well let’s just say it doesn’t have to BE that way!&lt;/p&gt;
&lt;p&gt;Reactive Streams beats this crazy problem of over-consuming an underutilized resource by introducing: &lt;em&gt;&lt;strong&gt;non-blocking.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The idea is simple: instead of holding up a thread waiting for a response, instead let that thread go do some other work. There is a little machinery to orchestrate this, but that is frameworks are good at, right?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;While a thread awaits a response to a remote web call, process the database call?&lt;/li&gt;
&lt;li&gt;While a thread awaits the database server to hand back some data, why not chew through that payload that just came back from the remote service?&lt;/li&gt;
&lt;li&gt;While a thread awaits another thread awaiting ANOTHER thread making a remote call…why not let ALL of those idle threads DO SOMETHING ELSE?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is what Reactive Streams does. &lt;em&gt;&lt;strong&gt;It decouples work from the thread.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Reactive Streams is a VERY simple spec (just four interfaces) that, in fact, is so simple, it’s not recommended for direct application usage. Instead, the suggestion is to build libraries on top of it that others can use.&lt;/p&gt;
&lt;p&gt;But as long as these libraries are compliant with these contracts, these libraries can integrate with each other.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Project Reactor&lt;/strong&gt; is VMware/Spring’s implementation of Reactive Streams.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RxJava&lt;/strong&gt; is Netflix’s implementation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vert.x 3.0&lt;/strong&gt;, &lt;strong&gt;MongoDB&lt;/strong&gt;, &lt;strong&gt;Ratpack&lt;/strong&gt;, &lt;strong&gt;Akka Streams&lt;/strong&gt;, and several other toolkits and framework also support Reactive Streams.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;So what exactly does Reactive Streams DO that is so slick and cool?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Simple: Reactive Streams replaces the old paradigm of PUSHING things onto downstream consumers and INSTEAD waits for the downstream consumer to PULL. These requests can be “send me 1” or “send me 10” or “send me ALL you’ve got”.&lt;/p&gt;
&lt;p&gt;The response, though, doesn’t have to come right away. Nor does it have to come on the same thread. Imagine there is a queue somewhere managing the work request. And the size of the queue is constantly dictated by the downstream puller.&lt;/p&gt;
&lt;p&gt;This ability to push a flow limit upstream is known as “back pressure” and when using Reactive Streams, allows such signals to get pushed from the last consumer all the way to the first producer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is even a network protocol (RSocket) that mirrors this contract!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And it’s this ability to control flow across the whole system, that when properly adopted by ALL components in the system, allows a MUCH more efficient flow of data!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*_iGf-8amwqgNbOJ7F1fdKQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Nevertheless, despite all the challenges of adopting functional programming, despite the “new fangled way” this all appears, Reactive Streams DOES make it possible to better squeeze more usage out of current CPU cycles and even SHRINK the number of servers you are renting from AWS, thus &lt;em&gt;&lt;strong&gt;lowering your cloud bill&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And while Reactive Streams may not, on a per-operation basis, be faster than conventional systems, the net gain in more efficient usage can result in your application having a &lt;strong&gt;substantially better throughput&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And lowering your cloud bill by significant factors by wringing out better usage of your AWS nodes, your application may leap forward in efficiency. Don’t dismiss this it because the paradigm is different.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this video where I go into the details of what reactive programming with Project Reactor is like!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="540" height="468" medium="image" url="https://www.procoder.io//_astro/1_yiNL2fQmeflwBLXJtGIxJw.L0Aj3SuB.png"/></item><item><title>What no university will teach…but is VITAL to your career!</title><link>https://www.procoder.io/articles/2022/2022-08-25_what-no-university-will-teach-but-is-vital-to-your-career--7b78802e72c1</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-08-25_what-no-university-will-teach-but-is-vital-to-your-career--7b78802e72c1</guid><description>If you’re either wrapping up your college program or 12-week bootcamp (or just did), then you’re probably all fired up and stoked to GET…</description><pubDate>Thu, 25 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you’re either wrapping up your college program or 12-week bootcamp (or just did), then you’re probably all fired up and stoked to GET OUT there! Yeah?&lt;/p&gt;
&lt;p&gt;Ready to carve out your own piece of this thing we call Software Development.&lt;/p&gt;
&lt;p&gt;Would it &lt;strong&gt;SURPRISE&lt;/strong&gt; you to know that one of &lt;strong&gt;THE MOST IMPORTANT&lt;/strong&gt; things you could learn to enhance your career was totally skipped over? One of those VITAL skills any pro coder needs is simply nowhere to be found in any 4-year collegiate program nor any 12-week bootcamp?&lt;/p&gt;
&lt;p&gt;What is this magical skill we all need but isn’t being covered?&lt;/p&gt;
&lt;p&gt;The answer: &lt;strong&gt;Continuous Integration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Continuous Integration (CI) is when you let a server build your software after every commit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If it succeeds, it shows &lt;strong&gt;GREEN&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;If it fails it shows &lt;strong&gt;RED&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Some CI servers will &lt;strong&gt;email you&lt;/strong&gt;. Others may send you an &lt;strong&gt;IM&lt;/strong&gt;. But the point is that you let this CI server run every single change anyone makes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why is this so &lt;em&gt;valuable&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;And more importantly, why didn’t anyone &lt;em&gt;TELL YOU&lt;/em&gt; about it during your studies?&lt;/p&gt;
&lt;p&gt;The reason CI is so valuable is that we need feedback, CONSTANT feedback on whether or not our changes have broken anything. Even if we made a seemingly tiny change, having a CI server run our tiny change and detect breakage will help by STOPPING us and suggesting we back up and see what went wrong.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*SR_NYrrXS6Zu9A5fg5hMWg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;But that is not all.&lt;/p&gt;
&lt;p&gt;CI servers don’t just build our software. They can do much more. If our code is consumed downstream, then publishing a snapshot to a repository will make it much easier for others to eat up our changes.&lt;/p&gt;
&lt;p&gt;And…it makes it easier to BREAK them.&lt;/p&gt;
&lt;p&gt;You heard me. Breaking downstream consumers of our module is GOOD because it exposes our lingering PROBLEMS sooner rather than later.&lt;/p&gt;
&lt;p&gt;The Spring team is BIG on backward compatibility. If Spring Data JPA were to drop a publicly-visible method that Spring Boot takes advantage of, the sooner we can push that into their team, the better. They’ll either accept this change, or they’ll ring us up, asking “What happened?!?”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Okay, the Spring Boot team won’t REALLY react that way. But they would certainly inquire as to WHY we dropped a publicly visible API in the middle of a point release.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CI is good at catching stuff sooner rather than later. And there is a hint of possibility that your formal education in software development MAY have mentioned, the sooner bugs are caught, the less they cost to fix.&lt;/p&gt;
&lt;p&gt;Which brings us back to WHY you’ll find NONE of this in your training!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*vBn-PYK93h6NqwymndODww.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Because they don’t &lt;strong&gt;CARE&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Or to be more precise…they care about a lot of stuff including: algorithms, language constructs, variables &amp;#x26; functions, logical tactics, and development tools.&lt;/p&gt;
&lt;p&gt;Maybe they DO care about other things like version control, CI, and operations, but not ENOUGH to bump any of these other topics. Relative to programming concepts and coding practices, no instructor views code hygiene as something they can fit into an already busy schedule.&lt;/p&gt;
&lt;p&gt;And so it becomes something YOU must embrace and learn about. Something YOU must decide will help you stop FIGHTING MIDNIGHT FIRES. Something YOU must choose to pick up and learn to do.&lt;/p&gt;
&lt;p&gt;Because in my 25-year career as a software engineering veteran whose first assignment was testing OTHER people’s code (and hence built an automated CI tool before CI had entered today’s lexicon), nothing has helped me MORE than knowing SOONER rather than LATER that a particular code change broke something.&lt;/p&gt;
&lt;p&gt;And the sooner I knew it, the sooner I could fix it.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this video where I talk frankly and openly about what YOU need to be doing as a PRO CODER to raise your value in the midst of a RECESSION.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="772" height="323" medium="image" url="https://www.procoder.io//_astro/1_SR_NYrrXS6Zu9A5fg5hMWg.CiVFOvWG.png"/></item><item><title>If at first you don’t succeed…try, try, try, try, try, try again!</title><link>https://www.procoder.io/articles/2022/2022-08-18_if-at-first-you-don-t-succeed-try--try--try--try--try--try-again--3c7c2df8ca5</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-08-18_if-at-first-you-don-t-succeed-try--try--try--try--try--try-again--3c7c2df8ca5</guid><description>The land of software development has some dark corners.</description><pubDate>Thu, 18 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The land of software development has some dark corners.&lt;/p&gt;
&lt;p&gt;We’re talking about the things we must all do from time to time to be a PRO CODER. It may be fun and glorious to build that &lt;em&gt;Hello World&lt;/em&gt; app with our latest 5-minute tutorial leveraging some cool toolkit. But to think THIS will be the thesis of your day-to-day job as a professional is false.&lt;/p&gt;
&lt;p&gt;I don’t know if you went to college or a 12-week bootcamp. I don’t know if you’re just reading this and THINKING about side hustling your way into the world of software development. (Kudos if you are!)&lt;/p&gt;
&lt;p&gt;But I don’t want there to be ANY confusion that on some days, many days in fact, you have to simply, calmly, peacefully…&lt;/p&gt;
&lt;p&gt;BRUTE FORCE your way through a PROBLEM!&lt;/p&gt;
&lt;p&gt;On certain days/weeks, you must:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Try something.&lt;/li&gt;
&lt;li&gt;See if it worked.&lt;/li&gt;
&lt;li&gt;If not, circle to step 1.&lt;/li&gt;
&lt;li&gt;Rinse and repeat.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And you must DO THIS 100x today. 100x tomorrow. 100x every day this week.&lt;/p&gt;
&lt;p&gt;100x100x100 times…until something moves the way you want it to move.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*mEGWo8aj61rVqwcn1pjGmg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;This is what has SO MANY people stoked for automated testing. This is why JUnit and Spock testing toolkit and Groovy testing and Testcontainers and so many other wickedly awesome testing toolkits draw such huge fanbases.&lt;/p&gt;
&lt;p&gt;The easier it is to capture a scenario or behavior in a repeatable piece of code that exercises your code, the easier it is to break out of that crazy loop I just listed up above.&lt;/p&gt;
&lt;p&gt;Because as grand and glorious as Software Development is, and as much as we celebrate it as a discipline of ENGINEERING, many times (too many times?), not everything is solved with pen &amp;#x26; paper.&lt;/p&gt;
&lt;p&gt;Some problems are simply solved by trial and error.&lt;/p&gt;
&lt;p&gt;Trial and error.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Random onlooker: “Yeah? So what! Lots of jobs require trial and error.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Indeed, Grasshopper, this is true. But to be a successful developer on your team, there are some days where no one has the answer for YOU. There will be some days where Stackoverflow.com won’t have the answer for YOU. There will be some days where the ONLY answer, the only way forward to solving the caper your team is in the middle of…&lt;/p&gt;
&lt;p&gt;…is you. Doing trial and error.&lt;/p&gt;
&lt;p&gt;You can say, “Oh well. Couldn’t fix that! I’ll just let someone else deal with it.”&lt;/p&gt;
&lt;p&gt;Good look getting tapped for something else. Good luck being handed the position of lead for a module.&lt;/p&gt;
&lt;p&gt;Because if you can’t embrace our beloved try-something-until-it-works for three weeks, you don’t have what it takes to lead anything.&lt;/p&gt;
&lt;p&gt;It’s true, we have ways to bounce ideas off each other. It’s true, you can reach out for help within your team or to online forums. But at the end of the day, there are times where it’s all you. And your ability to NEVER GIVE UP is what will make the difference.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*kNbQBNCi-X33vk1hS7mnDA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And the sooner you appreciate this and accept this. The sooner you have that attitude of not simply pushing the code along but instead making it bend to YOUR WILL…&lt;/p&gt;
&lt;p&gt;…well…the sooner you will be ready to apply &lt;strong&gt;This Same Tactic&lt;/strong&gt; to a system where you don’t get the answer of your latest TRY in 2.3 seconds, but instead in 13 minutes.&lt;/p&gt;
&lt;p&gt;I’ve been working on an adjustment to making our CI system do the bulk of the release process for all 17 officially released modules of Spring Data, and I can tell you…it’s been grueling.&lt;/p&gt;
&lt;p&gt;It takes 20 minutes for Jenkins to run ALL the steps needed for a release.&lt;/p&gt;
&lt;p&gt;And when the LAST step is the one that keeps failing…and when the last step can’t be run without all the preceding steps…&lt;/p&gt;
&lt;p&gt;Well, let’s just say I have devoted additional time over the past three weeks watching LOTS of build jobs fly by. Yes, I pushed things as FAR AS POSSIBLE on a local level.&lt;/p&gt;
&lt;p&gt;But at a certain point, you must test on the CI server itself.&lt;/p&gt;
&lt;p&gt;Yes, I am leveraging Docker containers to ensure my machine and the CI server BOTH HAVE THE SAME ENVIRONMENT.&lt;/p&gt;
&lt;p&gt;And yes, a MacBook Pro M1 Pro laptop and a Linux-based Jenkins server have differences I never expected, even in Docker.&lt;/p&gt;
&lt;p&gt;But I learned long ago in the formation of my career, that Jenkins ain’t messing with some newbie. Nope.&lt;/p&gt;
&lt;p&gt;Jenkins, as of midnight last night, began to crumble before me.&lt;/p&gt;
&lt;p&gt;Jenkins, as of midnight last night, began to realize that no matter WHAT it threw my way, my Google Fu was unstoppable and would not yield.&lt;/p&gt;
&lt;p&gt;Jenkins, as of midnight last night, began to regret picking this fight with me.&lt;/p&gt;
&lt;p&gt;Jenkins, as of midnight last night, began to understand that defying me three weeks ago was a mistake.&lt;/p&gt;
&lt;p&gt;Yes, this is emotional. Software development is. Always has been. The sooner you accept this, the sooner you can grow your OWN skills and conquer the systems put before you.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*_iOXmA690ruMpXFUoY0KfQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this video where I share a recent situation that threw ME for a loop…and how I dug my way out.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="437" medium="image" url="https://www.procoder.io//_astro/1_mEGWo8aj61rVqwcn1pjGmg.DNars3XO.png"/></item><item><title>5 tools every Spring developer should have</title><link>https://www.procoder.io/articles/2022/2022-08-11_5-tools-every-spring-developer-should-have-b034352e5932</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-08-11_5-tools-every-spring-developer-should-have-b034352e5932</guid><description>When it comes to building apps with Spring Boot, there are a handful of tools I turn to every day. Some are free. Some are not.</description><pubDate>Thu, 11 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When it comes to building apps with Spring Boot, there are a handful of tools I turn to every day. Some are free. Some are not.&lt;/p&gt;
&lt;p&gt;But ALL of them pay me back in time and value.&lt;/p&gt;
&lt;p&gt;So let’s check it out!&lt;/p&gt;
&lt;h3 id=&quot;1sublimetext&quot;&gt;1 — Sublime Text&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/hyut&quot;&gt;Sublime Text is a KILLER text editor&lt;/a&gt;. To call it a text editor is an understatement. This thing has contextual awareness of just about any file type I’ve run into. Java, shell scripts, Python, XML. You name it.&lt;/p&gt;
&lt;p&gt;It also can smell variable names and offer bits of completion not available in other text editors. In fact, some people use Sublime Text as their IDE.&lt;/p&gt;
&lt;p&gt;Sublime Text has a free trial version. The trial period has no defined date, so you can use it free forever. If you like and enjoy it, I encourage you to purchase a license and help support it.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*in_HBYVQkxoOennq14obkg.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;“Text editor” doesn’t really capture the power that is Sublime Text&lt;/p&gt;
&lt;h3 id=&quot;2intellijidea&quot;&gt;2 — IntelliJ IDEA&lt;/h3&gt;
&lt;p&gt;Once, long ago, I was a hardy Eclipse user. Eclipse was pretty nifty. Much edgier and more functional than the commercial one we were provided (at at previous job).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/wr23&quot;&gt;But then I took IntelliJ for a test drive&lt;/a&gt;. I was blown away.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It had this “awareness”. As if, when I would try to do something…it KNEW what I was doing and offered me a shortcut. It was clearly looking at the type of file I would be editing (Java), seeing the non-existent variable I had just made a reference to, and when I went to the top of the class and started to define it, would offer me the SAME NAME of variable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This type of situational awareness is hard to beat.&lt;/p&gt;
&lt;p&gt;That’s not all. It’s loaded amazing code completion tricks, refactoring tools, and if you’re looking for files and classes, amazing ways to do partial matches and FIND what you’re looking for. Fast. With minimal keystrokes.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*6xAYPfnmrmqrUsfPUBvE1A@2x.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Code completion is AWESOME!&lt;/p&gt;
&lt;h3 id=&quot;3airpodspro&quot;&gt;3 — AirPods Pro&lt;/h3&gt;
&lt;p&gt;This may sound weird, but wireless earbuds is a game changer. When I &lt;a href=&quot;https://trnq.st/rfam&quot;&gt;grabbed a pair of Apple AirPod Pros on Amazon Prime Day&lt;/a&gt; (with an $80 cut in price), I discovered how it became much easier to take my work environment with me.&lt;/p&gt;
&lt;p&gt;I work remotely, and with three kids home for the summer, this sometimes involves working at the dining table, in the living room, and other places as well.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I also sometimes work in a coffee shop. While I’ve had wired earbuds for years, I never hardly used them. Too. Dang. Hard.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But with wireless, it became much easier to pull them out, fire up my favorite coding playlist, and focus.&lt;/p&gt;
&lt;p&gt;They are REAL useful for team Zoom chats. And I even discovered that they sizzle during YouTube videos and live streams! Now I can have all the music and guest audio piped into my ears. Getting up to adjust a light or move the microphone is a snap.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*9-142D_WuzU8yPGJPWEygQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Me, with my AirPod Pros!&lt;/p&gt;
&lt;h3 id=&quot;4the-stayapp&quot;&gt;4 — The “Stay” App&lt;/h3&gt;
&lt;p&gt;When I started working from home, and had bought a 39” 4K TV set as my main monitor, I ran into a really ANNOYING issue.&lt;/p&gt;
&lt;p&gt;Anytime I hooked up my MacBook Pro, the windows would go all wonky. I would spend five minutes moving them around.&lt;/p&gt;
&lt;p&gt;Later I’d unhook, and everything would be wrecked. I’d fix the window arrangement. But then the next, when I’d reconnect to that giant TV…again I’d be battling window layouts.&lt;/p&gt;
&lt;p&gt;While five minutes isn’t a LOT, it’s DANG annoying!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://trnq.st/30ig&quot;&gt;So I spent a couple hours hunting down the Stay app.&lt;/a&gt; An app that would remember for ALL monitor configurations and let me record the location of every window.&lt;/p&gt;
&lt;p&gt;For a tiny one-time fee of $15, I can now change environments with ease. When I hook up to my giant TV, all the windows jump to their proper position. When I unhook, they switch to my laptop-only mode. If I connect to a new environment like an overhead in a conference room, I can shuffle the windows around, hit a hotkey, and record THAT setup.&lt;/p&gt;
&lt;p&gt;This tiny app makes it really easy to float around and not be sweating the small stuff.&lt;/p&gt;
&lt;h3 id=&quot;5dockerdesktop&quot;&gt;5 — Docker Desktop&lt;/h3&gt;
&lt;p&gt;In this day and age, with the emergence of Testcontainers and other Docker-based things, it’s practically a requirement to have &lt;a href=&quot;https://trnq.st/lsvh&quot;&gt;Docker Desktop&lt;/a&gt;, the current tool that lets you run Docker containers locally.&lt;/p&gt;
&lt;p&gt;It used to be a bugbear if you weren’t on a Linux machine. But now, they sneak in a tiny virtual machine inside the product and handle all the ceremony of making it available.&lt;/p&gt;
&lt;p&gt;And you really need to know some barebones knowledge about Docker. It turns out that running real instances of Postgres, RabbitMQ, MongoDB, and other things is quite handy when needed.&lt;/p&gt;
&lt;p&gt;It’s free for small stuff, but if part of bigger shop, then that’s different.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this video where I dig in deeper about the tools you need, including IDEs, if you really want to become a pro coder!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="395" medium="image" url="https://www.procoder.io//_astro/1_in_HBYVQkxoOennq14obkg.Bbfl55Il.png"/></item><item><title>JDBC vs. JPA</title><link>https://www.procoder.io/articles/2022/2022-08-03_jdbc-vs--jpa-623fe8258e8</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-08-03_jdbc-vs--jpa-623fe8258e8</guid><description>In the land of software development, we sure love acronyms. Our acronyms in the land of Java-apps-talking-to-database, there is no shortage…</description><pubDate>Wed, 03 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the land of software development, we sure love acronyms. Our acronyms in the land of Java-apps-talking-to-database, there is no shortage there.&lt;/p&gt;
&lt;p&gt;And maybe this leads to confusion: What do I use? Everyone else is using JPA? Should I? But I heard about Spring Data JDBC? And what about Spring Data JPA?&lt;/p&gt;
&lt;p&gt;In this article, we’ll talk about JDBC, JPA, where they came from, and the tradeoffs that exist.&lt;/p&gt;
&lt;h3 id=&quot;once-long-ago-there-wasjdbc&quot;&gt;Once, long ago, there was JDBC&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;JDBC&lt;/strong&gt; is the &lt;strong&gt;Java Database Connectivity API&lt;/strong&gt;. This is an &lt;em&gt;old&lt;/em&gt; standard, going all the way back to the days of Java 1.1 in 1997. And this API has served us well.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*NTKHstABdGRBZTRfsJUefA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;It’s “old data”. Get it?Everything, and I mean EVERYTHING that talks to databases goes through &lt;strong&gt;JDBC&lt;/strong&gt;. And that has its pros and cons. Basically, &lt;strong&gt;JDBC&lt;/strong&gt; is the Java implementation of the standard dance ALL technologies have played to interact with databases.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open connection.&lt;/li&gt;
&lt;li&gt;Open cursor.&lt;/li&gt;
&lt;li&gt;Submit query.&lt;/li&gt;
&lt;li&gt;Iterate over result set.&lt;/li&gt;
&lt;li&gt;Close result set/cursor.&lt;/li&gt;
&lt;li&gt;Close connection.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And we’ve all probably suffered the fate of implementing twenty queries, and forgetting to CLOSE one of those resources along the way. And then, six weeks later, getting a scary stack trace because somehow our database has run out of connections or cursors.&lt;/p&gt;
&lt;p&gt;We track down the issue. Patch it. Release it.&lt;/p&gt;
&lt;p&gt;And then eight weeks later, we find another. This is what happens when we are on the hook for managing something that shouldn’t be that hard to manage.&lt;/p&gt;
&lt;p&gt;And Spring saw this and took note. With one of its most &lt;a href=&quot;/articles/medium/2022-07-21_software-patterns-in-2022-b1bdd2cfcb66&quot;&gt;popular and powerful coding patterns&lt;/a&gt;, Spring Framework release &lt;strong&gt;JdbcTemplate&lt;/strong&gt;. A template that basically lets you focus on submitting queries and consuming the results.&lt;/p&gt;
&lt;p&gt;All resource management was handled by the toolkit. &lt;strong&gt;Never again&lt;/strong&gt; will you get a call at 3:00 AM because the database/your app has blown up.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Okay, maybe you still get those middle of the night calls. But not because you didn’t close a connection!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The thing is, once you’ve written two hundred queries, that amount of raw power capture in those strings becomes kind of overwhelming.&lt;/p&gt;
&lt;p&gt;In fact, along the way, after your thirteenth query against that same Item object, you wondered, “why can’t Java SEE the type…and just do it for me?”&lt;/p&gt;
&lt;p&gt;Welcome to &lt;strong&gt;Hibernate&lt;/strong&gt;, the forerunner of &lt;strong&gt;JPA&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;hello-hibernate&quot;&gt;Hello, Hibernate&lt;/h3&gt;
&lt;p&gt;Two things we’ve battled with other the years includes mapping table rows to Java objects as well as variations between relational database implementations.&lt;/p&gt;
&lt;p&gt;Do I REALLY need to rewrite my Oracle query when moved to Postgres??&lt;/p&gt;
&lt;p&gt;Sometimes, yes. Because the ANSI SQL spec doesn’t cover all the gaps. So database providers fill gaps.&lt;/p&gt;
&lt;p&gt;Hibernate promised the means to connect Java objects together in a unified way…if we just properly map those tables onto their related Java classes. It started with XML, but took off with Java 5 annotations!&lt;/p&gt;
&lt;p&gt;And the world leaped forward at warp speed!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*fM0kwgSKCnlcyrJuHwXzVQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And while having a neutral way to talk to any database engine on the planet using the SAME query was really cool, there was something else we didn’t REALLY understand.&lt;/p&gt;
&lt;p&gt;Okay, some people saw it coming, but most of us did not.&lt;/p&gt;
&lt;p&gt;You never REALLY escape the concepts of relational table mapping. That’s right. Just because you picked up Hibernate and started using it didn’t mean you could actually STOP thinking in terms of relational databases.&lt;/p&gt;
&lt;p&gt;For the simplest queries, yes you can.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;select i from Item i where i.description like ‘%:partialDescription%’&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That kind of query is straight forward. It makes sense. And it’s universal.&lt;/p&gt;
&lt;p&gt;This was the kind of stuff that once you got things up and running, Hibernate really had you humming. In fact, it was so popular, people sometimes referred to Spring + Hibernate and peanut butter with chocolate.&lt;/p&gt;
&lt;p&gt;And so they standardized it.&lt;/p&gt;
&lt;h3 id=&quot;hibernate-thy-name-isjpa&quot;&gt;Hibernate, thy name is JPA&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;JPA&lt;/strong&gt; is the &lt;strong&gt;Java Persistence API&lt;/strong&gt; (acronym within an acronym FTW!) Hibernate became the reference implementation for it. Most shops using &lt;strong&gt;JPA&lt;/strong&gt; today are in fact using Hibernate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JPA&lt;/strong&gt; was so profound that one could say &lt;strong&gt;JPA gives you wings&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;But inevitably, we discover that there is a deep, dark secret to JPA. Something that either someone TOLD US, or something we assumed on our own.&lt;/p&gt;
&lt;p&gt;You never, ever get away from the concept of a relational database tables. As you write more complex, more entangled, more business-oriented queries, you discover that sometimes your Java objects don’t FIT that paradigm.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You discover that you are simply exchanging your knowledge of SQL for your knowledge of JPA.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s possible. In fact, it’s quite powerful. And sometimes, that power needs a little assistance, hence the creation of &lt;strong&gt;Spring Data JPA&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spring Data JPA&lt;/strong&gt; can help you with simpler queries, and dodge the need to work TOO MUCH with JPA’s &lt;strong&gt;EntityManager&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But eventually, you have to get your hands into manually-written JPQL queries.&lt;/p&gt;
&lt;p&gt;And if you believe you can write a highly detailed, complex, and finely tuned JPQL query and then SOMEHOW customize the SQL output, you are in for a rude awakening.&lt;/p&gt;
&lt;p&gt;You see, it was common paradigm in the olden days to write several dozen queries for your system. Then, through the magic of DBA feedback and daily experience, to spot what queries were the most inefficient and taking too long. And by leveraging EXPLAIN PLANs, you could see HOW your query was wasting time.&lt;/p&gt;
&lt;p&gt;You’d then attack things by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create better indexes.&lt;/li&gt;
&lt;li&gt;Ensure statistics are running properly.&lt;/li&gt;
&lt;li&gt;Rewrite certain joins.&lt;/li&gt;
&lt;li&gt;STOP using UPPER (or LOWER) on everything to avoid full table scans.&lt;/li&gt;
&lt;li&gt;Don’t join the same table ten times! (Yes, I once found a view that did that.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And a dozen other tactics. You would tune your queries and something that may have taken twenty minutes could be optimized into a sub-second query. This was par for the course in database/application maintenance.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let’s just say, you ain’t doing that with the output of JPA.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And this is what some have come to dub the &lt;strong&gt;9th Circle of JPA&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*u_qL5kdI8Uq1ihk4ERvMUg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Maybe this is your jam? Maybe this is cool for you? But for many, it can be a bad taste in their mouth.&lt;/p&gt;
&lt;p&gt;And so can you imagine the enthusiasm when &lt;strong&gt;Spring Data JDBC&lt;/strong&gt; emerged back in 2017? In fact, my teammate Jens’ talk at the 2018 SpringOne conference resulted in a room PACKED with people, eager to hear the news.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spring Data JDBC&lt;/strong&gt; offers a way to pull back from the edge of the JPA abyss. It’s pretty cool. Check it out if you want to understand more.&lt;/p&gt;
&lt;p&gt;Spring Data JBDC attempts to do a lot of the work for you. But it doesn’t do EVERYTHING that good ole Hibernate would do. It presumes that if you were to handle a little bit yourself, you can retain some of the vim and vigor pure JDBC allowed. This where you now get the ability to see and understand your queries.&lt;/p&gt;
&lt;p&gt;This is where you get the ability to tune SQL statements more to your liking. Face it, there must ALWAYS be some amount of tuning to make things hum.&lt;/p&gt;
&lt;p&gt;And in exchange for handling a little more on your end, you can avoid getting pulled in potentially to the La Brea tarpit of ORMs!&lt;/p&gt;
&lt;p&gt;No matter what you pick (&lt;strong&gt;JdbcTemplate&lt;/strong&gt;, &lt;strong&gt;Spring Data JPA&lt;/strong&gt;, &lt;strong&gt;Spring Data JDBC&lt;/strong&gt;), hopefully by understanding more about their underlying standards that support them, you can make a solid choice about what best meets your needs.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this video, where we discuss entities vs. DTOs and what it all means!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="954" medium="image" url="https://www.procoder.io//_astro/1_NTKHstABdGRBZTRfsJUefA.CWGk5odG.png"/></item><item><title>5 ways to find data with Spring Data</title><link>https://www.procoder.io/articles/2022/2022-07-28_5-ways-to-find-data-with-spring-data-91766c74fa8e</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-07-28_5-ways-to-find-data-with-spring-data-91766c74fa8e</guid><description>Spring Data provides all kinds of ways to interact with your data store. But do you know them ALL? Odds are, you haven’t seen them all.</description><pubDate>Thu, 28 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Spring Data provides all kinds of ways to interact with your data store. But do you know them ALL? Odds are, you haven’t seen them all.&lt;/p&gt;
&lt;p&gt;And you may be suffering from wasting your time on some queries because of it.&lt;/p&gt;
&lt;p&gt;In this article, find out ALL the ways you can access your data, and see which one is for YOU!&lt;/p&gt;
&lt;h3 id=&quot;1-customfinders&quot;&gt;1 —Custom finders&lt;/h3&gt;
&lt;p&gt;The simplest and most eye-catching solution (to me) is your ability to write a custom query WITHOUT WRITING any, well, query, is this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public interface ItemRepository extends CrudRepository&amp;#x3C;Item, Long&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    List&amp;#x3C;Item&gt; findBySku(String sku);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In a system where you have defined your &lt;strong&gt;Item&lt;/strong&gt; type, and it has a field tracking its &lt;strong&gt;SKU&lt;/strong&gt; value, you can do that by writing what’s above.&lt;/p&gt;
&lt;p&gt;This tactic to craft a custom finder is known as &lt;strong&gt;query derivation&lt;/strong&gt;. Spring Data simply parses the name of the method, sees the “findBy” prefix and also the names of the fields inside Item, and is able to craft a query. It also binds the incoming argument and then fashions the output to work with a standard Java &lt;strong&gt;List&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Spring Data also supports return types including &lt;strong&gt;Iterable&lt;/strong&gt;, &lt;strong&gt;Stream&lt;/strong&gt;, &lt;strong&gt;Flux&lt;/strong&gt;, &lt;strong&gt;Optional&lt;/strong&gt;, and more.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But what if you don’t know all the criteria needed to fetch? What if they keep changing? Then check out the next section.&lt;/p&gt;
&lt;h3 id=&quot;2query-byexample&quot;&gt;2 — Query by Example&lt;/h3&gt;
&lt;p&gt;Query by Example is a way to allow someone &lt;em&gt;else&lt;/em&gt; to provide the criteria for finding data. A simple example is building a search box on the web page where someone wants to search your inventory of &lt;strong&gt;Item&lt;/strong&gt; objects.&lt;/p&gt;
&lt;p&gt;If they entered SKU, name, or description, you can then feed those details into a probe. Any parameters that are NOT null will be queried against!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Item probe = new Item();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;probe.setSku(searchForm.getSku());  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;probe.setName(searchForm.getName());  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;probe.setDescription(searchForm.getDescription());&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Example&amp;#x3C;Item&gt; example = Example.of(probe);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;itemRepository.findAll(example);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The default behavior for Query by Example is to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ignore any fields that are &lt;strong&gt;null&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Join all criteria as an &lt;strong&gt;AND&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Match completely on each field&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you wanted to alter things, such as joining via OR, ignoring entire fields completely, or partially matching one (or all) fields, then you can.&lt;/p&gt;
&lt;p&gt;But either way, this lets you quickly query for data based on varying criteria that may not be known until runtime.&lt;/p&gt;
&lt;p&gt;But what if you need to harness some of that deeper more powerful huzzah your data store has? Then you need to check into the next few sections.&lt;/p&gt;
&lt;h3 id=&quot;3template-based&quot;&gt;3 — Template-based&lt;/h3&gt;
&lt;p&gt;Spring Data MongoDB has &lt;strong&gt;MongoTemplate&lt;/strong&gt;. Spring Data for Apache Cassandra has &lt;strong&gt;CqlTemplate&lt;/strong&gt;. And Spring Data Redis has about a million various templates.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In case you’re wondering, old timey Spring Framework once had a &lt;strong&gt;JpaTemplate&lt;/strong&gt; as well as a &lt;strong&gt;HibernateTemplate&lt;/strong&gt;, but Hibernate/JPA evolved such that these templates no longer fit the bill. See further down how dropping down to the data store’s native API is always an option!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Basically, just about any Spring module has a template to help you dive into using native operations quickly and PROPERLY.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Item newItem = new Item(&quot;Smurf TV tray&quot;, &quot;SKU-12345&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mongoTemplate.insert(newItem);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mongoTemplate.updateFirst(  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    query(where(&quot;sku&quot;).is(&quot;SKU-12345&quot;)),   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    update(&quot;price&quot;, 19.99),   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Item.class);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Templates are geared toward giving you access to the data store’s power without getting caught up in resource management.&lt;/p&gt;
&lt;p&gt;(BTW, this fragment isn’t all that &lt;strong&gt;MongoTemplate&lt;/strong&gt; has to offer.)&lt;/p&gt;
&lt;p&gt;While a powerful tool, your code will certainly NOT be portable! If a custom finder is getting too complicated, it may be time to switch to the data store’s template.&lt;/p&gt;
&lt;p&gt;But what if using this template-based API is really just getting in the WAY of your need to write a store-specific query YOU ALREADY WROTE?&lt;/p&gt;
&lt;h3 id=&quot;4query&quot;&gt;4 — @Query&lt;/h3&gt;
&lt;p&gt;All Spring Data modules offer you a really cool way to just Write The Query Yourself.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public ItemRepository extends JpaRepository&amp;#x3C;Item, Long&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    @Query(&quot;select i from Item i where i.sku = :sku&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    List&amp;#x3C;Item&gt; myHandWrittenQuery(String sku);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While the example above is a bit contrived, a business office query that took you three weeks to write and joins twenty different tables is real. (I once wrote one!)&lt;/p&gt;
&lt;p&gt;And trying to twist and bend JPA to do the same thing may take you triple the time. If you already have the query, just stuff it into an @Query annotation like this and move on!&lt;/p&gt;
&lt;p&gt;Spring Data will still handle opening and closing connections, mapping results, and all that good stuff. It will simply let YOU take the role of writing the queries!&lt;/p&gt;
&lt;p&gt;And while this example is about Spring Data JPA, you’ll find counterpart annotations in most other modules as well.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*24Yrvoye3Aq5ktsRRpA0OA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;But sometimes even THAT isn’t quite enough!&lt;/p&gt;
&lt;h3 id=&quot;5-dropping-down-to-the-datastore&quot;&gt;5— Dropping down to the data store&lt;/h3&gt;
&lt;p&gt;Sometimes you REALLY need Spring Data to get out of the way. Whether that means talking straight to JPA’s entity manager&lt;/p&gt;
&lt;p&gt;Spring Data JPA lets you talk to the &lt;strong&gt;EntityManager&lt;/strong&gt;. Spring Data MongoDB allows you to use a &lt;strong&gt;ClientSession&lt;/strong&gt;. Spring Data Cassandra has the &lt;strong&gt;CqlSession&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;All of these are native connections to talk directly to the data store using their own APIs. And Spring Boot autowires an instance into the application context. At any time, in any Spring bean, you can ask for an instance and talk straight to the data store.&lt;/p&gt;
&lt;p&gt;Spring Data will get out of your way. This is only recommended as a last resort. It will be up to you to use the right interactions and properly manage resources. But if that’s what you need, then do it! (Just be sure to file any tickets with the original data store, okay?)&lt;/p&gt;
&lt;p&gt;Spring Data is meant to ease your efforts at accessing data for your application and provides you with multiple ways to do it. And it gets in your way, you can sidestep it and go straight in. The choice is yours.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out the following video where I show you how to test your Spring Data repositories…using a REAL database!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_24Yrvoye3Aq5ktsRRpA0OA.CtZMOK8t.jpeg"/></item><item><title>Software Patterns in 2022</title><link>https://www.procoder.io/articles/2022/2022-07-21_software-patterns-in-2022-b1bdd2cfcb66</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-07-21_software-patterns-in-2022-b1bdd2cfcb66</guid><description>Once, long ago, a fledgling coder grasped a beautiful tome titled “Design Patterns: Elements of Reusable Object-Oriented Software”…</description><pubDate>Thu, 21 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Once, long ago, a fledgling coder grasped a beautiful tome titled “Design Patterns: Elements of Reusable Object-Oriented Software”. Otherwise known as the “Gang of Four” book.&lt;/p&gt;
&lt;p&gt;And it was good.&lt;/p&gt;
&lt;p&gt;He read through it after hours, his ears perking up. Pattern after pattern. And in his very next project, he tried to USE the patterns. ALL of the patterns.&lt;/p&gt;
&lt;p&gt;And it was bad.&lt;/p&gt;
&lt;p&gt;If you didn’t catch on, that was me. What I did was wrong. 100% wrong. Spiritually, &lt;em&gt;ecumenically&lt;/em&gt;, &lt;em&gt;&lt;strong&gt;grammatically&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*ZRc5qJ4JPcJM2zsvzzdpEA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Arrrgh!!! Too many patterns!And that’s when I realized that software wasn’t just about patterns. I began to learn that TRUE engineering is about tradeoffs. And so when &lt;a href=&quot;https://trnq.st/cere&quot;&gt;I started writing my own software books&lt;/a&gt;, by golly, I included tradeoffs. I didn’t want another developer to suffer the same fate as me.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So what patterns should you look for in 2022? And what are THEIR tradeoffs? Let’s see!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;1templates&quot;&gt;1 — Templates&lt;/h3&gt;
&lt;p&gt;Templates offer developers shorthand ways to do stuff. They often arise when a full-blown API has too many options and lead to confusion. Templates can wrap such APIs and offer clear cut ways through the API confusion.&lt;/p&gt;
&lt;p&gt;Spring is loaded to hilt with templates. One of my favorite being &lt;strong&gt;JdbcTemplate&lt;/strong&gt; (the thing that drew me into the Spring Framework in the first place!) &lt;strong&gt;JdbcTemplate&lt;/strong&gt; has a handful of operations including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;query()&lt;/strong&gt;, &lt;strong&gt;update()&lt;/strong&gt;, &lt;strong&gt;delete()&lt;/strong&gt;, &lt;strong&gt;execute()&lt;/strong&gt;, and &lt;strong&gt;call()&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;There are overloaded variations as well as things like &lt;strong&gt;queryForObject()&lt;/strong&gt;, &lt;strong&gt;queryForList()&lt;/strong&gt;, and &lt;strong&gt;queryForMap()&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;But NOT anything about opening and closing connections and cursors!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The whole POINT of &lt;strong&gt;JdbcTemplate&lt;/strong&gt; is to take that off your hands. Use this template and you can focus on writing JDBC queries. Let the template handle resources.&lt;/p&gt;
&lt;p&gt;Templates are still relevant today. Spring Data in recent months added a new fluent API to supporting modules to make it easier to express a query without getting bogged down in query language specifics. It’s basically another template.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RestTemplate&lt;/strong&gt; is Spring Framework’s venerable tool to speak to remote services through HTTP. It’s creator, Arjen Poutsma, once presented to a packed room. Today, a newer variant with reactive programming supporting baked has emerged: &lt;strong&gt;WebClient&lt;/strong&gt;. Both of these offer powerful ways to speak HTTP without having to get dragged into the complexity of the HTTP dance.&lt;/p&gt;
&lt;p&gt;If you have some “recipe” you seem to keep copying everywhere, consider putting it into a template.&lt;/p&gt;
&lt;h3 id=&quot;2builders&quot;&gt;2 — Builders&lt;/h3&gt;
&lt;p&gt;A builder’s job is to gather all the information needed to assemble an object, but wait until the user invokes the &lt;strong&gt;build()&lt;/strong&gt; method before assembling the object.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*gC5P4YJ7tpyMR0_PiBHVNQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Can he build it? Yes he can!This one is trickier to assess whether it’s worth it to create the machinery. Sometimes, the best “builder” is a constructor call. Or two or three. Builders begin to shine when the information that must be provided isn’t in your hands all at once.&lt;/p&gt;
&lt;p&gt;For example, if you need to ask the user a series of questions through various forms. Or if you need to make some other method calls. Builders let you plug in the values, as you gather them, building up this intermediate state. And then once you it all, you can MAKE the object.&lt;/p&gt;
&lt;p&gt;This is also presuming you do NOT want to “make the object” BEFORE you have all the information.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Back in the day, setter injection was really popular. But the risk of a half-baked object has risen, and so today, it’s good practice to ONLY create an object when you have all the information on hand.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As tantalizing as they are, patterns are just a way to&lt;/p&gt;
&lt;p&gt;Knowledge from on high, carried to the common coder. And just like the mythical tale of fire carried from Olympus to Earth, so, too, did this fountain of knowledge have dangers of untold tales.&lt;/p&gt;
&lt;p&gt;You see, this book was chock full of ways to solve problems. But it came up short in trade offs. It said WHAT to do but not so much WHEN to do them.&lt;/p&gt;
&lt;h3 id=&quot;3injected-interfaces&quot;&gt;3 — Injected Interfaces&lt;/h3&gt;
&lt;p&gt;This pattern may seem kind of strange, but hear me out.&lt;/p&gt;
&lt;p&gt;If you have some concrete object that needs to act one way in this environment, but a different way in another environment, sometimes the simplest thing is to swap out that object for an interface. And then inject the concrete solution.&lt;/p&gt;
&lt;p&gt;Imagine you had a &lt;strong&gt;KitchenService&lt;/strong&gt; that provided &lt;strong&gt;Meal&lt;/strong&gt; instances. It’s not hard to imagine building up all the actions this KitchenService would have. We could craft things like &lt;strong&gt;fetchIngredients()&lt;/strong&gt;, &lt;strong&gt;cookMeal()&lt;/strong&gt;, and &lt;strong&gt;plateTheFood()&lt;/strong&gt;. Simple enough, right?&lt;/p&gt;
&lt;p&gt;We always run into situations where the concrete scenario that we started with needs to evolve. Maybe we started this imaging our system serving up French cuisine, but something needs to pivot when we need an Italian-based kitchen?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While the French kitchen uses &lt;strong&gt;grabTheButter()&lt;/strong&gt; relentlessly, the Italian one MUST have &lt;strong&gt;grateTheCheese()&lt;/strong&gt;!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s okay to have a concrete instance buried deep early on. But in this evolving scenario, carry out the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Replace the class definition of &lt;strong&gt;KitchenService&lt;/strong&gt; with an interface of the same name.&lt;/li&gt;
&lt;li&gt;Implement it with &lt;strong&gt;FrenchKitchenService&lt;/strong&gt;, migrating your existing code there.&lt;/li&gt;
&lt;li&gt;Now implement &lt;strong&gt;ItalianKitchenService&lt;/strong&gt; and inject it for your new scenario through an updated constructor call!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*dT2l9zivmyVsWqYe0_L21A.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Make your code SAVORY using injectable interfaces!Another keen benefit is that you can now inject test mocks and stubs in testing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What’s key in applying this pattern is to ONLY DO THIS when you NEED TO. Don’t start off with making EVERYTHING an interface!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nope.&lt;/p&gt;
&lt;p&gt;Start cobbling things together with concrete instances. Only when situations arise that demand variations should you consider this tactic. This type of litmus test can serve as a good gut check on whether or not something warrants an injection point or not.&lt;/p&gt;
&lt;h3 id=&quot;4strategies&quot;&gt;4 — Strategies&lt;/h3&gt;
&lt;p&gt;Let’s wrap up this article with one more pattern that is still quite relevant today. And that is what is sometimes called a strategy interface or simply a strategy.&lt;/p&gt;
&lt;p&gt;It’s kind of like the previous one, but not really. Yes, this is an injectable interface. But that’s about it when it comes to similarities.&lt;/p&gt;
&lt;p&gt;The previous pattern speaks to injecting concrete instances that contain entire flows of operations. A strategy is more about turning this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if (policy == NetworkMode.ONLINE) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    download();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;} else if (policy == NetworkMode.OFFLINE) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    skipDownload();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;into this…&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class OnlineStrategy implements NetworkModeStrategy {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    public void download() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        // download it already!  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class OfflineStrategy implements NetworkModeStrategy {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    public void download() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        // do nothing!  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, an IDE that while in &lt;strong&gt;ONLINE&lt;/strong&gt; mode would download artifacts from maven central, but in &lt;strong&gt;OFFLINE&lt;/strong&gt; mode…doesn’t.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The idea is to capture a common operation (&lt;strong&gt;download()&lt;/strong&gt;), and implement based on something like the user toggling a button. Or the system detecting a network outage. Or…whatever!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Swap out one strategy for another. This strategy can be changing…or it can be driven by startup conditions. Maybe your code publishes user-based events if the web page is loaded, but it doesn’t if you’re running in headless mode?&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Rttn3joRSmx2V0X-_R4Nsg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;The scope of what the strategy does is much simpler. But this tactic is quite effective. And it opens the doors to expanding your options in the future. If you find yourself coding the same if-then clause (or switch statement) in multiple places, it could be a sign that you need to inject a strategy instead.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this episode of my podcast, where we learn how to effectively test Spring MVC web controllers using the tools of Spring Boot!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="331" medium="image" url="https://www.procoder.io//_astro/1_ZRc5qJ4JPcJM2zsvzzdpEA.Bxxle521.png"/></item><item><title>When to NOT use Spring Boot!</title><link>https://www.procoder.io/articles/2022/2022-07-14_when-to-not-use-spring-boot--96a64574497d</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-07-14_when-to-not-use-spring-boot--96a64574497d</guid><description>Spring Boot is awesome. Spring Boot is great. It’s the bee’s knees. So why would you NOT want to use it? That’s what we’ll cover in this…</description><pubDate>Thu, 14 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Spring Boot is awesome. Spring Boot is great. It’s the bee’s knees. So why would you NOT want to use it? That’s what we’ll cover in this article.&lt;/p&gt;
&lt;h3 id=&quot;1you-already-have-a-working-application&quot;&gt;1 — You already have a working application&lt;/h3&gt;
&lt;p&gt;Something we developers have a problem with is being handed an already-working application. It’s loaded with twisted paths of logic and coded with gnarly patterns. Oftentimes, this ball of mud before us screams “just rewrite me!”&lt;/p&gt;
&lt;p&gt;And many-a-times, this is a mistake.&lt;/p&gt;
&lt;p&gt;What we don’t realize is that this code contains a lot of information. A lot of knowledge. Many vital decisions, meetings, and analyses are tied up in this precious little hunk of code.&lt;/p&gt;
&lt;p&gt;Simply rewriting it implies that not only can we write its immediate function better. We can handle all those nasty corner cases that had to be dealt with. Customer issues. Vendor wrinkles. The whole of it.&lt;/p&gt;
&lt;p&gt;So before you reach for the almighty Spring Boot in the hopes of rewriting something written with a “lesser” toolkit, consider that maybe you’d be better off UNDERSTANDING the thing first.&lt;/p&gt;
&lt;p&gt;Spend time learning its test kits. Make some additions and adjustments by first writing new tests. Once you’ve walked a few miles in that app’s proverbial shoes, you may just have a better understanding of how Spring Boot can help.&lt;/p&gt;
&lt;p&gt;And maybe you won’t have to REWRITE it so much as ADAPT it to the world of Spring Boot.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*RyQgvXgnC2AIzoAIMPy3qg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;ADAPT usually beats REWRITE!### 2 — You could use…something else!&lt;/p&gt;
&lt;p&gt;We certainly love writing those Spring MVC controllers, crafting those Spring Data repositories, and locking it down with Spring Security policies. It’s fun to wield such power.&lt;/p&gt;
&lt;p&gt;But is this really the best use of your time?&lt;/p&gt;
&lt;p&gt;I recently wanted to roll my own “bit.ly”. A web site that would me create short links using my OWN domain. I had briefly looked up the cost of going bit.ly itself and paying to use a custom domain.&lt;/p&gt;
&lt;p&gt;Nope.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*U7OD-OXrP0KwNudfh2ym9Q.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;*To code it myself or NOT to code it myself…that is the question!*Instead, I did a little extra research and opted to craft a lightweight Wordpress site with the Pretty Links plugin! The truth is, most of my time was hunting down the right domain and finding a domain provider that sell it to me. I found the official provider of .st domains in São Tomé, did some hunting, and found I could easily register &lt;a href=&quot;https://trnq.st&quot;&gt;https://trnq.st&lt;/a&gt; for just 29 EUR a year!&lt;/p&gt;
&lt;p&gt;With that setup, I configured Cloudflare DNS and had a Wordpress site rolled and operational within 48 hours.&lt;/p&gt;
&lt;p&gt;Now imagine trying to code a site that did A) random URL slugs, B) optionally custom URL slugs, C) metrics tracking, D) and the UI to go with it. Yikes!&lt;/p&gt;
&lt;p&gt;Some things are easier to use already-baked solutions, and frankly NOT worth your personal time. The same can be said if you’re building a blog site or CMS system.&lt;/p&gt;
&lt;p&gt;What’s that I hear? Isn’t &lt;a href=&quot;https://spring.io&quot;&gt;https://spring.io&lt;/a&gt; a custom Spring Boot application? Yes it is. We initially crafted that back in 2014 and gave it a facelift just a couple years ago.&lt;/p&gt;
&lt;p&gt;And it has required a bit of maintenance. Not because Spring Boot is trouble. But simply because ANY CUSTOM SITE YOU BUILD will have Ops-related issues, maintenance demands, and other issues you can’t ever foresee.&lt;/p&gt;
&lt;p&gt;When you reach for someone else’s site-baking toolkit, be it Wordpress or Nuxt or whatever, you are taking advantage of literally MILLIONS of hours of development time from often huge communities. Why presume you can roll that in your off hours?&lt;/p&gt;
&lt;p&gt;And even if you have to pay 29 EUR/year + &lt;a href=&quot;https://trnq.st/hosting&quot;&gt;whatever your hosting provider costs&lt;/a&gt;, it’s still a LOT cheaper than the hours YOU’LL have to spend getting it up and running and then sustaining it!&lt;/p&gt;
&lt;h3 id=&quot;3spring-boot-just-doesntfit&quot;&gt;3 — Spring Boot just doesn’t fit&lt;/h3&gt;
&lt;p&gt;We all like to use our favorite solution everywhere, right? But sometimes, things just don’t fly. If you’re part of a big team, then odds are, more than one application is being built.&lt;/p&gt;
&lt;p&gt;One of the backend systems MAY be using Spring Boot. But another one ISN’T!&lt;/p&gt;
&lt;p&gt;And what if that OTHER system is built by the &lt;em&gt;&lt;strong&gt;&lt;strong&gt;gulp&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt; JavaScript team!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*yBuoxIK5_zBRlmtt61XqwA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;“I am so scared!”All joking aside, the JavaScript team MAY be using Node to do everything. They may use it for the frontend AND the backend.&lt;/p&gt;
&lt;p&gt;And that’s okay. You can’t get your fingers into everything. And if we’re talking about a huge team/contract, then you need to focus on your area of influence.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Getting bent out of shape because another team is NOT using Spring Boot isn’t the way to go.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The other piece in all this is that JavaScript-based systems have an entire WORLD of tools: build systems, deployment tools, IDEs, and management stuff.&lt;/p&gt;
&lt;p&gt;Waltzing in and suggesting to a team of JavaScript pros that they need to cast it all aside isn’t likely to resonate.&lt;/p&gt;
&lt;p&gt;So simply…let it go.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Iy8vemdAE-KbhbB-7kOjKQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 4 — It’s not your decision&lt;/p&gt;
&lt;p&gt;Sometimes, when you join a new team, and they’ve already made a choice on which way to move forward, the opportunity to pick has passed. And it’s your job to implement it!&lt;/p&gt;
&lt;p&gt;Perhaps this comment I’ve just made sounds a little rude? Well, if you’ve joined a team that just finished three weeks of meetings, discussions, and email threads in order to form a plan, then it may be YOU that is rude. That is, if you’re suggesting they drop EVERYTHING and pivot to Spring Boot.&lt;/p&gt;
&lt;p&gt;If you want to be a professional software developer, then one piece of that is communication. And professionals don’t go out of their way to argue and push. Instead, try to learn what decisions were made. Invest time in groking the choices made. And write the best code you can!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*m-uK3VlfrP_SEiIGru2QLg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Just write the best code you canBecause things change. People roll off projects. Some day, YOU may be the lead developer, and you’ll be faced with Yet Another Decision to make for either a new app, or an authorized rewrite of this one.&lt;/p&gt;
&lt;p&gt;And that is the time to apply you’ve learned about the current app along with what you’ve gleaned from Spring Boot Learning, and pitch your best idea (which, hopefully, is Spring Boot!)&lt;/p&gt;
&lt;p&gt;If YOU’RE facing down a decision to Spring Boot or NOT to Spring Boot, then leave me a comment.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this episode of my podcast, where I chatted with a Spring community contributor on the whole of Spring, Spring Boot, OSS, and working together.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content? Then&lt;/em&gt; &lt;a href=&quot;/list&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="263" medium="image" url="https://www.procoder.io//_astro/1_RyQgvXgnC2AIzoAIMPy3qg.B-gCyKuf.jpeg"/></item><item><title>What books should I buy to become a Spring developer?</title><link>https://www.procoder.io/articles/2022/2022-07-07_what-books-should-i-buy-to-become-a-spring-developer--16bb247c7298</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-07-07_what-books-should-i-buy-to-become-a-spring-developer--16bb247c7298</guid><description>I wrote an article over nine years ago talking about this, and it’s woefully due for an update.</description><pubDate>Thu, 07 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I wrote an article over nine years ago talking about this, and it’s woefully due for an update.&lt;/p&gt;
&lt;p&gt;The struggle with answering this, is that when I was learning the ropes of software engineering, my circumstances were different. For one thing, SUN Microsystems was still a company! And Java was a newborn technology people didn’t fully grok.&lt;/p&gt;
&lt;p&gt;But understanding the spirit of new grads and fledgling developers seeking to get a jumpstart on their coding careers, I have built up this list of recommendations I think will benefit you.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*hLybQxUQo5dlajRXnigXvA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Look at all these people LOVING Spring books!### 1 — My books!&lt;/p&gt;
&lt;p&gt;Well, duh! What author isn’t going to recommend their own?&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*1FnEPYZ653rVyjReSXI70Q.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Pre-order your copy today at &lt;a href=&quot;https://trnq.st/book&quot;&gt;https://trnq.st/book&lt;/a&gt;!On a more serious note, I &lt;a href=&quot;https://trnq.st/book&quot;&gt;recommend my own books&lt;/a&gt; because I strive to offer hands-on coding examples along with practical solutions. I also like to point out choice you have to make and the tradeoffs that involves.&lt;/p&gt;
&lt;p&gt;Engineering is fraught with tradeoffs. There is rarely a hard rule that doesn’t have some exception. It’s important to understand the costs and benefits in making choices. And if there’s there one thing I can bring to the table, it’s experience with Real World(TM) systems.&lt;/p&gt;
&lt;p&gt;I worked on a 24x7x365 operational system for ten years. I came in after hours to fix things if they broke. I once came in three times on the same night. Yikes! I built tools to me stave off outages. That sort of crucible hones your ability to build apps as well.&lt;/p&gt;
&lt;p&gt;And so, I try to put some of that experience into my books.&lt;/p&gt;
&lt;h3 id=&quot;2spring-in-action-by-craigwalls&quot;&gt;2 — &lt;em&gt;Spring in Action&lt;/em&gt; by Craig Walls&lt;/h3&gt;
&lt;p&gt;There’s a reason this teammate and personal friend has the &lt;a href=&quot;https://trnq.st/o2oa&quot;&gt;biggest selling title at Manning&lt;/a&gt;. He is a real Spring pro! And he was an expert on Spring when I was but a wee lad. He’s not older. He’s just been in the trenches of Spring development from the early days.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*ck5r8z4TQY_1zBu-fbUfJw.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Grab the latest version of Spring in Action at &lt;a href=&quot;https://trnq.st/o2oa&quot;&gt;https://trnq.st/o2oa&lt;/a&gt;!And he knows LOTS of ins and outs. His content is gold.&lt;/p&gt;
&lt;p&gt;And it’s entertaining. Having written probably more titles than anyone I know (including me), he has honed his writing style to where you can have fun AND learn valuable concepts.&lt;/p&gt;
&lt;p&gt;And he’s always making updates to his tomes of knowledge. Maybe that sounds like a negative, but it’s really a positive. At first blush, you may feel like he’s simply trying to make an extra buck. In truth, you KNOW that he will have a new book in the next 1–2 years with the latest features. Spending $30–40 every other year is a reasonable price for some rock-solid information.&lt;/p&gt;
&lt;h3 id=&quot;3whatever-your-ui-solutionis&quot;&gt;3 — Whatever your UI solution is&lt;/h3&gt;
&lt;p&gt;What is your team using to build its UI? React? Vue? Angular? JavaFX? Swing? Griffon?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you even KNOW what Swing of Griffon are, leave me a comment below!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Whatever your team is using, it is of keen benefit to understand it &lt;em&gt;even if you aren’t directly tasked with building it&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;That’s right.&lt;/p&gt;
&lt;p&gt;Even if you aren’t part of the UI-building team, understanding what they are building will be valuable. It will make YOU more valuable to understand it. To be able to contribute to it, here and there. And, on occasion, to chip in a pull request.&lt;/p&gt;
&lt;p&gt;I’m no expert at JavaScript. I’m more of a Padawan. But this has helped me work with our UI experts and also interact with those on our team that are NOT.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*7UM4mH1oZTdUrAFPIr1nPQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;If THIS is what YOU’RE building, I’d LOVE to see it!### 4 — Whatever your data store solution happens to be&lt;/p&gt;
&lt;p&gt;Where are you storing all your data? Dimes-to-donuts it’s a relational database. Postgres? MySQL? MariaDB? Oracle?&lt;/p&gt;
&lt;p&gt;Even if you’re using something like MongoDB of Apache Cassandra, it’s of benefit for you to go grab be best-selling title on that datastore.&lt;/p&gt;
&lt;p&gt;Boning up your skill son Postgres or MongoDB will help you layer your application on top of that. Understanding tables or document structures will give you the ability to discuss deep-seated solutions that leverage your datastore with maximum power.&lt;/p&gt;
&lt;p&gt;And don’t grab some foolish ANSI SQL book. That’s ridiculous. SQL itself has too many gaps and is spread across too many standards for those books to REALLY help you.&lt;/p&gt;
&lt;p&gt;If your team is using Postgres, grab a Postgres book and start reading! Interoperability isn’t as valuable as leveraging that datastore to the hilt. The odds your management will decide to ditch Postgres and switch to MariaDB are pretty much nil.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*UK3NWwokTrAmHvGNmQ_9Hw.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;### 5 — BONUS TIP&lt;/p&gt;
&lt;p&gt;There’s one ADDITIONAL tip I want to offer.&lt;/p&gt;
&lt;p&gt;It’s not something you’ll find in a book or a handout or a LinkedIn post.&lt;/p&gt;
&lt;p&gt;It’s this — create a Google Document and start taking notes. Daily notes. Write down what you’re working on. Write down what you’re struggling with.&lt;/p&gt;
&lt;p&gt;Create an engineer’s journal.&lt;/p&gt;
&lt;p&gt;You see, when I started my career long ago, before Google was even a thing, I had a small notebook. I wrote down daily activities. Routine actions. Stuff I would do.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*8F-72NVYRBdeqsG4_8cuCA.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Journaling, “old school”That fell by the wayside, but I recently upgraded that concept and started writing myself a personal journal in a Google Document that is just for me.&lt;/p&gt;
&lt;p&gt;And it has, more than anything, served as a way to gauge my activity. It gives me instant feedback on my personal development velocity.&lt;/p&gt;
&lt;p&gt;And, because I write down everything I work on (not just completed code), it is GREAT at helping me beat back the beast of Imposter Syndrome. At a glance, I can see everything I’ve done in the past 4–5 days. And simply SEEING my efforts, research, and completion, means I no longer have to rely on my MEMORY to REMEMBER what I’ve accomplished.&lt;/p&gt;
&lt;p&gt;I can SEE what I’ve accomplished. And I go to bed at night much more satisfied that I’m making the difference that I originally sought by becoming a software engineer.&lt;/p&gt;
&lt;p&gt;And don’t forget — books are a means to learn some knowledge. But they don’t contain &lt;em&gt;everything&lt;/em&gt; you need to grow as a developer.&lt;/p&gt;
&lt;p&gt;Stay tuned for my next article. However, if you simply can’t wait, then check out this video below, where I ran into a problem I COULDN’T SOLVE despite being a pro coder!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="351" medium="image" url="https://www.procoder.io//_astro/1_hLybQxUQo5dlajRXnigXvA.z4HqEWRX.jpeg"/></item><item><title>Spring Boot is your ticket…to ticket resolution!</title><link>https://www.procoder.io/articles/2022/2022-06-30_spring-boot-is-your-ticket-to-ticket-resolution--fb744ef1be49</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-06-30_spring-boot-is-your-ticket-to-ticket-resolution--fb744ef1be49</guid><description>Systems break. Bugs pop up. Things fall apart. As a scan tickets on Spring Data JPA, I run into this all the time. And what do I do?</description><pubDate>Thu, 30 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ever had something go wrong?&lt;/p&gt;
&lt;p&gt;Systems break. Bugs pop up. Things fall apart. As a scan tickets on Spring Data JPA, I run into this all the time. And what do I do?&lt;/p&gt;
&lt;p&gt;Half the time, I try to create a “reproducer”. We all like a situation that reproduces someone’s problem, moving us one step closer to fixing the problem. Yeah, yeah, I know that I sometimes call myself a “test-bitten script junky.” That’s because I’m a HUGE fan of automated testing and capturing things into test case.&lt;/p&gt;
&lt;p&gt;Heck, I’ve been known to &lt;a href=&quot;/articles/medium/2022-06-01_writing-tests-is-never-a-mistake--78d7054f56ba&quot;&gt;add more tests to the system EVEN IF NOTHING GOT BROKEN&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So what happens when someone tells me their query isn’t working? Their JPA entity configuration isn’t working? Their CONFIGURATION of Spring Data inside their Spring Boot app isn’t working?&lt;/p&gt;
&lt;p&gt;I reach for the Spring Initializr at &lt;a href=&quot;https://start.spring.io,&quot;&gt;https://start.spring.io,&lt;/a&gt; craft a barebones application, and start trying to replicate their setup. People are usually happy to share entity class definitions. Sometimes they’ll give me their SQL or JPQL statements.&lt;/p&gt;
&lt;p&gt;With the power of H2 embedded databases, a fleet of test modules included with every project, and the fact that I can have a humming application setup and ready to go in five minutes (or less), Spring Boot + Spring Initializr is the ULTIMATE PRODUCTIVITY toolkit!&lt;/p&gt;
&lt;p&gt;One of our past teammates, Matt Stine, once eyeballed this in Spring Boot’s early days. He had remarked “everything a Boot app!” When Spring Boot debuted back in 2014, everyone was blown away. But in that moment, they/we didn’t realize the power of being to throw together an app in no time.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*cDtapa2d51W3SPnz9oBIag.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Everything a Boot app!Nobody back in 2014 realized the power you hold in your hands by simply grabbing some basic dependencies and merrily start reproducing someone else’s application. Coupled with github and the ability to throw your application onto a source-sharing site, and you’ve got yourself collaboration we’ve never seen before.&lt;/p&gt;
&lt;p&gt;Today alone, I’ve created two different application, attempting to replicate two different problems. And it worked! I tracked down someone’s problem to a single annotation that had been misconfigured. This was after I had created my own reproducer, and THEY had created a reproducer.&lt;/p&gt;
&lt;p&gt;With two different Spring Boot apps, both tiny, I knew we could converge on the issue, quickly. And this fact drew me in. I was excited. Finding the crux of this was FUN! I submitted a PR to their reproducer and linked back to it in the original issue.&lt;/p&gt;
&lt;p&gt;As you work through your own issues, I encourage you, at any time, to stop what you’re doing and simply RECREATE IT. That’s right. Stop working in your Big App, and see if you can create a Tiny App that hovers around this issue you’re having.&lt;/p&gt;
&lt;p&gt;Because if you run aground and CAN’T figure it out, your Tiny App will provide the means to SHARE you problem with others. This also gives you a chance to sanitize if need be. But ultimately, it forces you to RETHING your problem. Can you capture your problem easily?&lt;/p&gt;
&lt;p&gt;Because if you can do this, we are well on your way toward solving the problem and ultimately subsuming it into a test case of your Big App.&lt;/p&gt;
&lt;p&gt;Spring Boot is the ultimate “noodling” tool. You can noodle out solutions by simply recreating things. And this is one of those things that Spring Boot really sizzles at.&lt;/p&gt;
&lt;p&gt;If you dig Spring Boot, then please stay tuned for my next article. However, if you simply can’t wait, then check out this live stream where we dive into configuring Spring Boot applications and learn how things “fit together” in the land of Spring.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="800" medium="image" url="https://www.procoder.io//_astro/1_cDtapa2d51W3SPnz9oBIag.r-9h1QK1.png"/></item><item><title>How to Write a Software Book in 4 Steps</title><link>https://www.procoder.io/articles/2022/2022-06-23_how-to-write-a-software-book-in-4-steps-243cde3ffe60</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-06-23_how-to-write-a-software-book-in-4-steps-243cde3ffe60</guid><description>Step 1 — Come up with a great topic</description><pubDate>Thu, 23 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;step-1come-up-with-a-greattopic&quot;&gt;Step 1 — Come up with a great topic&lt;/h3&gt;
&lt;p&gt;It’s critical that you pick a topic people won’t be able to put down.&lt;/p&gt;
&lt;p&gt;If you were to attend a technical conference today, imagine what are people talking about. Because if they’re talking about, they’re probably willing to purchase a book about it!&lt;/p&gt;
&lt;p&gt;Back in 2014, Spring Boot made its first GA release. And the buzz was STRONG. In the midst of that year’s SpringOne conference, I received an email from my publisher asking about doing a Spring book. I looked around, and seeing all the chatter, hastily threw together a counter proposal, telling them we HAD to write a book about Spring Boot. They had never heard of Spring Boot, but leveraging my expertise and pointing out the excitement, my publisher agreed to a five chapter book deal.&lt;/p&gt;
&lt;p&gt;Suffice it to say, that book was a slam dunk. Being the first Spring Boot to market, it sold FAST. The advance they gave me was earned back in six months.&lt;/p&gt;
&lt;p&gt;I’d like to take credit as some phenomenal writer, but the truth is, Spring Boot as a topic is a gold mine and did much of the heavy lifting.&lt;/p&gt;
&lt;p&gt;What are you an expert in? What is something you could talk about all day without hesitation? And contrast this with, what is something in the vicinity of your expertise that you KNOW people want to LEARN MORE about?&lt;/p&gt;
&lt;p&gt;Redis? React? Spring? Project Reactor? MongoDB? Postgres? There are MANY opportunities.&lt;/p&gt;
&lt;p&gt;Try this — carve out one afternoon, perhaps four hours. Sit down and try to write (or type into a Google Doc) a list of your skills. Not necessarily stuff you have committed to memory. Just imagine the areas of code you have written LOTS of code using. Also list book topics you would read about. This may reveal a topic others would like and you could write!&lt;/p&gt;
&lt;p&gt;Alas, as important as this is, the next step is vital.&lt;/p&gt;
&lt;h3 id=&quot;step-2start-writing-the-code-forit&quot;&gt;Step 2 — Start writing the code for it&lt;/h3&gt;
&lt;p&gt;There is no other genre of books I can think of that has the concept of writing both prose AND code.&lt;/p&gt;
&lt;p&gt;For software-based books, we need the code. Your readers will WANT THE CODE. So plan on this — don’t be stingy. Considering GitHub organizations are now freely available, go carve one out and make a public-facing repository to hold all your book’s code.&lt;/p&gt;
&lt;p&gt;And start writing code.&lt;/p&gt;
&lt;p&gt;That’s right…plan on GIVING AWAY the code to your book.&lt;/p&gt;
&lt;p&gt;Because that’s how open source works these days. People may not have free access to your prose, but giving away the code will create interest in the paid-for book you’ll later write.&lt;/p&gt;
&lt;p&gt;As you knuckle down and start writing code, think about what struggles YOU had in using this toolkit or framework. Imagine what you WISH someone had shared with you early on. And shape your application.&lt;/p&gt;
&lt;p&gt;I have found that some of the bits I need to show are in the core application. And some of the bits can be captured inside a test case class somewhere else.&lt;/p&gt;
&lt;p&gt;And don’t forget — not ALL the code in the repository has to be in the book. You can have a fully developed operational application in your repository and plan on only putting the key bits in the manuscript. This leaves you room to tell the reader to GO TO YOUR REPOSITORY for more!&lt;/p&gt;
&lt;p&gt;You don’t have to have ALL your code in place to begin what I like to call The Grind™, but it’s the part that will elevate you, in the next section.&lt;/p&gt;
&lt;h3 id=&quot;step-3typeset-everything&quot;&gt;Step 3 — Typeset everything&lt;/h3&gt;
&lt;p&gt;I once worked at a sports magazine. Not as a writer. Not as an editor. Instead, as a “gopher”, because my job to “go for” anything the editor told me to. Stories came in all the time from the editor’s freelance authors. He would hand them to me and tell to “typeset” them. That’s because the story had already been written. This was more like transcription. Simple moving the letters and words from one medium to another.&lt;/p&gt;
&lt;p&gt;When it comes to software books, once you have the code written to hang the whole book upon, a lot of the heavy lifting has been done. I often will spend hours if not days hammering out the code.&lt;/p&gt;
&lt;p&gt;Then I can simply paste in various fragments of it inside either a Word document or an Asciidoctor file.&lt;/p&gt;
&lt;p&gt;Then I explain it. And expound upon it.&lt;/p&gt;
&lt;p&gt;And while doing so, I often spot tradeoffs I made in writing the code. (This is critical! Your readers will want to know, for example, whether to inject the real service or use a mock if you’re talking about testing!)&lt;/p&gt;
&lt;p&gt;And often what I find, is that I can extract a story in the process.&lt;/p&gt;
&lt;p&gt;Right now I’m writing &lt;em&gt;&lt;strong&gt;Chapter 5, Testing with Spring Boot&lt;/strong&gt;&lt;/em&gt; of my &lt;a href=&quot;/books/learning-spring-boot-3-0&quot;&gt;&lt;em&gt;Learning Spring Boot 3.0 book&lt;/em&gt;&lt;/a&gt;. And in covering all the various forms of testing, whether its domain objects, mocked out services, repositories built on top of embedded databases, repositories leveraging Testcontainers, or security-based testing, it all turns into a story.&lt;/p&gt;
&lt;p&gt;SHOULD someone test their domain objects? WHAT ABOUT getters and setters? WHY would someone choose an embedded database over a mock one? SHOULD I choose a Docker-based Testcontainers approach over embedded.&lt;/p&gt;
&lt;p&gt;I KNOW you can write code. But…can you EXPLAIN your code to someone else? This is what elevates you. This is what is grinding is all about. It’s not necessarily hard. It can just be tedious. Sometimes it takes me longer to spell out one method of functionality than it takes me to read and grok that code.&lt;/p&gt;
&lt;p&gt;And like I said, embrace giving your reader the reasons you are doing this and that. Draw upon your skills and experience. This is why someone paid for your book. And…speak to your reader like you’re having a one-on-one conversation. Like you’re pair programming and you’re walking them through the code.&lt;/p&gt;
&lt;p&gt;Anyone can see your publicly visible code. But only those that have chosen to give you money are waiting patiently for your depth and analysis ABOUT that code!&lt;/p&gt;
&lt;p&gt;Now that you’ve written code and the explanation behind it, it’s time for some tips’n’tricks to market your tome.&lt;/p&gt;
&lt;h3 id=&quot;step-4market-yourbook&quot;&gt;Step 4 — Market your book&lt;/h3&gt;
&lt;p&gt;This step is key. You need to let people know about your book. However, there are some finer points that many people don’t realize that could catapult your book ahead of others.&lt;/p&gt;
&lt;p&gt;First of all, DO NOT WAIT until your book is complete to begin this process.&lt;/p&gt;
&lt;p&gt;You need to alert your friends and fans that you are writing a book &lt;em&gt;the moment you start&lt;/em&gt;. This is a way to build anticipation so that when it’s released, they will be EXCITED to buy it!&lt;/p&gt;
&lt;p&gt;But don’t just TELL people. And don’t BEG people to sign up either for a pre-release copy.&lt;/p&gt;
&lt;p&gt;Instead, use something deeper and more meaningful. &lt;strong&gt;Build content around your book&lt;/strong&gt;. Some of the most effective ways involves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Live stream some coding sessions&lt;/li&gt;
&lt;li&gt;Write blog posts, Medium articles, and LinkedIn posts&lt;/li&gt;
&lt;li&gt;Start building an email list and send out campaigns to your fans&lt;/li&gt;
&lt;li&gt;Etc., etc., and so on!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don’t BEG people to sign up for your book. Instead, create value and then include a link somewhere in the middle or even toward the end.&lt;/p&gt;
&lt;p&gt;You see, people will buy your book if it solves a problem they are having. That’s why a post titled “Please buy my book” will draw anyone, but a live stream on YouTube called “How to test with Spring Boot” can result in literally hundreds of people watching and sharing your content.&lt;/p&gt;
&lt;p&gt;Let me introduce one additional concept that BLEW MY MIND when I discovered it: &lt;em&gt;&lt;strong&gt;You can talk about the exact same thing…more than once&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*qLJOz3Dh-hFm_TKar8WlAw.gif&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;You can make the SAME THING more than once!Imagine that you created a video where you talk about using Testcontainers to verify a service.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use that video’s script or bullet points and then &lt;strong&gt;write an article&lt;/strong&gt; on Medium.&lt;/li&gt;
&lt;li&gt;Next, &lt;strong&gt;write a post&lt;/strong&gt; for your paying members.&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;newsletter campaign&lt;/strong&gt; for the people that have signed up.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With this strategy, you write one chunk of code, but &lt;em&gt;reuse it on multiple platforms&lt;/em&gt;. Meet your community where they are, whether that’s LinkedIn, YouTube, Twitter, Medium, your membership provider (I used to use Buy Me a Coffee), etc.&lt;/p&gt;
&lt;p&gt;And when you embark upon the next chapter of your book, you can repeat the whole process using THAT chapter’s code.&lt;/p&gt;
&lt;p&gt;And that’s okay.&lt;/p&gt;
&lt;p&gt;You are NOT losing customers of your book when you use this strategy. As strange as it sounds, you will actually GROW YOUR BASE of interested readers.&lt;/p&gt;
&lt;p&gt;You see, each platform works differently. For example, someone wanting to learn the ins and outs about Spring Boot can learn a LOT of that by watching all my videos on my YouTube channel. But that requires hours of effort. And they’d have to sift through which videos to pick depending on their needs.&lt;/p&gt;
&lt;p&gt;A book offers that same person a more structured and condensed way to consume the same information. At the same time, someone that’s reading my book may want to see more details on a specific topic. That’s why my book has links to various videos on my channel where they can get an enhanced experience.&lt;/p&gt;
&lt;p&gt;The ability to tie text with video and create a more synergistic experience is paramount.&lt;/p&gt;
&lt;p&gt;It’s flat out foolish to ignore this opportunity.&lt;/p&gt;
&lt;p&gt;And so I encourage you to take that leap. If you want to write a book, START TODAY! If you’re thinking about this, leave response and let me know.&lt;/p&gt;
&lt;p&gt;Stay tuned for my next article. However, if you simply can’t wait, then check out my most recent live stream down below where I literally USED CODE FROM MY CURRENT BOOK to teach others about testing Spring MVC web controllers!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;/list&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="640" height="420" medium="image" url="https://www.procoder.io//_astro/1_qLJOz3Dh-hFm_TKar8WlAw.D06nR-0N.gif"/></item><item><title>Unit tests saved my hide and helped me track down the REAL problem!</title><link>https://www.procoder.io/articles/2022/2022-06-15_unit-tests-saved-my-hide-and-helped-me-track-down-the-real-problem--bccd78f2021d</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-06-15_unit-tests-saved-my-hide-and-helped-me-track-down-the-real-problem--bccd78f2021d</guid><description>I recently picked up a curious ticket. Someone was using an obscure combination of features inside Spring Data JPA. In particular, DTO…</description><pubDate>Wed, 15 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;unit-tests-saved-my-hide-and-helped-me-track-down-the-real-problem&quot;&gt;Unit tests saved my hide and helped me track down the REAL problem!&lt;/h1&gt;
&lt;p&gt;I recently picked up a curious ticket. Someone was using an obscure combination of features inside Spring Data JPA. In particular, DTO…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;unit-tests-saved-my-hide-and-helped-me-track-down-the-realproblem&quot;&gt;Unit tests saved my hide and helped me track down the REAL problem!&lt;/h3&gt;
&lt;p&gt;I recently picked up a curious ticket. Someone was using an obscure combination of features inside Spring Data JPA. In particular, DTO objects and paging.&lt;/p&gt;
&lt;p&gt;Say what?&lt;/p&gt;
&lt;p&gt;Did you know you can write JPQL statements like this?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;SELECT new com.example.CustomDto(u.firstname, u.lastname) from User u&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What you’re doing is essentially pre-converting the results into this DTO type instead of the usual entity type. There are some key requirements like having to spell out the FQDN (fully qualified domain name), but other than, it makes for a tidy arrangement.&lt;/p&gt;
&lt;p&gt;In Spring Data JPA, this can manifest as either a named query in the entity’s definition, or you can apply it through the @Query annotation on your repository!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(SELECT new com.example.CustomDto(u.firstname, u.lastname) from User u&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&amp;#x3C;CustomDto&gt; findByNamedQueryWithConstructorExpression();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maybe that is a little clunky? If you’ve just recently picked up JPA and are using to writing bare SQL, this can look super cray. Nevertheless, it’s actually a feature I learned about recently that I think is handy if you’re wanting to keep the entity-to-DTO translation close to each other.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;BTW, IntelliJ IDEA totally can parse these strings! It even offers code completion. If you ever have doubts, put them aside. IntelliJ IDEA is always a step or two ahead of us, ready to do what’s key to maintaining code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what’s the problem in all this?&lt;/p&gt;
&lt;p&gt;When you take this seemingly harmless statement above and alter it’s signature to return a &lt;strong&gt;Page&lt;/strong&gt; of &lt;strong&gt;CustomDto&lt;/strong&gt; objects, you may or may not have everything fall apart.&lt;/p&gt;
&lt;p&gt;No, this isn’t Schrödinger’s Bug (though it may feel like it!)&lt;/p&gt;
&lt;p&gt;If you instead have THIS in your repository definition:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(SELECT new com.example.CustomDto(u.firstname, u.lastname) from User u&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Page&amp;#x3C;CustomDto&gt; findByNamedQueryWithConstructorExpression(Pageable pageable);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…then you are picking up Spring Data JPA’s ability to fetch a subset of results automatically. However, to do this, Spring Data JPA must first transform the query into a count-based query so it can, you know, count the results!&lt;/p&gt;
&lt;p&gt;And that’s where a really quirky bug lives. Due to pattern matching rules written long ago, everything works great if this query has a DISTINCT. But if NOT, well, it blows up if there’s no comma anywhere inside that “new com.example.CustomDTO” expression.&lt;/p&gt;
&lt;p&gt;BOTTOM LINE: Spring Data JPA can’t handle one of these DTO-oriented operations to fashion a Page &lt;strong&gt;if the DTO only has one argument&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Whew! That was, what’s the clinical term? Overcomplicated for describing a problem.&lt;/p&gt;
&lt;p&gt;Suffice it to say, I spent all day JUST TRYING TO WRITE A TEST CASE. At first, I thought I had figured out the problem no longer existed. I was ready to commit my smug little tests, since there’s &lt;a href=&quot;/articles/medium/2022-06-01_writing-tests-is-never-a-mistake--78d7054f56ba&quot;&gt;nothing wrong with submitting a new test case even if no code has changed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*lBbkAlt-jJWnNGfvrfET6A.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;I thought the issue no longer existed!But something in the back of my mind wouldn’t accept that. No, I sensed that I should poke and prod some more. And that proved correct. My original test case did NOT properly apply the Paging situation.&lt;/p&gt;
&lt;p&gt;Once I wiggled things into place, I sure enough had a failing test case right in front of my very eyes.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*pN0gsTnXYKD3rKcVL_W5eQ.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;But…I was wrong.With a nicely failing test case right in front of me, I could FINALLY engage with IntelliJ’s debugger. And boy howdy did I do that.&lt;/p&gt;
&lt;p&gt;Something you may not know, is that Spring Data JPA does a lot of parsing upfront when you have repository definitions. What that means is that if you put a plain old breakpoint smack dab in the middle of its parsing algorithm, the debugger will stop FOR EVERY SINGLE REPOSITORY METHOD.&lt;/p&gt;
&lt;p&gt;So I had to utilize conditional breakpoints. You just right-click on an existing break point and add a little pseudo-Java code to ONLY stop if the query string has my little &lt;strong&gt;CustomDto&lt;/strong&gt; object in it.&lt;/p&gt;
&lt;p&gt;I say pseudo-Java, because you not only have access to all in-scope methods, but IntelliJ seems to have some bean property shortcuts also at your beck and call.&lt;/p&gt;
&lt;p&gt;Anywho, with conditional breakpoints in place, I started running the test cases relentless, until I narrowed everything down to a tiny sliver of code that used regular expressions to rip apart that query string and then wrap it with a nice &lt;strong&gt;count()&lt;/strong&gt; operation.&lt;/p&gt;
&lt;p&gt;And so I started down the regular expression logic and TRIED to figure out what it was doing. A day-and-a-half in, and I was looking at something I kinda sorta had a glimmer of an idea how it worked.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*OckUet1N5PyK6YkQhGhHhg.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Me, trying to grok a regular expressionSuffice it to say, I tried this, that, and the other thing. And none of them worked. This little beasty of code kept tripping me up!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;boolean useVariable = StringUtils.*hasText*(variable) *//* &amp;#x26;&amp;#x26; !variable.startsWith(&quot; new&quot;) *//* &amp;#x26;&amp;#x26; !variable.startsWith(&quot;count(&quot;) *//* &amp;#x26;&amp;#x26; !variable.contains(&quot;,&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This little fragment of code would end up as &lt;strong&gt;false&lt;/strong&gt; for a 2-argument DTO (which worked) but &lt;strong&gt;true&lt;/strong&gt; for a 1-argument DTO. It needed to be &lt;strong&gt;false&lt;/strong&gt; for both!&lt;/p&gt;
&lt;p&gt;So I subtly &lt;em&gt;overrode it with&lt;/em&gt; &lt;em&gt;&lt;strong&gt;false&lt;/strong&gt;&lt;/em&gt; and then ran the entire test suite!&lt;/p&gt;
&lt;p&gt;And what do you know! Almost everything PASSED.&lt;/p&gt;
&lt;p&gt;Except for like TWO test cases. And they both had something to do with &lt;strong&gt;select distinct&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now I had started at the tiny space right before new up in that code fragment more than once. Have you? Something weird about it? I had even tried removing the space. After all, isn’t that THE SAME THING?&lt;/p&gt;
&lt;p&gt;Well, on a fluke, I decided to ADD another clause:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x26;&amp;#x26; !variable.startsWith(&quot;new&quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Same as the other one, but no spaces. I ran the battery of test cases. And they ALL worked.&lt;/p&gt;
&lt;p&gt;And then I looked, dumbfounded and my jaw wide open, I saw it. I realized it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;startsWith(“ new”)&lt;/strong&gt; and &lt;strong&gt;startsWith(“new”)&lt;/strong&gt; are absolutely, positively NOT THE SAME THING. I was imagining &lt;strong&gt;contains()&lt;/strong&gt;. But &lt;strong&gt;startsWith()&lt;/strong&gt; is VERY CLEARLY different.&lt;/p&gt;
&lt;p&gt;With a “whoop de doo”, I proceeded to polish it all up, and ensure that the information just gleaned from an entire day’s effort would NOT be lost, turning out this little fragment of code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;boolean useVariable = StringUtils.*hasText*(variable) *//* &amp;#x26;&amp;#x26; !variable.startsWith(&quot;new&quot;) *// select [new com.example.User...* &amp;#x26;&amp;#x26; !variable.startsWith(&quot; new&quot;) *// select distinct[ new com.example.User...* &amp;#x26;&amp;#x26; !variable.startsWith(&quot;count(&quot;) *// select [count(...* &amp;#x26;&amp;#x26; !variable.contains(&quot;,&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The added comments were to help jog my own memory, in case we ran into this in the future.&lt;/p&gt;
&lt;p&gt;I also was able to polish up test cases, ensuring we were testing every angle.&lt;/p&gt;
&lt;p&gt;And once again, regular expressions turned out to &lt;a href=&quot;/articles/medium/2022-06-08_how-i-stopped-worrying-and-learned-to-love-regular-expressions-40fd12400bf0&quot;&gt;not be as tragic as they could have&lt;/a&gt;! After making sure everything was up to Spring standards, I proceeded to backport the fix to all supported versions.&lt;/p&gt;
&lt;p&gt;That last backport took a little extra finessing, but it was worth it. And nothing puts a smile more than seeing an emoji reaction on my final summary comment:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*YDmivymH4vZyCR_hBM-7kA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Emojis in GitHub are always welcome! Makes the whole effort worth it.If you are monitoring a ticket and have the chance to “thumbs up” or cheer someone’s effort, please do. It’s one of those tiny opportunities we all have to spread a little cheer.&lt;/p&gt;
&lt;p&gt;Stay tuned for my next article. However, if you simply can’t wait, then check out the video below where I find the most powerful coder in all of gamingland to help me write a web app!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="468" medium="image" url="https://www.procoder.io//_astro/1_lBbkAlt-jJWnNGfvrfET6A.DATuZDn7.png"/></item><item><title>How I stopped worrying and learned to love regular expressions</title><link>https://www.procoder.io/articles/2022/2022-06-08_how-i-stopped-worrying-and-learned-to-love-regular-expressions-40fd12400bf0</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-06-08_how-i-stopped-worrying-and-learned-to-love-regular-expressions-40fd12400bf0</guid><description>As mentioned in my previous article, people select relational over NoSQL databases for new projects. Big time. We’re talking 80% of the…</description><pubDate>Wed, 08 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;how-i-stopped-worrying-and-learned-to-love-regular-expressions&quot;&gt;How I stopped worrying and learned to love regular expressions&lt;/h1&gt;
&lt;p&gt;As mentioned in my previous article, people select relational over NoSQL databases for new projects. Big time. We’re talking 80% of the…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-i-stopped-worrying-and-learned-to-love-regular-expressions-1&quot;&gt;How I stopped worrying and learned to love regular expressions&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;/articles/medium/2022-06-01_writing-tests-is-never-a-mistake--78d7054f56ba&quot;&gt;As mentioned in my previous article&lt;/a&gt;, people select relational over NoSQL databases for new projects. Big time. We’re talking 80% of the time. That’s 4-to-1 for you odds makers. And because no app is truly complete without data, it makes Spring Data JPA rank VERY high in most-selected modules when people pull together a new app over at &lt;a href=&quot;https://start.spring.io&quot;&gt;https://start.spring.io&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*zrjjtCTZQSbnZXiMSrHJng.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Seriously, when someone wants to whip up and app and they use that wickedly cool website, they most often reach for Spring Boot (cuz its baked in), Spring Security (your app isn’t real until its secured) and Spring Data JPA.&lt;/p&gt;
&lt;p&gt;And what happens when you’re popular? People open tickets against the project. We’re talking on a daily basis. And someone was needing to use PostgreSQL’s JSONB functions.&lt;/p&gt;
&lt;p&gt;This ain’t your grandpa’s relational database.&lt;/p&gt;
&lt;p&gt;No, today all the cool kids are using hot features like JSON-manipulating functions rolled straight into their SQL code. In this case, PostgreSQL has support parsing and gleaning JSON. And this includes some slick operators. Look at this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&apos;{&quot;a&quot;:1, &quot;b&quot;:2}&apos;::jsonb ? &apos;b&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That little puppy will query a JSON structure to test whether or not HAS “b” as a key in the structure. Nice, ehh? Probably better than pulling out some string-based data, running it through a JSON parser, and THEN querying for something.&lt;/p&gt;
&lt;p&gt;Why NOT put that RIGHT INTO THE DATABASE?&lt;/p&gt;
&lt;p&gt;Did I mentioned Spring Data JPA earlier in this article? Spring Data JPA doesn’t do JPA directly. No, we offload actual JPA operations to a JPA provider, whether thats Hibernate or EclipseLink. But we provide some handy integrations.&lt;/p&gt;
&lt;p&gt;For example, if you declare an interface method, we can glean the nature of the entity type, parse the method name, and essentially talk to the JPA entity manager on your behalf to assemble a query. If you’ve worked with the EntityManager SPI directly, then you’ll understand why this is really slick for something like 80% of standard queries.&lt;/p&gt;
&lt;p&gt;We also provide some other ways to take domain-level knowledge of your application and transform it into JPA styled queries.&lt;/p&gt;
&lt;p&gt;But if there’s one thing Spring does, it’s provide you with an escape hatch. Maybe your query is flat out too complicated for our easements. In that situation, you can simply apply an @Query annotation to your query method and roll the JPQL yourself!&lt;/p&gt;
&lt;p&gt;Which has proven to be quite handy for your Spring Data community.&lt;/p&gt;
&lt;p&gt;Unless you happen to be using one of these new-fangled JSON operators! Something we try and guard against is people mixing what are called “JDBC style parameters” (?) with “JPA style parameters” (:foo or ?2). When you fashion a query, you really need to pick one or the other.&lt;/p&gt;
&lt;p&gt;The error message from the JPA provider may be cryptic, so we try to catch that early on. Well guess what this type of query would look like:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(&quot;SELECT * FROM table WHERE (json_col-&gt;&apos;jsonKey&apos;)::jsonb \\?\\? :param &quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&amp;#x3C;User&gt; customQueryWithQuestionMarksAndNamedParam(String param);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hibernate will allow a double question mark (??) through, turning it into a single question mark (?) on the other side. I’m not sure if JPA itself covers this, or if this is outside the spec.&lt;/p&gt;
&lt;p&gt;But either way, our existing pattern detectors viewed this as a JDBC-style parameter. And the named (:param) argument is deemed JPA-style. And thus, this query was viewed as a mixer, which meant we shut it down as BAD!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Mixing of ? parameters and other forms like ?1 is not supported!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I spent probably 2–3 hours today simply grokking the problem at hand. I fashioned a test case to sniff out that double-? and ignore it, but realized we needed much more comprehensive testing.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(&quot;SELECT * FROM table WHERE (json_col-&gt;&apos;jsonKey&apos;)::jsonb \\?\\? :param &quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&amp;#x3C;User&gt; customQueryWithQuestionMarksAndNamedParam(String param);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(&quot;SELECT * FROM table WHERE (json_col-&gt;&apos;jsonKey&apos;)::jsonb \\?\\? ? &quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&amp;#x3C;User&gt; customQueryWithQuestionMarksAndJdbcStyleParam(String param);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(&quot;SELECT * FROM table WHERE (json_col-&gt;&apos;jsonKey&apos;)::jsonb \\?\\? ?1 &quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&amp;#x3C;User&gt; customQueryWithQuestionMarksAndNumberedStyleParam(String param);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Query(&quot;SELECT * FROM table WHERE (json_col-&gt;&apos;jsonKey&apos;)::jsonb \\?\\? ?1 and other_col = ? &quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&amp;#x3C;User&gt; customQueryWithQuestionMarksAndJdbcStyleAndNumberedStyleParam(String param1, String param2);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Essentially, we need laser-focused resolution on what’s happening so only legit queries are allowed through. And sometime, when solving a problem, you need to watch out for the edge cases right next door to your current scenario. I didn’t want to solve this problem and have a nigh-identical ticket get opened the next day.&lt;/p&gt;
&lt;p&gt;And so I ended up, knee deep in Spring Data JPA code, writing a regex pattern detector for JDBC-style (?), numbered-style (?1), and named-style (:foo) parameters.&lt;/p&gt;
&lt;p&gt;If there is something that makes any coder squirm and shake, it’s maintaining regex patterns. Well, I’ve done them for years. PERL, Python, and even the scary Java variants. And I knew, KNEW, that what we needed in this scenario was something called a “zero width lookahead” pattern.&lt;/p&gt;
&lt;p&gt;Basically ask the question “does this string contain a space, following by a question mark, and NOT followed by a number”. Spoiler alert: it looks like this…&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Pattern JDBC_STYLE_PARAM = Pattern.compile(&quot; \\?(?!\\d)&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That pattern starts with a space. It then has the question mark. And to avoid this being an “optional” modifier, has a backslash in front of it. (And a 2nd backslash to escape the backslash. Welcome to Java pattern matching.)&lt;/p&gt;
&lt;p&gt;That last pattern is extra complex, so I’ll pull it down below first:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;(?!\d)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wrapped with parentheses, the first character is a ?, indicating it’s a lookahead or lookbehind pattern. The !-character signals this as a negative match, i.e. a NOT. And \d signals that we’re looking for a digit.&lt;/p&gt;
&lt;p&gt;So this little thing means to look head, and see if there is NOT a digit, without consuming any characters. (That’s what zero lookahead means).&lt;/p&gt;
&lt;p&gt;The alternative way to write “…and not followed by zzz” is so convoluted I’m not even putting it here. This little pattern lets you find a question mark NOT followed a digit.&lt;/p&gt;
&lt;p&gt;And I didn’t know this before today. Or better stated, someone ELSE submitted a patch to Spring Data JPA a few weeks ago using the same construct but on another pattern. And this was the first time I realized THAT was the solution I needed! And reached for it today.&lt;/p&gt;
&lt;p&gt;And it worked beautifully.&lt;/p&gt;
&lt;p&gt;I’ll let you read the following pattern and deduce what each of them does:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Pattern NUMBERED_STYLE_PARAM = Pattern.compile(&quot; \\?(?=\\d)&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Pattern NAMED_STYLE_PARAM = Pattern.compile(&quot; :\\w+&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;HINT: In look aheads, = is the match, and ! is the NOT match. To look behind, you use ?&amp;#x3C;.&lt;/p&gt;
&lt;p&gt;JPA parameters are basically numbered OR named. Using these handy little patterns made it possible for me to rewrite our handlers. After all, we only want to sniff out someone using JPA and JDBC in the same query. Anything else, and we turn it over to the JPA provider and then let them pass it on to the database engine.&lt;/p&gt;
&lt;p&gt;If the engine itself doesn’t handle JSONB queries, well that’s between you and your database engine.&lt;/p&gt;
&lt;p&gt;Stay tuned for my next article. However, if you simply can’t wait, then check out the video below and get a taste of querying for data with Spring Boot!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="800" medium="image" url="https://www.procoder.io//_astro/1_zrjjtCTZQSbnZXiMSrHJng.On3C6N9Z.jpeg"/></item><item><title>Writing tests is NEVER a mistake…</title><link>https://www.procoder.io/articles/2022/2022-06-01_writing-tests-is-never-a-mistake--78d7054f56ba</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-06-01_writing-tests-is-never-a-mistake--78d7054f56ba</guid><description>…even if the “main” code doesn’t need to change.</description><pubDate>Wed, 01 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;writing-tests-is-never-a-mistake&quot;&gt;Writing tests is NEVER a mistake…&lt;/h1&gt;
&lt;p&gt;…even if the “main” code doesn’t need to change.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;writing-tests-is-never-amistake&quot;&gt;Writing tests is NEVER a mistake…&lt;/h3&gt;
&lt;p&gt;…even if the “main” code doesn’t need to change.&lt;/p&gt;
&lt;p&gt;As the lead for Spring Data JPA, I have had to learn a LOT of details about how this toolkit works. Nothing shakes you up more than being handed the reins to a critical project and then opening up your first “new” issue the next day.&lt;/p&gt;
&lt;p&gt;And being The One that has to deal with it.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*kxWfhGGznzyGifyKtEhsVA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;People often open new tickets against Spring Data JPA. With people selecting SQL-based data stores over NoSQL-based data stores at an average of 4-to-1 on new projects, it makes this project popular. And when have troubles, they open tickets.&lt;/p&gt;
&lt;p&gt;So one of my first steps is to simply glean what went wrong. Sometimes it’s plain as day and I can point it out. But more often than not, they have a specific situation in their application where something went awry.&lt;/p&gt;
&lt;p&gt;And so the first thing I reach for, if not spotting it as an Already Solved issue, is to see how easy it is to write a test case.&lt;/p&gt;
&lt;p&gt;And this is where I smile.&lt;/p&gt;
&lt;p&gt;Because automated test cases are the key toward learning a new project. Every time we write a test case, it forces us to understand how the system works. How a single module works. How a single function works.&lt;/p&gt;
&lt;p&gt;And with each test case, our understanding grows.&lt;/p&gt;
&lt;p&gt;It takes patience. It takes endurance. If you want to become a pro developer, this is the kind of thing you will experience day in and day out. Not the glittery, uber-existing thing where you assemble a Twitter-lookalike in 45 minutes like I’ve seen at conference talks. That stuff is fun, but it’s not representative of the grind software geeks face.&lt;/p&gt;
&lt;p&gt;We must reproduce problems, diagnose if they REALLY exist, and if so, decide what the solution is. (Or..wink wink…what the solution is NOT. Sometimes, a solution isn’t warranted, but that’s for another article.)&lt;/p&gt;
&lt;p&gt;And over time, as we write more and more tests, we will learn more and more of the system. We will, over time, build up a knowledge of how all the parts work together.&lt;/p&gt;
&lt;p&gt;And this is why, sometimes even if there is no actual problem to fix in a given issue, &lt;strong&gt;I’ll sometimes add the newly minted test cases to the codebase&lt;/strong&gt;!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Extra test cases are NEVER a mistake to add to a codebase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And then comes that “ah-ha” moment. That day when you wake up, brew your coffee, look out the window as the sun rises, and have a brain blast. You realize that part of the system that keeps cropping up in bug reports was built sub-optimally. It doesn’t have the “right” structure and hence the source of multiple issues.&lt;/p&gt;
&lt;p&gt;And you’ll run up the stairs, to the end of the hallway, into your office, power up your machine, and start coding with speed and excitement. Because you can FINALLY see the project as a whole and HOW it needs to be pivoted in order to Do Something Right.&lt;/p&gt;
&lt;p&gt;And you’ll sit back, grinning with your coffee cup in hand, confident in your knowledge. It may have taken six months, nine months, maybe eighteen months. But your knowledge isn’t exactly something picked up from reading the reference manual.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*pFSkLnih9BlnR1HxvRSAuA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;No, you have deep, intimate knowledge and can effect change that will serve users AS WELL AS yourself. And that’s part of the deep satisfaction that will affirm this was what you were meant to be.&lt;/p&gt;
&lt;p&gt;If you enjoyed this article, then follow me to catch the next one. But if you simply can’t wait, then check out the video below, where do deep, talking about DTOs vs. entities and why that’s a thing!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="533" medium="image" url="https://www.procoder.io//_astro/1_kxWfhGGznzyGifyKtEhsVA.CIIK-FYU.png"/></item><item><title>Want to secure your Spring Boot 3 app with OUT managing all those users?</title><link>https://www.procoder.io/articles/2022/2022-05-25_want-to-secure-your-spring-boot-3-app-with-out-managing-all-those-users--47c5a25d23a8</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-05-25_want-to-secure-your-spring-boot-3-app-with-out-managing-all-those-users--47c5a25d23a8</guid><description>&gt; The best things in life are free.</description><pubDate>Wed, 25 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;want-to-secure-your-spring-boot-3-app-with-out-managing-all-those-users&quot;&gt;Want to secure your Spring Boot 3 app with OUT managing all those users?&lt;/h1&gt;
&lt;p&gt;There’s a saying:&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;want-to-secure-your-spring-boot-3-app-with-out-managing-all-thoseusers&quot;&gt;Want to secure your Spring Boot 3 app with OUT managing all those users?&lt;/h3&gt;
&lt;p&gt;There’s a saying:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The best things in life are free.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While I’m not convinced this is even remotely true, when it comes to offloading user management on a major tech company at no cost, Google is the way to go!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/articles/medium/2022-05-18_spring-boot-3---oauth-2---youtube--60fc47772d0b&quot;&gt;In my previous article&lt;/a&gt;, we explored how to register an OAuth 2 application with Google, grab creds, and hook them into Spring Boot.&lt;/p&gt;
&lt;p&gt;The cherry on top, which we’ll cover in THIS article, is how after you let Google authenticate your users FOR YOU, you can then scarf some of that free YouTube data, and sport it on your own web site!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*PHZJFkr34pAJ0x93bQ8nBA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;In that previous article, we managed to configure all the Spring Boot 3 + Spring Security OAuth 2 goodness along with a Spring Framework &lt;strong&gt;WebClient&lt;/strong&gt; wired up to use the OAuth 2 credentials to do all its leg work, making it possible to do remote calls.&lt;/p&gt;
&lt;p&gt;And part of the magic included designing an &lt;strong&gt;OpenFeign-like remote client&lt;/strong&gt; pure using a Java interface like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;interface YouTube {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @GetExchange(&quot;/search?part=snippet&amp;#x26;type=video&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  SearchListResponse channelVideos( *//* @RequestParam String channelId, *//* @RequestParam int maxResults, *//* @RequestParam Sort order);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  enum Sort {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    DATE(&quot;date&quot;), *//* VIEW\_COUNT(&quot;viewCount&quot;), *//* TITLE(&quot;title&quot;), *//* RATING(&quot;rating&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    private final String type;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Sort(String type) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      this.type = type;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In case you didn’t catch word, Spring Boot 3 is based on &lt;strong&gt;Java 17&lt;/strong&gt;. And one of the coolest features in Java 17 are records, a perfect tool for capturing all the &lt;a href=&quot;https://developers.google.com/youtube/v3/docs/search/list&quot;&gt;DTOs defined in YouTube’s API&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The YouTube service defined up above sports a &lt;strong&gt;SearchListResponse&lt;/strong&gt; return type. Based on a simple reading of YouTube’s API, this record definition should do the trick!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchListResponse(String kind, String etag, String nextPageToken, String prevPageToken, PageInfo pageInfo,  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  SearchResult[] items) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it! This tiny definition provides fields, setters &amp;#x26; getters (slightly different than traditional Java beans), and an all-arg constructor. It’s possible to add additional methods as needed, but as shown, Jackson, the JSON serialization engine autoconfigured by Spring Boot will perfectly convert the JSON response from YouTube into this type.&lt;/p&gt;
&lt;p&gt;Now most of these fields are simple Java types. However, we need to capture &lt;strong&gt;PageInfo&lt;/strong&gt; and &lt;strong&gt;SearchResult&lt;/strong&gt;. Time for more records!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record PageInfo(Integer totalResults, Integer resultsPerPage) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchResult(String kind, String etag, SearchId id, SearchSnippet snippet) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In these two records, there are a couple additional records needed:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchId(String kind, String videoId, String channelId, String playlistId) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchSnippet(String publishedAt, String channelId, String title, String description,  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Map&amp;#x3C;String, SearchThumbnail&gt; thumbnails, String channelTitle) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only additional type in these records not seen earlier is a SearchThumbnail:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchThumbnail(String url, Integer width, Integer height) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since these final records don’t require any more records, we are done!&lt;/p&gt;
&lt;p&gt;It’s Spring MVC controller time, baby.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Controller  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class HomeController {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  private final YouTube youTube;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  public HomeController(YouTube youTube) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    this.youTube = youTube;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @GetMapping  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  String index(Model model) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    model.addAttribute(&quot;channelVideos&quot;, *//* youTube.channelVideos(&quot;UCjukbYOd6pjrMpNMFAOKYyw&quot;, 10, YouTube.Sort.*VIEW\_COUNT*));  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return &quot;index&quot;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This slim little web controller will autowire that YouTube service defined earlier, granting us access to YouTube’s API. The parameters include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The ID for a given YouTube channel (no vanity URLs). (Feel free to plug in your own!)&lt;/li&gt;
&lt;li&gt;The number of videos to return for the first page of data.&lt;/li&gt;
&lt;li&gt;The sorting mechanism to use (sort by most views)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the tl;dr on the previous article, we already chose &lt;strong&gt;Mustache&lt;/strong&gt; as the templating language of choice. It’s slim and trim, making it easy to get a lot done without keeping a reference manual open on your tab-heavy browser (amirite?)&lt;/p&gt;
&lt;p&gt;Since the web controller is returning “index” from the index() method, you need to go down to src/main/resources/templates and create a file named index.mustache. Then start writing your own YouTube user experience:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;!doctype html&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;html lang=&quot;en&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;head&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;link href=&quot;style.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;/&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/head&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;body&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;h1&gt;Greetings Learning Spring Boot 3.0 fans!&amp;#x3C;/h1&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;p&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    In this section, we are learning how to make  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    a web app using Spring Boot 3.0 + OAuth 2.0  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/p&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;h2&gt;Your Videos&amp;#x3C;/h2&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;table&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;thead&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;tr&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;td&gt;Id&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;td&gt;Published&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;td&gt;Thumbnail&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;td&gt;Title&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;td&gt;Description&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/tr&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/thead&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;tbody&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    {{#channelVideos.items}}  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;tr&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;td&gt;{{id.videoId}}&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;td&gt;{{snippet.publishedAt}}&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;a href=&quot;https://www.youtube.com/watch?v={{id.videoId}}&quot; target=&quot;\_blank&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;img src=&quot;{{snippet.thumbnail.url}}&quot; alt=&quot;thumbnail&quot;/&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;#x3C;/a&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;td&gt;{{snippet.title}}&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;#x3C;td&gt;{{snippet.shortDescription}}&amp;#x3C;/td&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;#x3C;/tr&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    {{/channelVideos.items}}  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/tbody&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/table&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/body&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This page is mostly good ole’ HTML 5. But in a few places, you’ll notice some Mustache directives, denoted by the double curly bracket wrappers. &lt;strong&gt;{{#channelVideos.items}}&lt;/strong&gt; is a signal to take the &lt;strong&gt;channelVideos&lt;/strong&gt; model attribute (defined up in the web controller), and navigate to its &lt;strong&gt;items&lt;/strong&gt; property.&lt;/p&gt;
&lt;p&gt;And if you remember from the &lt;strong&gt;SearchListResponse&lt;/strong&gt; record type, &lt;strong&gt;items&lt;/strong&gt; is an array of &lt;strong&gt;SearchResult&lt;/strong&gt; objects. The pound sign (#) inside a Mustache directive is a signal to iterate. Every chunk of HTML inside that directive is repeated for every entry.&lt;/p&gt;
&lt;p&gt;Inside the directive, you’ll parts like &lt;strong&gt;{{id.videoId}}&lt;/strong&gt;. This tells Mustache to grab the &lt;strong&gt;SearchResult&lt;/strong&gt; object, look up its &lt;strong&gt;id&lt;/strong&gt; field, and because it’s a subrecord, go into &lt;strong&gt;SearchId&lt;/strong&gt; to find the &lt;strong&gt;videoId&lt;/strong&gt; field.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;TIP: With Mustache, it sometimes take longer to explain a directive with words than just glance and grok.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now there are a couple show stoppers in this template that may surprise you. The first one is the fact that YouTube actually has more than one thumbnail for each video. First time I rendered this template, I spotted FOUR thumbnails. Not exactly elegant.&lt;/p&gt;
&lt;p&gt;And here’s the rub: &lt;em&gt;Mustache is known as a logic-less templating engine.&lt;/em&gt; While engines like Thymeleaf have support for “if” checks, and Mustache has the ability to skip over null-valued fields, anything much slicker than this isn’t possible.&lt;/p&gt;
&lt;p&gt;It means we need to go back to the record backing structure and add more “virtual” fields. And, as you may discover, many YouTube videos have LONG descriptions. So we can ALSO add a “short description” that shortens the description field.&lt;/p&gt;
&lt;p&gt;So let’s revamp things like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;record SearchSnippet(String publishedAt, String channelId, String title, String description,  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Map&amp;#x3C;String, SearchThumbnail&gt; thumbnails, String channelTitle) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  String shortDescription() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if (this.description.length() &amp;#x3C;= 100) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      return this.description;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return this.description.substring(0, 100);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  SearchThumbnail thumbnail() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return this.thumbnails.entrySet().stream() *//* .filter(entry -&gt; entry.getKey().equals(&quot;default&quot;)) *//* .findFirst() *//* .map(Map.Entry::getValue) *//* .orElse(null);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This updated SearchSnippet now has shortDescription, which is a record’s description field is greater than 100 characters, will return back a substring.&lt;/p&gt;
&lt;p&gt;It also grabs the map of thumbnails and iterates over all the entries until it finds one named “default”.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;TIP: To be honest, I kind of prefer having this sort of logic in my Java code, not my template!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With all this in place, we can launch our application! Visit localhost:8080, and Spring Security OAuth 2 should bounce you over to Google’s famous login page:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*Utby9CMz8HMcwuePcq1vbw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Yes, I have more than one Google account. (Another GOOD reason to offload such user management to Google!)&lt;/p&gt;
&lt;p&gt;Once you pick your Google account, because you’re requesting YouTube data, Google will further ask you to pick a specific channel:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*hMD8OovRwAzzraX5rHD2sw.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Yes, I have more than one YouTube channel that I manage in my spare time. (Again, do you really want to manage any of this?)&lt;/p&gt;
&lt;p&gt;Anywho, pick your channel, and then…voila!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*hsU6tN2Y7Vq9IWSLKGenkA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;The template, rendered in all it’s glory! The thumbnails even have anchor links to open a new tab and watch the video.&lt;/p&gt;
&lt;p&gt;Feel to play around and see what else you can glean from their API. Perhaps other ways to leverage OAuth 2?&lt;/p&gt;
&lt;p&gt;And before you start rubbing your hands in excitement, you should know that not EVERY metric that is served up inside YouTube Studio is available through their API. So don’t be surprised if you can’t replicate every single facet. But still…the thought of building your own system to potentially test out different thumbnails for a new video AUTOMATICALLY is kind of gnarly.&lt;/p&gt;
&lt;p&gt;Stay tuned for my next article, where we’ll delve into writing test cases and why it’s NEVER a bad idea! However, if you simply can’t wait, then check out the video below and get a taste of testing with Spring Boot!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="629" medium="image" url="https://www.procoder.io//_astro/1_Utby9CMz8HMcwuePcq1vbw.NVnwnGNd.png"/></item><item><title>Spring Boot 3 + OAuth 2 = YouTube!</title><link>https://www.procoder.io/articles/2022/2022-05-18_spring-boot-3---oauth-2---youtube--60fc47772d0b</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-05-18_spring-boot-3---oauth-2---youtube--60fc47772d0b</guid><description>One of the coolest things people reach for in building web apps, is off loading authentication to one of the three biggies: Facebook…</description><pubDate>Wed, 18 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;spring-boot-3--oauth-2--youtube&quot;&gt;Spring Boot 3 + OAuth 2 = YouTube!&lt;/h1&gt;
&lt;p&gt;One of the coolest things people reach for in building web apps, is off loading authentication to one of the three biggies: Facebook…&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;spring-boot-3--oauth-2-youtube&quot;&gt;Spring Boot 3 + OAuth 2 = YouTube!&lt;/h3&gt;
&lt;p&gt;One of the coolest things people reach for in building web apps, is off loading authentication to one of the three biggies: Facebook, Twitter, or Google.&lt;/p&gt;
&lt;p&gt;Why maintain a list of users when there is someone else (with considerably bigger budgets) ready to do that for you?&lt;/p&gt;
&lt;p&gt;So as part of my latest book writing endeavor, I wanted to dig in and show you The Way. Spring Boot 3 + Spring Security’s amazing OAuth 2.0 support!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*PHZJFkr34pAJ0x93bQ8nBA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Before we can move forward, there’s a little something YOU have to do. And that’s create “an app” in Google. This is the part, where you tell Google about your app, and they give you credentials. It’s not hard. Just…tedious.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href=&quot;https://console.cloud.google.com/home/dashboard&quot;&gt;Google Cloud’s dashboard&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click on the drop down right next to &lt;strong&gt;Google Cloud Platform&lt;/strong&gt; and then hit &lt;strong&gt;New Project&lt;/strong&gt;. Accept the default values.&lt;/li&gt;
&lt;li&gt;Select your new project so it’s showing in the dropdown at the top.&lt;/li&gt;
&lt;li&gt;On the left-hand panel, scroll down and hover on &lt;strong&gt;APIs &amp;#x26; Services&lt;/strong&gt;. On the pop-up menu, click on &lt;strong&gt;Enabled APIs &amp;#x26; Services&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On the list below, look for YouTube Data API v3. Click on it, then hit &lt;strong&gt;Enable API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Back at your application’s dashboard, look on the left-hand panel and select &lt;strong&gt;Credentials&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;+CREATE CREDENTIALS&lt;/strong&gt;. Select &lt;strong&gt;OAuth Client&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For Application type, select &lt;strong&gt;Web Application&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In Name, give your web application a name.&lt;/li&gt;
&lt;li&gt;This part is &lt;em&gt;critical&lt;/em&gt;. In the &lt;strong&gt;Authorized redirect URIs&lt;/strong&gt;, enter &lt;a href=&quot;http://localhost:8080/login/oauth2/code/google&quot;&gt;http://localhost:8080/login/oauth2/code/google&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Once these client credentials are credited, capture the &lt;strong&gt;Client ID&lt;/strong&gt; and &lt;strong&gt;Client secret&lt;/strong&gt; in the top right corner.&lt;/li&gt;
&lt;li&gt;Go back to the left-hand column from earlier, and click on &lt;strong&gt;OAuth Consent Screen&lt;/strong&gt;. Underneath &lt;strong&gt;Test User&lt;/strong&gt; create an entry for each email address you want to login under.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This should get you off the ground. It’s a little tricky, but possible.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;TIP: You do NOT have to publish or release your application to get warmed up on OAuth! You can tinker with this application where you (and only you) can access it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Once you have your OAuth &lt;strong&gt;client ID&lt;/strong&gt; and &lt;strong&gt;client secret&lt;/strong&gt;, you are ready to proceed with the magic that is Spring Boot 3. To make this as fast as possible, just visit &lt;a href=&quot;https://start.spring.io&quot;&gt;https://start.spring.io&lt;/a&gt; and plugin the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spring Boot version&lt;/strong&gt;: &lt;strong&gt;3.0.0-SNAPSHOT&lt;/strong&gt; (there’s some other goodies we’ll use further down in the article that depends on snapshots!)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;: &lt;strong&gt;Mustache&lt;/strong&gt;, &lt;strong&gt;Spring Web&lt;/strong&gt;, &lt;strong&gt;Spring Reactive Web&lt;/strong&gt;, and &lt;strong&gt;OAuth 2 Client&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that’s it! Just hit GENERATE, unzip, and import your newly minted Spring Boot 3 app into your favorite IDE, and let’s get cranking.&lt;/p&gt;
&lt;p&gt;Perhaps the first question on your mind is “why Spring Web &lt;em&gt;and&lt;/em&gt; Spring Reactive Web?” Because we building a servlet-based app (Spring Web) but taking full advantage of WebClient (Spring Reactive Web), which we’ll get to in a Spring minute.&lt;/p&gt;
&lt;p&gt;Before we can hook into Google and the YouTube API, we first need to plugin that clientId and clientSecret we produced up above. And to do that, we need to open up our project’s &lt;strong&gt;application.properties&lt;/strong&gt; file (look in &lt;strong&gt;src/main/resources&lt;/strong&gt; if you haven’t found it!):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;spring.security.oauth2.client.registration.google.clientId=**ClientId**&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;spring.security.oauth2.client.registration.google.client-secret=*Secret*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;spring.security.oauth2.client.registration.google.scope=openid,profile,email,https://www.googleapis.com/auth/youtube&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These three properties are the key bits that signal this as your app. Since your clientId and clientSecret are different than mine (I hope), I’ve put some stubbed out values in the first two properties in this snapshot. Just plugin your own. The third lists the “scopes” or permissions you wish to use. For this article, this is enough to load up some informata about a YouTube channel!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;TIP: Spring Security comes with prebaked settings for Google, Github, Facebook, and Okta found inside&lt;/em&gt; CommonOAuth2Provider*. We’re using Google, given by the google portion of the property name.*&lt;/p&gt;
&lt;p&gt;Something that comes with Spring Boot’s autoconfiguration is fashioning lots of key beans needed to make your app come alive. But in certain scenarios, it needs a little more information. One of these required pieces of information is how your app plans to manage OAuth clients.&lt;/p&gt;
&lt;p&gt;You see in OAuth land, your app is the direct &lt;em&gt;client&lt;/em&gt; to the service (Google) while the user is someone your app is working &lt;em&gt;on behalf&lt;/em&gt;. Traditional client/server paradigms are trickier, and thus can lead to confusing terminology.&lt;/p&gt;
&lt;p&gt;You need to configure a OAuth2AuthorizedClientManager bean which is responsible for handling all interactions between your users and the OAuth service, like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Configuration  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class SecurityConfig {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @Bean  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  public OAuth2AuthorizedClientManager authorizedClientManager(  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ClientRegistrationRepository clientRegistrationRepository,  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    OAuth2AuthorizedClientRepository authorizedClientRepository) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    OAuth2AuthorizedClientProvider authorizedClientProvider = *//* OAuth2AuthorizedClientProviderBuilder.*builder*() *//* .authorizationCode() *//* .refreshToken() *//* .clientCredentials() *//* .password() *//* .build();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    DefaultOAuth2AuthorizedClientManager authorizedClientManager =new DefaultOAuth2AuthorizedClientManager( *//* clientRegistrationRepository, *//* authorizedClientRepository);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    authorizedClientManager *//* .setAuthorizedClientProvider(authorizedClientProvider);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return authorizedClientManager;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This bean needs to be inside an @Configuration class, so that Spring Boot will detect it and automatically register it with the application context. With that in place, we can finally wire up a little magic!&lt;/p&gt;
&lt;p&gt;To really sizzle, we are using Spring Framework’s support for OpenFeign (only available in 6.0.0-SNAPSHOT at the time of writing). This means we can define all the remote means of accessing the YouTube API using an interface, and nothing more! To do that, we need a WebClient, which is the reason we added Spring Reactive Web earlier in the article.&lt;/p&gt;
&lt;p&gt;And so, we need another @Configuration class…&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Configuration  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class YouTubeConfig {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  private static final String *YOUTUBE\_V3\_API* =   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                      &quot;https://www.googleapis.com/youtube/v3&quot;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @Bean  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  WebClient webClient(OAuth2AuthorizedClientManager      &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                             authorizedClientManager) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = *//* new ServletOAuth2AuthorizedClientExchangeFilterFunction( *//* authorizedClientManager);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    oauth2.setDefaultClientRegistrationId(&quot;google&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return WebClient.*builder*() *//* .baseUrl(*YOUTUBE\_V3\_API*) *//* .apply(oauth2.oauth2Configuration()) *//* .build();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @Bean  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  YouTube client(WebClient oauth2WebClient) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    HttpServiceProxyFactory factory =   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;         HttpServiceProxyFactory.*builder*(  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                   new WebClientAdapter(oauth2WebClient)) *//* .build();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return factory.createClient(YouTube.class);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;strong&gt;@Configuratio&lt;/strong&gt;n class has two key beans: &lt;strong&gt;WebClient&lt;/strong&gt; and &lt;strong&gt;YouTube&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;WebClient&lt;/strong&gt; bean definition builds a new &lt;strong&gt;WebClient&lt;/strong&gt; using the root URL of YouTube’s Data API as the &lt;strong&gt;baseUrl&lt;/strong&gt;. It then grabs the &lt;strong&gt;OAuth2AuthorizedClientManager&lt;/strong&gt; and builds an exchange filter function out if, setting the registration id to “google”, aligning with the “google” key in our &lt;strong&gt;application.properties&lt;/strong&gt; file.&lt;/p&gt;
&lt;p&gt;Essentially, this &lt;strong&gt;WebClient&lt;/strong&gt; instance will have YouTube as its base URL and will pipe all requests through this OAuth2-handling function. Because of the &lt;strong&gt;clientId&lt;/strong&gt; and &lt;strong&gt;clientSecret&lt;/strong&gt; registered in our &lt;strong&gt;application.properties&lt;/strong&gt;, everything else will be handled effortlessly on our behalf.&lt;/p&gt;
&lt;p&gt;The second bean definition, YouTube, takes this &lt;strong&gt;WebClient&lt;/strong&gt; and wraps it inside a &lt;strong&gt;WebClientAdapter&lt;/strong&gt;, then hooking it into Spring Framework’s OpenFeign feature, &lt;strong&gt;HttpServiceProxyFactory&lt;/strong&gt;. This adapter makes it possible to plugin WebClient as the worker in this scenario, but there are plans to support things like RestTemplate and potentially other HTTP service utilities in the future.&lt;/p&gt;
&lt;p&gt;Maybe you’re wondering what YouTube is? It’s the interface we’re about to define!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;interface YouTube {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  @GetExchange(&quot;/search?part=snippet&amp;#x26;type=video&quot;)  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  SearchListResponse channelVideos( *//* @RequestParam String channelId, *//* @RequestParam int maxResults, *//* @RequestParam Sort order);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  enum Sort {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    *DATE*(&quot;date&quot;), *//  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; VIEW\_COUNT*(&quot;viewCount&quot;), *//  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; TITLE*(&quot;title&quot;), *//  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; RATING*(&quot;rating&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    private final String type;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Sort(String type) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      this.type = type;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This lightweight interface is all it takes to start talking to YouTube’s Data API. This one has a single method, &lt;strong&gt;channelVideos&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;@GetExchange&lt;/strong&gt; annotation is analogous to Spring MVC’s @GetMapping annotation. It signals that we wish to do an HTTP GET call with the &lt;strong&gt;/search&lt;/strong&gt; content appended to WebClient’s &lt;strong&gt;baseUrl&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Tip: Feel free to visit&lt;/em&gt; &lt;a href=&quot;https://developers.google.com/youtube/v3/docs/search/list&quot;&gt;&lt;em&gt;YouTube’s reference docs&lt;/em&gt;&lt;/a&gt; &lt;em&gt;to read more about the search API.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In addition to specifying the path, you can also declare arguments for the request using &lt;strong&gt;@RequestParam&lt;/strong&gt;. In this case: channelId, maxResults, and order. It should be pointed out that the names in the signature are the same names in the API, ensuring we have alignment. While the first two are pure strings, the third is an enum, confining the options.&lt;/p&gt;
&lt;p&gt;This application will nicely let you start talking to YouTube and displaying valuable content on your web page…&lt;a href=&quot;/articles/medium/2022-05-25_want-to-secure-your-spring-boot-3-app-with-out-managing-all-those-users--47c5a25d23a8&quot;&gt;a topic best saved for the next article&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*hsU6tN2Y7Vq9IWSLKGenkA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;While waiting for my next article where we plugin YouTube content right into our webpage, be sure to click the link below and get ramped up on Spring Security!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="800" height="600" medium="image" url="https://www.procoder.io//_astro/1_PHZJFkr34pAJ0x93bQ8nBA.DnAOMzcl.png"/></item><item><title>Building Spring Boot 3 apps is easier than ever!</title><link>https://www.procoder.io/articles/2022/2022-05-05_building-spring-boot-3-apps-is-easier-than-ever--47d81f60101e</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-05-05_building-spring-boot-3-apps-is-easier-than-ever--47d81f60101e</guid><description>If you’re a coder, and you’re reading this, then the odds are ever in your favor that you’re building an app.</description><pubDate>Thu, 05 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;building-spring-boot-3-apps-is-easier-than-ever&quot;&gt;Building Spring Boot 3 apps is easier than ever!&lt;/h1&gt;
&lt;p&gt;If you’re a coder, and you’re reading this, then the odds are ever in your favor that you’re building an app.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;building-spring-boot-3-apps-is-easier-thanever&quot;&gt;Building Spring Boot 3 apps is easier than ever!&lt;/h3&gt;
&lt;p&gt;If you’re a coder, and you’re reading this, then the odds are ever in your favor that you’re building an app.&lt;/p&gt;
&lt;p&gt;And let’s cut to the chase. This probably isn’t some dream app YOU came up with. In all likelihood, you’re building an app for boss/customer/contract. There are hobbyists and enthusiasts. But the vast bulk of building writing software are pro developers (or those studying at Uni/Bootcamp to become pro developers.&lt;/p&gt;
&lt;p&gt;And so, building apps is our mission. And let’s be honest. We LOVE writing code. We enjoy the taste of crafting cryptic prose inside an editor or IDE and seeing it come to life when our app runs.&lt;/p&gt;
&lt;p&gt;So it certainly is no fun if we have to climb over several hills, crawl through muck, and dig our way through the swamp of configuration and infrastructure to simply set up an environment to RUN our app!&lt;/p&gt;
&lt;p&gt;Back in the olden days, when I learned to write BASIC apps (I know I’m dating myself), I could write something as simple as this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;10 PRINT &quot;Hello, world!&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And POOF, I had an app! And every language can do this. Granted, Java can be a bit clumsy to do the same thing, but it’s possible.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class App {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    public static void main(String[] args) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        System.out.println(&quot;Hello, world!&quot;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But if you want to graduate to what clients and bosses want, you suddenly enter the realm of servlet containers and what not. And strange as it may seem, Java for the longest time, required that we provide some 3rd party service to do that!&lt;/p&gt;
&lt;p&gt;But ever since Spring Boot entered the scene back in 2014, that idea of going somewhere else on the Internet, downloading a servlet container like Apache Tomcat, installing it on every target machine, and then having to deploy your to it has been swiftly removed from our lexicon.&lt;/p&gt;
&lt;p&gt;Because Spring Boot comes loaded with support for &lt;em&gt;embedded&lt;/em&gt; Apache Tomcat. And by “support”, we mean, it includes it. That’s right. Spring Boot actually goes out and finds the binaries for Apache Tomcat, pulls it down, wraps it up inside your JAR file, and hands it to you, ready to unwrap like a sweet tasting chocolate egg from Easter.&lt;/p&gt;
&lt;p&gt;So Step 1 of any app developer, find a suitable environment to run your app, is taken care of.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Maybe this should really be Step 0. Simply finding something to run your app you’d THINK would be a part of your app, right?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The next step, actually building an app, is critical. And that’s when you start to move the bits that make a website come alive. Yes, I know not EVERYTHING is a web app. But for the 99.999% of apps that are, this piece is critical.&lt;/p&gt;
&lt;p&gt;Do make things sizzle, you want to get your hands on Spring MVC. Now back in the olden days, you know, when people trekked to Oregon via a Conestoga wagon (or maybe I’m mixing that up with playing The Oregon Trail video game?), you were better off getting a book to guide you on ALL the beans you had to configure. Spring MVC is powerful. But it require careful configuration.&lt;/p&gt;
&lt;p&gt;View resolvers, path handlers, all kinds of stuff. The set up was intricate.&lt;/p&gt;
&lt;p&gt;And in the immortal words of Buzz Lightyear, “Not today, Zurg!”&lt;/p&gt;
&lt;p&gt;Spring Boot 3 does ALL OF THIS for you through the magic of autoconfiguration. By simply adding &lt;code&gt;spring-boot-starter-web&lt;/code&gt; to your project file, Spring Boot will pull down embedded Apache Tomcat, Spring MVC, and Jackson (for JSON serialization/deserialization).&lt;/p&gt;
&lt;p&gt;It will then proceed to wire it all together with nary a peep. It just sits there, comfortably starting at you, ready for you to write a web controller.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;@Controller  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;public class HomeController {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    @GetMapping  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    public String index() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        return &quot;index&quot;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s about all it takes to get off the ground. This light weight class contains everything needed to start rendering some HTML for the end user. This web controller signals to Spring that this is a class made for handling web requests.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;@GetMapping&lt;/code&gt; annotation defaults to “/”, meaning it will map HTTP GET / calls onto this &lt;code&gt;index&lt;/code&gt; method. And the method itself will return the &lt;em&gt;name of a template&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;That’s right. You’re not QUITE done. You indeed need to craft a template. But we haven’t talked about templates. Because the thing is, Spring tries to pick reasonable defaults. And up until this point, it has. The assumptions include things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;embedded Apache Tomcat&lt;/li&gt;
&lt;li&gt;root servlet path of /&lt;/li&gt;
&lt;li&gt;local port of 8080&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But Spring leaves it up to YOU to decide what templating engine you desireth. There are many to pick from. For something lightweight and simple, use &lt;code&gt;spring-boot-starter-mustache&lt;/code&gt; . For something more sophisticated and powerful, I’d use &lt;code&gt;spring-boot-starter-thymeleaf&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;Add the dependency of your own choosing to your project file, and BAM! Spring Boot will autoconfigure that as well. No need to register Mustache view resolvers or other stuff and nonsense. Instead, you jump to crafting a template underneath &lt;code&gt;src/main/resources/template/index.mustache&lt;/code&gt; . (Your IDE &lt;em&gt;probably&lt;/em&gt; even supports Mustache!)&lt;/p&gt;
&lt;p&gt;Slide in a little HTML and all ready to go!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;h1&gt;Greetings Spring Boot Learning fans!&amp;#x3C;/h1&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;p&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Spring Boot 3 is your ticket to less setup and more  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;writing code that actually moves the needle for the projects  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;you&apos;re working on.  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is Step 3? That would involve building JSON APIs and more! But this article is already getting a little long. Click on FOLLOW and catch my next post!&lt;/p&gt;
&lt;p&gt;In the meantime, if you simply cannot wait, check out this video below where you can get a deeper glimpse into the power of web apps with Spring Boot 3!&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="1408" height="768" medium="image" url="https://www.procoder.io//_astro/default-hero-2.MKd_i9T4.jpg"/></item><item><title>What if I wanted to reproduce a build?</title><link>https://www.procoder.io/articles/2022/2022-03-05_what-if-i-wanted-to-reproduce-a-build--a977c980470a</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-03-05_what-if-i-wanted-to-reproduce-a-build--a977c980470a</guid><description>There is a movement afoot in the open source world. It’s called reproducible builds.</description><pubDate>Sat, 05 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;what-if-i-wanted-to-reproduce-a-build&quot;&gt;What if I wanted to reproduce a build?&lt;/h1&gt;
&lt;p&gt;There is a movement afoot in the open source world. It’s called reproducible builds.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-if-i-wanted-to-reproduce-abuild&quot;&gt;What if I wanted to reproduce a build?&lt;/h3&gt;
&lt;p&gt;There is a movement afoot in the open source world. It’s called reproducible builds.&lt;/p&gt;
&lt;p&gt;What exactly is that? And why would we need it?&lt;/p&gt;
&lt;p&gt;To answer the first question, it may be better to answer the second question. When it comes to delivering software, there can be a lot of steps. And I’m not just talking about compiling and packaging.&lt;/p&gt;
&lt;p&gt;I mean getting it to its destination. I’m old enough to remember building an app, burning it to a CD, and walking into a production room that had NO NETWORKED CONNECTION to the outside world. This CD was the only way to bring in a new release of software.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*5CjTyhco0mY3avX9.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;And that was by design.&lt;/p&gt;
&lt;p&gt;With these types of restrictions, it becomes easy to run checksum reports on the CD, on the binaries in the production environment, and any steps along the way. You can verify that what is running in production IS THE EXACT SAME THING as what you built.&lt;/p&gt;
&lt;p&gt;And that was stuff I did at my old and haven’t touched in years. Because that was government contracting and I departed that world when I joined the Spring team back in 2010.&lt;/p&gt;
&lt;p&gt;Open source systems need reproducibility as well. But I’ve not seen anyone clamoring for a checksum report since. I haven’t run into a customer that wants a complete snapshot of all the source, burned to a portable drive, with instruction on how to rebuild from scratch. Offline.&lt;/p&gt;
&lt;p&gt;Oh wait. I have.&lt;/p&gt;
&lt;p&gt;Before I joined the Spring Data team, I worked with a customer that had paid for the option of having every single tag of the system captured and stored away with the option to rebuild devoid of the outside world.&lt;/p&gt;
&lt;p&gt;When my manager handed me that task, I kind of blinked.&lt;/p&gt;
&lt;p&gt;“Everything?” I asked.&lt;/p&gt;
&lt;p&gt;My manager nodded yes.&lt;/p&gt;
&lt;p&gt;“Built offline?” My mind was struggling to accept this task.&lt;/p&gt;
&lt;p&gt;My manager continued to nod.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*cDuXXlVMKmU7mCJRDTa-1Q.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Ever cloned a repository and built every tag? Using maven, but in offline mode?&lt;/p&gt;
&lt;p&gt;Yeah, that last one took me a LOT of experimenting and tinkering. (You essentially build it ONLINE, but then switch on a couple flags, pointed at your local maven repository cache).&lt;/p&gt;
&lt;p&gt;Anywho, once I figured that out, loaded it all onto a portable drive, I shipped it off to IronMountain to be added to their vault and closed that task up.&lt;/p&gt;
&lt;p&gt;Maybe that sounds a little crazy to you. Well, that’s because it is. At least for 95% of the situations you’ll run into.&lt;/p&gt;
&lt;p&gt;But there’s valid suggestion that buried in that task is the need to go to any tag, check it out, build it using the same tools as always, and run it. Perhaps in a different way? On a different machine? With different parameters? Or perhaps to replace the server that just got fried by the tech who accidentally switched it from 120V to 240V power during a routine maintenance task?&lt;/p&gt;
&lt;p&gt;In these types of situations, people are willing to pay for reduced risk. And introducing software changes to systems that have been running stable for months or years often isn’t acceptable.&lt;/p&gt;
&lt;p&gt;We try to hedge risk with new-and-improved continuous integration and continuous deployment systems. But the world still needs the ability to reduce risk and run stable, secure builds.&lt;/p&gt;
&lt;p&gt;With the security issues popping into headlines, log4j being the latest, the world still needs to know that they can move from one stable release to another through processes that are controlled and not subject to individual whim.&lt;/p&gt;
&lt;p&gt;CI systems have made such release processes a lot more automated and a lot more scaleable. Sure am glad I know longer turn over tags to some CM person that literally had to walk around and get physical signatures from department heads before handing me a CD to carry into production.&lt;/p&gt;
&lt;p&gt;But that doesn’t mean we can’t do better with reproducible build environments, reproducible version of software, controlled keys, and proper checks.&lt;/p&gt;
&lt;p&gt;Sure you can debate whether a JAR file built six months later using the same version of Java, source code, and Maven is REALLY the same. After all, the timestamp on that JAR file along with dates injected into its metadata may vary. But if you crack it open and run a checksum report on every individual class file, you may be able to prove you have the exact same logic and data as the first version.&lt;/p&gt;
&lt;p&gt;And that breathes stability and confidence.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="730" height="480" medium="image" url="https://www.procoder.io//_astro/0_5CjTyhco0mY3avX9.CU1AbcNv.jpeg"/></item><item><title>What does it take to SUCCEED as a pro Spring Boot developer?</title><link>https://www.procoder.io/articles/2022/2022-02-12_what-does-it-take-to-succeed-as-a-pro-spring-boot-developer--962c2350f229</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-02-12_what-does-it-take-to-succeed-as-a-pro-spring-boot-developer--962c2350f229</guid><description>Do you dream of becoming a professional Spring Boot developer? Find out EXACTLY what tools you need to make it a reality!</description><pubDate>Sat, 12 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;what-does-it-take-to-succeed-as-a-pro-spring-boot-developer&quot;&gt;What does it take to SUCCEED as a pro Spring Boot developer?&lt;/h1&gt;
&lt;p&gt;Do you dream of becoming a professional Spring Boot developer? Find out EXACTLY what tools you need to make it a reality!&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-does-it-take-to-succeed-as-a-pro-spring-boot-developer-1&quot;&gt;What does it take to SUCCEED as a pro Spring Boot developer?&lt;/h3&gt;
&lt;p&gt;I posted a poll to my YouTube channel’s Community tab a couple months ago asking “What best describes you?”&lt;/p&gt;
&lt;p&gt;The options sought out whether the reader was studying coding, a fledgling developer, or a seasoned pro.&lt;/p&gt;
&lt;p&gt;Since over 2/3 of the audience responded to being relatively new to the field, I figured this was the perfect time for a series of videos sharing some of MY successful tips on what being a pro coder was like!&lt;/p&gt;
&lt;p&gt;The first thing I wanted to tackle was what kind of tools and practices you needed to take on to make it a reality…&lt;/p&gt;
&lt;p&gt;The next idea I had penciled out on my list of pro developer skillsets was how much time I spend simply communicating with fellow developers and colleagues.&lt;/p&gt;
&lt;p&gt;This doesn’t just mean email or Slack.&lt;/p&gt;
&lt;p&gt;In my 24-year career, I’ve had to learn how to communicate ideas, ask questions, and go hunting for information.&lt;/p&gt;
&lt;p&gt;While I was working on this video series, I had actually run into a coding issue that threw me for a loop.&lt;/p&gt;
&lt;p&gt;I had run into a tricky situation with Spring Data JPA, and while in the thick of it…realized THIS would be a GREAT addition to this video series!&lt;/p&gt;
&lt;p&gt;Debugging involves more than just clicking on the IDE’s “bug” icon. There are tactics that you NEED to LEARN to solve problems!&lt;/p&gt;
&lt;p&gt;If you know ANYTHING about the Spring portfolio, it’s that we all like to polish the code.&lt;/p&gt;
&lt;p&gt;I mean polish, polish POLISH!&lt;/p&gt;
&lt;p&gt;That is, we like to get things working, then clean it up so it is as clean and consistent as possible for future readers…even if that is for us!&lt;/p&gt;
&lt;p&gt;I couldn’t continue this series without carving out time showing exactly WHY this is so valuable and tips and tricks YOU can take to give your code extended longevity.&lt;/p&gt;
&lt;p&gt;(Getting Morgan Free to do a voice over was tricky…but worth it!)&lt;/p&gt;
&lt;p&gt;My series of lessons on what it takes to be a pro coder would all be for naught if I didn’t give some tips on how interview.&lt;/p&gt;
&lt;p&gt;I’ve been involved in MANY hiring decisions over my career, and it only makes sense to help YOU know the sorts of things people are looking for when they discuss a potential candidate!&lt;/p&gt;
&lt;p&gt;While I had new and fledgling developers in mind for these videos, everything in there is applicable to the most seasoned veteran. Today!&lt;/p&gt;
&lt;p&gt;And if it’s easier for you, you can watch them all from within a single playlist.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3D404s9QnVo&amp;#x26;list=PLLAi7xIKHkislZTAJouH1S3cv8SFKJQiC&quot;&gt;&lt;strong&gt;LET ME WATCH IT ALL AT ONCE&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With that series done, I’m already drafting my NEXT video series: &lt;strong&gt;Building My First Spring Boot App&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(BTW, I’m soon going to share the actual scripts and filming process with the PREMIUM members of my group.)&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="1280" height="896" medium="image" url="https://www.procoder.io//_astro/developer.CNbnPdy6.jpg"/></item><item><title>What is the good, the bad, and the ugly of CI?</title><link>https://www.procoder.io/articles/2022/2022-02-05_what-is-the-good--the-bad--and-the-ugly-of-ci--91d576ee1fd8</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-02-05_what-is-the-good--the-bad--and-the-ugly-of-ci--91d576ee1fd8</guid><description>CI has lots of nooks and crannies. What does it take to pull things together that best serves you?</description><pubDate>Sat, 05 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;what-is-the-good-the-bad-and-the-ugly-of-ci&quot;&gt;What is the good, the bad, and the ugly of CI?&lt;/h1&gt;
&lt;p&gt;CI has lots of nooks and crannies. What does it take to pull things together that best serves you?&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-is-the-good-the-bad-and-the-ugly-ofci&quot;&gt;What is the good, the bad, and the ugly of CI?&lt;/h3&gt;
&lt;p&gt;If there’s one thing I do, it’s jumping in feet first when I find something I like. A keen example is: &lt;strong&gt;Docker&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*QjTvUnXfK6vx5aQLQ6exgQ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;I don’t mean everything in Docker. Quite the contrary. I find the usage of Docker for development actually gets in my way. No, I’m talking about using Docker as a core piece of building any &lt;strong&gt;continuous integration&lt;/strong&gt; or &lt;strong&gt;CI&lt;/strong&gt; solution.&lt;/p&gt;
&lt;p&gt;I’m a big fan of building every single commit pushed to github. And by “building”, what I mean is, “test against a matrix of compatible profiles, publish the artifacts to a repository, and generate documentation”.&lt;/p&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The Spring portfolio has a strong reputation of backward compatibility. To ensure this on the projects I manage (Spring Web Services, Spring Session for MongoDB, and Spring HATEOAS), I need to test each version against multiple versions of the Spring Framework, Spring Security, and Spring Data.&lt;/p&gt;
&lt;p&gt;This was a chore nonetheless when we used the old CI system (&lt;strong&gt;Bamboo&lt;/strong&gt; by Atlassian). You went into a web page, configured all kinds of stuff, then hoped for the best. It sort of worked. But every time you wanted to make a change, you had to revisit the web site and learn it all over again.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Want to &lt;strong&gt;upgrade Maven&lt;/strong&gt;? Contact the sysadmin.&lt;/li&gt;
&lt;li&gt;Want to install a different &lt;strong&gt;version of Java&lt;/strong&gt;? Contact the sysadmin.&lt;/li&gt;
&lt;li&gt;Want to use a &lt;strong&gt;particular OS&lt;/strong&gt;? Contact the sysadmin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the pattern? Trying to do something edgy, like testing against multiple versions of the JDK was out of the question. No way do any of us have the time for that.&lt;/p&gt;
&lt;h3 id=&quot;several-solutions&quot;&gt;&lt;strong&gt;Several Solutions&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;This is the reason I wholeheartedly embraced &lt;strong&gt;Travis CI&lt;/strong&gt; years ago when it emerged. Visit their website and enable your project. That’s it! All you must do is add a single file with build details to your code base, and you’re set.&lt;/p&gt;
&lt;p&gt;With a huge growth in Travis, other similar CI systems emerged. One that really caught my fancy was &lt;strong&gt;CircleCI&lt;/strong&gt;. The biggest difference was your ability to specify the Docker container your builds would run inside. That meant pulling down images from Docker hub, not just what the CI company offered.&lt;/p&gt;
&lt;p&gt;That came in handy when I spotted minor versions of Java breaking Spring Web Services due to tiny wrinkles inside the JDK’s SOAP libraries.&lt;/p&gt;
&lt;p&gt;That’s when I realized Docker was the ticket to CI nirvana. Docker combined with the Maven wrapper would absolutely obliterate those CI configuration issues.&lt;/p&gt;
&lt;p&gt;The Spring Data release train has grown to 15 officially supported modules. Team leaders Oliver Drotbohm and Mark Paluch had built a tool to automate releasing this beast, but a small gap had grown huge — the Bamboo jobs set up long ago to monitor each module couldn’t keep up.&lt;/p&gt;
&lt;p&gt;There was no way to spot, for example, that someone’s patch in Spring Data Commons would break Spring Data REST due to a change rippling through Spring Data JPA. Discovering these sorts of issues on the day of a release was no way to operate.&lt;/p&gt;
&lt;h3 id=&quot;a-challenge&quot;&gt;&lt;strong&gt;A Challenge&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;So Oliver put out the call for someone to attack our CI system. He didn’t care what the solution was, just that it had to not be rocket science so we all could handle it.&lt;/p&gt;
&lt;p&gt;I raised my hand. This sort of server-side, infrastructure honing is one of my “things.” And so for several months, I hammered away at building a pipeline.&lt;/p&gt;
&lt;p&gt;Did I mention pipelines? Historically, CI systems used to be these mammoth single-job runners. But certain shops (&lt;em&gt;&lt;strong&gt;cough Netflix&lt;/strong&gt;&lt;/em&gt;) raised the bar by defining pipelines where smaller tasks would get chained together. And so other CI systems began defining pipelines. CircleCI introduced one that I used for certain things. But it was clunky and hard to reason what was happening.&lt;/p&gt;
&lt;p&gt;That’s when I discovered &lt;strong&gt;Concourse&lt;/strong&gt;. Oh my, talk about an elegant solution. Everything is boiled down to a job with a set of tasks. And every task is a Docker-managed script with inputs and outputs. You chain together a series of tasks where one task’s outputs are the next task’s inputs. VERY easy to reason about.&lt;/p&gt;
&lt;p&gt;I rapidly added parallel jobs that would compile different profiles against different versions of Java. That, my friend, was the ticket toward creating confidence.&lt;/p&gt;
&lt;p&gt;But there were still a few wrinkles. The Spring Data team must publish branched artifacts without stomping on released ones. Anytime an official branch is pushed to github, we needed a pipeline to run. And Concourse flat out could NOT handle that. You configured it to monitor one and only one branch.&lt;/p&gt;
&lt;h3 id=&quot;revisiting-an-oldenemy&quot;&gt;&lt;strong&gt;Revisiting an Old Enemy&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;So after trudging through thick and thin, I had to put Concourse on the shelf and turn to my old nemesis: &lt;strong&gt;Jenkins&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/1*iPu26AWD0RxC0Z8rtpEliA.png&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;Jenkins is arguably the oldest CI system you’ll ever find. And it has a history of big, clunky configuration screens with pages and pages of options. This, to me, was worse than Bamboo!&lt;/p&gt;
&lt;p&gt;But Jenkins in the past couple years had apparently adopted a pipeline approach. And had adopted a Groovy-based DSL. And (drum roll) had introduced 1st class support for Docker.&lt;/p&gt;
&lt;p&gt;Jenkins also has about 3–4 different dialects to configure a job. I sought out the purist, simplest DSL approach I could find. I had to scrap certain features. But the idea was to make a given version of a given Spring Data module as simple to read as possible. So my teammates would embrace it fully.&lt;/p&gt;
&lt;p&gt;And so I have finally come to accept that the &lt;strong&gt;true solution for CI is Jenkins&lt;/strong&gt; (at least for me). Why? For these key reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every stage &lt;strong&gt;run inside&lt;/strong&gt; a Docker container (except actually building containers).&lt;/li&gt;
&lt;li&gt;Pipeline captured as &lt;strong&gt;code&lt;/strong&gt; in the project.&lt;/li&gt;
&lt;li&gt;Ability to run certain stages in &lt;strong&gt;parallel&lt;/strong&gt; with conditional settings.&lt;/li&gt;
&lt;li&gt;Easy to &lt;strong&gt;read&lt;/strong&gt; and &lt;strong&gt;comprehend&lt;/strong&gt;, hence easy to &lt;strong&gt;alter&lt;/strong&gt; as needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you ever bump into me at a conference, be sure to say “hey!”&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then&lt;/em&gt; &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;em&gt;SIGN UP FOR MY NEWSLETTER&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/jpeg" width="800" height="450" medium="image" url="https://www.procoder.io//_astro/1_QjTvUnXfK6vx5aQLQ6exgQ.71AYzFc7.jpeg"/></item><item><title>I have a pair of 8TB NAS drives[1].</title><link>https://www.procoder.io/articles/2022/2022-02-02_i-have-a-pair-of-8tb-nas-drives-1---b9299f0419aa</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-02-02_i-have-a-pair-of-8tb-nas-drives-1---b9299f0419aa</guid><description>Under the hood, it&apos;s basically a Linux server running LVM.</description><pubDate>Wed, 02 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;i-have-a-pair-of-8tb-nas-drives1&quot;&gt;I have a pair of 8TB NAS drives[1].&lt;/h1&gt;
&lt;p&gt;Under the hood, it’s basically a Linux server running LVM.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I have a pair of 8TB NAS drives[1]. The Synology device itself comes with software to manage it over SMBFS. You can use standard RAID levels, but I’ve adopted SHR-1, Synology’s enhanced variant of RAID 5.&lt;/p&gt;
&lt;p&gt;Under the hood, it’s basically a Linux server running LVM.&lt;/p&gt;
&lt;p&gt;[1] &lt;a href=&quot;https://amzn.to/3ARqhaH&quot;&gt;https://amzn.to/3ARqhaH&lt;/a&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="1408" height="768" medium="image" url="https://www.procoder.io//_astro/default-hero.D-v8eEMA.jpg"/></item><item><title>You have failed me for the last time, Time Machine!</title><link>https://www.procoder.io/articles/2022/2022-01-29_you-have-failed-me-for-the-last--time-machine--a1cd9473f90a</link><guid isPermaLink="true">https://www.procoder.io/articles/2022/2022-01-29_you-have-failed-me-for-the-last--time-machine--a1cd9473f90a</guid><description>What can you do when your backup system completely falls apart?</description><pubDate>Sat, 29 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently purchased a &lt;a href=&quot;https://amzn.to/34j3LeK&quot;&gt;Synology DS420j RAID chassis&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The TL;DR is that this beast is a 4-bay RAID chassis loaded to the hilt with tools to make building redundant disk arrays a snap.&lt;/p&gt;
&lt;p&gt;The first thing I did was point my MacBook Pro as well as the Mrs.’s newly purchased M1 Macbook Air. Time Machine backups at the shiny new memory-alpha NAS.&lt;/p&gt;
&lt;p&gt;(Yes, I assigned it the hostname of memory-alpha. Welcome to Geekland).&lt;/p&gt;
&lt;p&gt;And promptly forgot about it.&lt;/p&gt;
&lt;p&gt;And that was a mistake.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*jiNceawuQxc0C4yG.gif&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt; &lt;em&gt;^ — — — me, force-choking Time Machine&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Guess what?&lt;/p&gt;
&lt;p&gt;A month later, the Mrs. couldn’t find a Keynote presentation she given last fall to a virtual writers conference. A talk she is slated to present later this year.&lt;/p&gt;
&lt;p&gt;Nothing via Alfred. Nothing via Spotlight. All our tools couldn’t find this one little presentation.&lt;/p&gt;
&lt;p&gt;“Enter Time Machine,” I said! And so we did.&lt;/p&gt;
&lt;p&gt;And so we couldn’t find anything. Or at least we couldn’t find anything PRIOR to the setup of memory alpha.&lt;/p&gt;
&lt;p&gt;You see Time Machine works through the magic of hard links.&lt;/p&gt;
&lt;p&gt;Hard links are files that when copied, only copy references. Not the contents. Copy a file 50 times…still only one “copy” of the file. But 50 different records in 50 different folders. Hence, nicely structured but without wasting any disk space.&lt;/p&gt;
&lt;p&gt;Hourly backups running on top of a RAID chassis built on Linux Volume Management, and you are in backup Nirvana.&lt;/p&gt;
&lt;p&gt;That’s what is was SUPPOSED to be.&lt;/p&gt;
&lt;p&gt;The Mrs. was giving me the Evil Eye, consigning herself to the fate of having to recreate a slide show.&lt;/p&gt;
&lt;p&gt;And I was giving Time Machine the Evil Eye for failing what was supposed to be simple.&lt;/p&gt;
&lt;p&gt;Only it started back with cold, lifeless disregard.&lt;/p&gt;
&lt;p&gt;Until the Mrs. pulled out her previous solid state external drive. “What about here?”&lt;/p&gt;
&lt;p&gt;I snatched it from her hands and cried “maybe?!” with exuberance.&lt;/p&gt;
&lt;p&gt;(Okay, it wasn’t QUITE like that. But it adds a little action ehh?)&lt;/p&gt;
&lt;p&gt;After plugging it in and attempting to navigate THIS thing via Time Machine (which also failed), I finally expanded it’s folders and found a small folder named “01–26–2021”.&lt;/p&gt;
&lt;p&gt;After digging around in this ancient folder, we managed to unearth a copy of that Keynote deck. Apparently the file had gotten saved into the iCloud folder INSTEAD of “our” folders, hence never making the journey from her old Mac to the new frontier.&lt;/p&gt;
&lt;p&gt;I shoved a copy into her hands, ejected the solid state backup, and promptly went to sulk over the misery Time Machine had befallen me.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*cjy3FlUk6LHmFAe1.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt; &lt;em&gt;“Time Machine…I thought we were best friends!”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Because I also wondered what other files were missing because it this flub. And how would we find them?&lt;/p&gt;
&lt;p&gt;I started googling for alternatives.&lt;/p&gt;
&lt;p&gt;Turns out that “time machine alternatives” yields about a bazillion articles. And one pointed me toward Carbon Copy Cloner. I promptly downloaded the trial version and fired it up.&lt;/p&gt;
&lt;p&gt;The UI was…amazing. The thing took a peek at my laptop’s hard drive and instantly recognized characteristics I had never known of. And was ready to leverage them. (Look up Apple APFS snapshots if you’re in the mood.)&lt;/p&gt;
&lt;p&gt;I quickly created a task to backup the DATA portion of my hard drive into a specific folder of the NAS. I scheduled it to run hourly BUT DON’T WAKE UP THE MACHINE. And then I tuned it to exclude Dropbox and VMware OneDrive.&lt;/p&gt;
&lt;p&gt;And I clicked “Start”.&lt;/p&gt;
&lt;p&gt;Waking up the next day, it appeared to have finished that backup around 1:30 AM…&lt;/p&gt;
&lt;p&gt;…and complete several more snapshot backups every hour since.&lt;/p&gt;
&lt;p&gt;Going through it’s UI, I was able to “View in Finder” the backup made at 3:30 AM.&lt;/p&gt;
&lt;p&gt;Wow.&lt;/p&gt;
&lt;p&gt;THIS Is what Time Machine is SUPPOSED to be doing!!&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;#x22;src&amp;#x22;:&amp;#x22;@assets/images/medium/0*uJih3s_YACMVKYAZ.jpeg&amp;#x22;,&amp;#x22;alt&amp;#x22;:&amp;#x22;&amp;#x22;,&amp;#x22;index&amp;#x22;:0}&quot;&gt;24 hours haven’t even passed and I’ve already defined a similar task to backup my machine to my 2 TB Passport external drive. (Redundant backups FTW!)&lt;/p&gt;
&lt;p&gt;I also created a task that backs up the “Movies” folder from that 2 TB drive to the “Movies” folder of our glorious RAID chassis, ensuring NOTHING supporting our YouTube channels is lost. And it runs ANYTIME I plug in that external drive.&lt;/p&gt;
&lt;p&gt;I even ran a one-time task that pulled that old Time Machine backup from the Mrs.’s external SSD drive and stuffed it onto memory-alpha.&lt;/p&gt;
&lt;p&gt;That way, if she DOES need a file from yesteryear, there is a snapshot ready, willing and able…located on our already-hard-at-work RAID chassis. Available to search.&lt;/p&gt;
&lt;p&gt;And I plan to backup her data both to the RAID chassis as well as her external drive. So she can take it with her whenever needed.&lt;/p&gt;
&lt;p&gt;THIS is what backups are meant to be. Set it and forget it. And make them easy to consume.&lt;/p&gt;
&lt;p&gt;— Greg&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you want to get a free tech e-book, be alerted to my discounts, and get even MORE content about SPRING BOOT? Then &lt;a href=&quot;https://trnq.st/d2v5&quot;&gt;&lt;strong&gt;SIGN UP FOR MY NEWSLETTER&lt;/strong&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded><media:content type="image/png" width="440" height="374" medium="image" url="https://www.procoder.io//_astro/0_jiNceawuQxc0C4yG.DhaZxGfu.gif"/></item><item><title>Arrow functions are the first/best feature of ES6.</title><link>https://www.procoder.io/articles/2017/2017-04-21_arrow-functions-are-the-first-best-feature-of-es6--c42dd6ab1f1d</link><guid isPermaLink="true">https://www.procoder.io/articles/2017/2017-04-21_arrow-functions-are-the-first-best-feature-of-es6--c42dd6ab1f1d</guid><description>The thought of writing THIS one more time…</description><pubDate>Fri, 21 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;arrow-functions-are-the-firstbest-feature-of-es6&quot;&gt;Arrow functions are the first/best feature of ES6.&lt;/h1&gt;
&lt;p&gt;The thought of writing THIS one more time…&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Arrow functions are the first/best feature of ES6. It’s the #1 reason I now setup babel.js for any JS-based project.&lt;/p&gt;
&lt;p&gt;The thought of writing THIS one more time…&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;var self = this  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;toolkit.do(function() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ....self...  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…makes me shudder!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;toolkit.do(() =&gt; ...this...)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Isn’t that easier?&lt;/p&gt;
&lt;p&gt;And once you take this on, the rest flows.&lt;/p&gt;</content:encoded><media:content type="image/png" width="1408" height="768" medium="image" url="https://www.procoder.io//_astro/default-hero-2.MKd_i9T4.jpg"/></item></channel></rss>