<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shannon Mettry</title>
    <description>The latest articles on DEV Community by Shannon Mettry (@shannonianthe).</description>
    <link>https://dev.to/shannonianthe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3948089%2F859859ab-9d3f-4875-bc2f-eed88c90e7dd.png</url>
      <title>DEV Community: Shannon Mettry</title>
      <link>https://dev.to/shannonianthe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shannonianthe"/>
    <language>en</language>
    <item>
      <title>Codewars did not teach me JavaScript. My job did.</title>
      <dc:creator>Shannon Mettry</dc:creator>
      <pubDate>Thu, 18 Jun 2026 16:08:05 +0000</pubDate>
      <link>https://dev.to/shannonianthe/codewars-did-not-teach-me-javascript-my-job-did-379k</link>
      <guid>https://dev.to/shannonianthe/codewars-did-not-teach-me-javascript-my-job-did-379k</guid>
      <description>&lt;h2&gt;
  
  
  Why your brain learns faster by doing than by studying, and the neuroscience that explains it
&lt;/h2&gt;

&lt;p&gt;I spent months on Codewars. One to two problems a day, every day. When I couldn't figure out the answer I would look it up and memorize it.&lt;br&gt;
I also bought courses. Multiple. I knew the basics of JavaScript well enough to talk about it.&lt;/p&gt;

&lt;p&gt;And yet nothing really stuck. The Codewars questions felt abstract and disconnected. The examples made no logical sense to me. I would finish a problem and think okay, and? My brain would not hold onto it because it had nowhere to put it.&lt;/p&gt;

&lt;p&gt;Then I got a job that threw me into real code. Real systems. Real consequences.&lt;/p&gt;

&lt;p&gt;And everything changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The moment it clicked
&lt;/h2&gt;

&lt;p&gt;I remember the specific moment I knew something had shifted.&lt;/p&gt;

&lt;p&gt;I got a ticket that required updating a complex, long script. Hundreds of lines of code. The kind of thing that would have made past me close the laptop and go make a coffee and quietly panic.&lt;/p&gt;

&lt;p&gt;Instead I sat with it. Read through it. Understood what it was doing, where to go in, what to change.&lt;/p&gt;

&lt;p&gt;I did not memorize my way to that moment. I built my way there through months of real work with real purpose.&lt;/p&gt;

&lt;p&gt;That is not a coincidence. That is neuroscience.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is actually happening in your brain
&lt;/h2&gt;

&lt;p&gt;When you learn something in a real context your brain does something different than when you study it abstractly. It does not just store the information, it stores it connected to everything around it. The system it lives in, the problem it solves, the feeling of figuring it out.&lt;/p&gt;

&lt;p&gt;This is called contextual learning. Your hippocampus, which handles memory formation, encodes information much more effectively when it is attached to a meaningful experience. Abstract exercises give it nowhere to anchor. Real problems give it a whole ecosystem to hold onto.&lt;/p&gt;

&lt;p&gt;There is also the dopamine loop to consider. Every time you fix something real like a bug, a broken integration, a script that finally runs correctly your brain releases dopamine. That dopamine hit reinforces the behavior and the learning attached to it. Your brain literally marks that moment as worth remembering.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why algorithms and abstract exercises are so hard for certain brains
&lt;/h2&gt;

&lt;p&gt;Here is the thing nobody says out loud. Codewars and algorithm challenges are not bad. They work for some people. Specifically they work for people who can hold abstract problems in their head and find satisfaction in solving them without real world context.&lt;/p&gt;

&lt;p&gt;Not everyone's brain works that way.&lt;/p&gt;

&lt;p&gt;Some people, and I am clearly one of the,  need the concrete thing first. The real system, the actual purpose, the tangible result. The theory makes sense after the experience, not before it.&lt;/p&gt;

&lt;p&gt;Neuroscientists call this bottom up learning. You build understanding from specific real experiences upward toward general principles. The opposite, top down learning, starts with the abstract concept and works toward application. Neither is better. They are just different and most technical education assumes everyone is top down.&lt;/p&gt;

&lt;p&gt;If you have ever felt stupid because you could not get through algorithm challenges, you are probably not stupid. You are just bottom up in a top down world.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually worked for me
&lt;/h2&gt;

&lt;p&gt;Real projects with real stakes. A job that required JavaScript every single day for eight hours. Tickets with consequences. Systems I could break and fix and break again.&lt;/p&gt;

&lt;p&gt;The repetition mattered too. Doing the same types of problems over and over in slightly different contexts until the patterns stopped being something I had to think about and became something I just saw.&lt;/p&gt;

&lt;p&gt;That is how procedural memory forms. The same way you learn to drive or surf. Not by studying the theory but by doing it until your brain stops treating it as a conscious effort.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to use this if you are learning right now
&lt;/h2&gt;

&lt;p&gt;Stop grinding abstract exercises if they are making you feel like you are not smart enough. That feeling is your brain telling you it needs context not confirmation that you are broken.&lt;/p&gt;

&lt;p&gt;Find a real project. Build something you actually care about even if it is small and messy. Contribute to open source. Get a job that throws you in the deep end. Find any context that gives the code a reason to exist and your brain something real to hold onto.&lt;/p&gt;

&lt;p&gt;The courses are not useless. The foundation matters. But the foundation only becomes a building when you have something real to build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your brain is not the problem. The method might be.
&lt;/h3&gt;

</description>
      <category>career</category>
      <category>codenewbie</category>
      <category>javascript</category>
      <category>learning</category>
    </item>
    <item>
      <title>REST vs SOAP — what nobody told me when I started working with both</title>
      <dc:creator>Shannon Mettry</dc:creator>
      <pubDate>Wed, 17 Jun 2026 16:40:06 +0000</pubDate>
      <link>https://dev.to/shannonianthe/rest-vs-soap-what-nobody-told-me-when-i-started-working-with-both-1ghh</link>
      <guid>https://dev.to/shannonianthe/rest-vs-soap-what-nobody-told-me-when-i-started-working-with-both-1ghh</guid>
      <description>&lt;p&gt;REST and SOAP are both ways of sending and receiving data between systems. They do the same job. They just do it very differently. And nobody really explained that to me clearly when I started. I just kept looking for patterns until things clicked.&lt;/p&gt;

&lt;p&gt;This is what I wish someone had said out loud.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I actually encountered both
&lt;/h2&gt;

&lt;p&gt;I use REST most of the time. It feels natural at this point. I think in it, I debug in it, it's the default mode.&lt;/p&gt;

&lt;p&gt;Then a client comes along running Adobe Campaign Classic and suddenly I am looking at XML wrapped in envelopes and thinking okay, different rules here. SOAP shows up with older enterprise systems a lot. The kind of platforms that were built before REST was even a thing and have no intention of changing now.&lt;/p&gt;

&lt;p&gt;You don't always get to choose which one you work with. The system chooses for you. So you learn to read both.&lt;/p&gt;

&lt;p&gt;My approach when I hit something unfamiliar is always the same, look for the patterns. What is this sending? What structure is it expecting back? What breaks when something goes wrong? The specifics change but the thinking doesn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  What REST actually is
&lt;/h2&gt;

&lt;p&gt;REST stands for Representational State Transfer. It is an architectural style for building APIs that communicate over HTTP. It sends and receives data in JSON format, which is lightweight, human readable, and maps naturally to JavaScript objects.&lt;/p&gt;

&lt;p&gt;It works with standard HTTP methods: GET to retrieve data, POST to send it, PUT to update it, DELETE to remove it. If you have done any web development you already know these.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascript&lt;/span&gt;&lt;span class="c1"&gt;// GET request — retrieving a user&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/users/1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// POST request — creating a user&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Shan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Integration Developer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean. Readable. Does exactly what it looks like it does.&lt;/p&gt;




&lt;h2&gt;
  
  
  What SOAP actually is
&lt;/h2&gt;

&lt;p&gt;SOAP stands for Simple Object Access Protocol. The word simple is doing a lot of heavy lifting there.&lt;/p&gt;

&lt;p&gt;SOAP sends data wrapped in XML inside a defined envelope structure. It has strict rules about how messages are formatted, what headers look like, and how errors are handled. It was built for enterprise environments where consistency and security matter more than convenience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;xml&lt;span class="c"&gt;&amp;lt;!-- SOAP request envelope --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;soap:Envelope&lt;/span&gt; &lt;span class="na"&gt;xmlns:soap=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/envelope/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;soap:Header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AuthHeader&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Username&amp;gt;&lt;/span&gt;shannon&lt;span class="nt"&gt;&amp;lt;/Username&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Password&amp;gt;&lt;/span&gt;supersecure&lt;span class="nt"&gt;&amp;lt;/Password&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/AuthHeader&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/soap:Header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;soap:Body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GetUser&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;UserId&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/UserId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/GetUser&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/soap:Body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/soap:Envelope&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- SOAP response --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;soap:Envelope&lt;/span&gt; &lt;span class="na"&gt;xmlns:soap=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/envelope/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;soap:Body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GetUserResponse&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Name&amp;gt;&lt;/span&gt;Shannon&lt;span class="nt"&gt;&amp;lt;/Name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Role&amp;gt;&lt;/span&gt;Integration Developer&lt;span class="nt"&gt;&amp;lt;/Role&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/GetUserResponse&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/soap:Body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/soap:Envelope&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More verbose. More rigid. But when you are working with systems like Adobe Campaign or banking platforms or healthcare integrations, this is the language they speak and you meet them where they are.&lt;/p&gt;




&lt;h2&gt;
  
  
  The practical differences side by side
&lt;/h2&gt;

&lt;p&gt;Data format: REST uses JSON, SOAP uses XML.&lt;br&gt;
Protocol: REST works over standard HTTP, SOAP has its own protocol on top of HTTP.&lt;br&gt;
Flexibility: REST is flexible about structure, SOAP enforces a strict contract.&lt;br&gt;
Error handling: REST uses HTTP status codes like 404 or 500, SOAP has its own fault elements inside the envelope.&lt;br&gt;
When you see it: REST is everywhere in modern APIs and web services. SOAP shows up in enterprise systems, legacy platforms, and anywhere that was built before REST became the standard.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I approach switching between them
&lt;/h2&gt;

&lt;p&gt;When I hit a new integration I look for patterns first. What format is the data in? What does the request structure look like? What does a successful response look like versus an error?&lt;/p&gt;

&lt;p&gt;With REST that usually means checking the endpoint documentation and looking at the JSON structure. With SOAP it means finding the WSDL file which defines all the operations and data types the service supports, and then working out what envelope structure it expects.&lt;/p&gt;

&lt;p&gt;The thinking is the same. The syntax is just very different.&lt;/p&gt;

&lt;p&gt;The one line to remember&lt;/p&gt;

&lt;p&gt;REST is a conversation. SOAP is a legal contract.&lt;/p&gt;

&lt;p&gt;Both get the job done. One just requires a lot more paperwork. And sometimes the paperwork is not optional.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I stopped posting when I got a job. Classic.</title>
      <dc:creator>Shannon Mettry</dc:creator>
      <pubDate>Sat, 13 Jun 2026 11:42:50 +0000</pubDate>
      <link>https://dev.to/shannonianthe/i-stopped-posting-when-i-got-a-job-classic-40b4</link>
      <guid>https://dev.to/shannonianthe/i-stopped-posting-when-i-got-a-job-classic-40b4</guid>
      <description>&lt;p&gt;That's what I wrote when I came back to LinkedIn recently. Short, a little dry, kind of embarrassing to admit. People related to it immediately.&lt;/p&gt;

&lt;p&gt;But the longer version is more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The return
&lt;/h2&gt;

&lt;p&gt;I used to post every day. CSS tips, UX observations, little things I noticed about how people move through interfaces. I was genuinely excited about it. I'd wake up thinking about what to share. Then I got a job, got comfortable, got absorbed into the rhythm of meetings and incident queues and just... stopped.&lt;/p&gt;

&lt;p&gt;I didn't notice how much I missed it until I came back. And coming back made me think about why I left in the first place. And that made me think about what social media actually is now and what we're all doing on it.&lt;/p&gt;

&lt;p&gt;So now I'm back. Not with a strategy or a content calendar. More like an experiment.&lt;/p&gt;

&lt;p&gt;What makes people stop scrolling? What gets a reaction and what disappears into the void? I have theories but no data. And the only way to get data is to show up and pay attention.&lt;/p&gt;

&lt;p&gt;Also, rejection therapy. Because apparently posting on the internet still makes me nervous and I think that's worth pushing through.&lt;/p&gt;




&lt;h2&gt;
  
  
  How social media actually changed
&lt;/h2&gt;

&lt;p&gt;Here's what I keep thinking about. Our phones are our TVs now. That's not a metaphor anymore, it's just true.&lt;/p&gt;

&lt;p&gt;We don't sit down to watch something scheduled at a specific time. We scroll through hundreds of micro-moments from real people living real lives and decide in about half a second whether to stay or keep moving. The average human attention span online is now shorter than a goldfish. Which is either depressing or fascinating depending on your mood.&lt;/p&gt;

&lt;p&gt;And it's changed everything around it. The way brands sell. The way people find jobs. The way ideas spread. The way trust gets built between a stranger and an audience.&lt;/p&gt;

&lt;p&gt;Sales used to be about reach, get your message in front of as many people as possible. Billboards. TV spots. Email blasts. Now it's about resonance. Does this person feel real? Do I trust them? Do I want to keep watching? You can have a million followers and no trust, or a thousand followers and genuine influence. The metric that used to matter most is now almost beside the point.&lt;/p&gt;

&lt;p&gt;Every person with a phone is now a potential channel. A media company of one. Including me. Including you.&lt;/p&gt;




&lt;h2&gt;
  
  
  The niche question
&lt;/h2&gt;

&lt;p&gt;Everyone says you need a niche. Find your lane, stay in it, build an audience around one specific thing.&lt;/p&gt;

&lt;p&gt;I don't have mine yet. I'm a tech person who loves integrations and APIs and also thinks about UX and also wants to try UGC content creation and also finds the sociology of social media genuinely fascinating. That's either a problem or just an honest starting point.&lt;/p&gt;

&lt;p&gt;I think the people who say "find your niche first" are skipping the part where you have to try things before you know what fits. You don't find a niche by thinking about it. You find it by showing up, making things, paying attention to what feels natural and what feels like a performance.&lt;/p&gt;

&lt;p&gt;So that's what I'm doing. Natural, honest, with a dry edge of humor. No performing confidence I don't have. Just curiosity and consistency and seeing what happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters for people in tech specifically
&lt;/h2&gt;

&lt;p&gt;If you work in tech and you're not building any kind of public presence, I'm not saying you have to, but it's worth at least thinking about.&lt;/p&gt;

&lt;p&gt;The way people get hired is changing. The way people find collaborators is changing. The way you demonstrate what you know is changing. A CV is still important but it's increasingly one part of a bigger picture. What do you write about? What do you build in public? What problems do you talk about?&lt;/p&gt;

&lt;p&gt;I'm not saying become an influencer. I'm saying show up somewhere consistently and be honest about what you're learning. That's it. The bar is lower than it looks.&lt;/p&gt;

&lt;p&gt;I know because I just came back after years away and the most common response I got was "same."&lt;/p&gt;

&lt;p&gt;So. Here we are. Let's see what this social media thing does.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I stopped nodding along and actually contributed to open source</title>
      <dc:creator>Shannon Mettry</dc:creator>
      <pubDate>Thu, 04 Jun 2026 15:57:00 +0000</pubDate>
      <link>https://dev.to/shannonianthe/how-i-stopped-nodding-along-and-actually-contributed-to-open-source-250l</link>
      <guid>https://dev.to/shannonianthe/how-i-stopped-nodding-along-and-actually-contributed-to-open-source-250l</guid>
      <description>&lt;p&gt;For years I saw "open source contributions" on job descriptions and just... nodded along. Typed it into Google once, got overwhelmed, closed the tab.&lt;/p&gt;

&lt;p&gt;It always seemed like something other people did. People who actually knew what they were doing. People who weren't me.&lt;/p&gt;

&lt;p&gt;Then I started looking into it properly. And honestly? It still seemed big. Like I'd need to understand an entire codebase, find a complex bug, write some genius fix that the maintainers would applaud.&lt;br&gt;
Turns out that's not it at all.&lt;/p&gt;

&lt;p&gt;I found some resources that changed how I saw it completely. The bar to start is embarrassingly low, and that's intentional. The open source community built it that way on purpose.&lt;/p&gt;

&lt;p&gt;So I did it. Was it a few lines of code? Yes. Did I do it directly in the browser like a person who has no idea what they're doing? Also yes. Do I care? Absolutely not.&lt;/p&gt;

&lt;p&gt;Where to actually start:&lt;/p&gt;

&lt;p&gt;goodfirstissue.dev — filters repos by good first issue label&lt;br&gt;
up-for-grabs.net — same idea, different interface&lt;br&gt;
Docs you already use — if you read something and think "that's oddly worded," you're already there&lt;br&gt;
GitHub search — label:"good first issue" is:open and filter by language&lt;/p&gt;

&lt;p&gt;Here's the thing though, this isn't just about open source. Everything seems big and intimidating at first. So you start small. One tiny contribution. Not because it's impressive but because it's real, and it's yours, and it builds something. Confidence mostly. Then you do a slightly bigger thing. Then a bigger thing after that.&lt;/p&gt;

&lt;p&gt;You don't level up by waiting until you're ready. You level up by starting small and not stopping.&lt;/p&gt;

&lt;p&gt;My first contribution exists now. That's enough for today.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>basic</category>
    </item>
    <item>
      <title>Why WhatsApp API Integrations Fail: Lessons from Real-Time Systems</title>
      <dc:creator>Shannon Mettry</dc:creator>
      <pubDate>Sat, 23 May 2026 18:32:24 +0000</pubDate>
      <link>https://dev.to/shannonianthe/why-whatsapp-api-integrations-fail-lessons-from-real-time-systems-14f0</link>
      <guid>https://dev.to/shannonianthe/why-whatsapp-api-integrations-fail-lessons-from-real-time-systems-14f0</guid>
      <description>&lt;p&gt;In marketing technology, “sending a message” is never just sending a message.&lt;/p&gt;

&lt;p&gt;In my case, I work on the technical layer that prepares and sends structured campaign data from a delivery creation system into the Meta WhatsApp Template API.&lt;/p&gt;

&lt;p&gt;That means I don’t build the messaging platform itself. I build everything &lt;em&gt;before&lt;/em&gt; it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validating campaign data&lt;/li&gt;
&lt;li&gt;enforcing strict formatting rules&lt;/li&gt;
&lt;li&gt;structuring payloads correctly&lt;/li&gt;
&lt;li&gt;checking whether requests were accepted&lt;/li&gt;
&lt;li&gt;and building workflows that survive very opinionated APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if there’s one thing I’ve learned from working with strict APIs, it’s this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The hardest part is rarely sending the data.&lt;/p&gt;

&lt;p&gt;The hardest part is convincing the API your data deserves to exist.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The reality of “real-time integrations”
&lt;/h2&gt;

&lt;p&gt;People hear “real-time integration” and imagine something elegant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System A → API → Message sent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In reality, the workflow usually looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Delivery Creation System
        ↓
Data Validation Layer
        ↓
Payload Transformation
        ↓
WhatsApp Template Formatting
        ↓
Meta API Request
        ↓
Acceptance Check
        ↓
Webhook Confirmation
        ↓
Retry / Logging / Monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message itself is actually the easiest part.&lt;/p&gt;

&lt;p&gt;The difficult part is making sure the payload satisfies every rule enforced by the receiving API.&lt;/p&gt;

&lt;p&gt;And the Meta WhatsApp Template API has &lt;em&gt;a lot&lt;/em&gt; of rules.&lt;/p&gt;




&lt;h2&gt;
  
  
  Strict APIs do not negotiate
&lt;/h2&gt;

&lt;p&gt;One of the first things I learned is that WhatsApp templates are extremely rigid.&lt;/p&gt;

&lt;p&gt;You are not sending “messages”.&lt;/p&gt;

&lt;p&gt;You are sending:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;approved templates&lt;/li&gt;
&lt;li&gt;predefined structures&lt;/li&gt;
&lt;li&gt;validated variables&lt;/li&gt;
&lt;li&gt;controlled CTA configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything has to fit the exact schema expected by Meta.&lt;/p&gt;

&lt;p&gt;Not “close enough”.&lt;/p&gt;

&lt;p&gt;Not “technically valid JSON”.&lt;/p&gt;

&lt;p&gt;Exactly correct.&lt;/p&gt;




&lt;h2&gt;
  
  
  The formatting constraints are where things get interesting
&lt;/h2&gt;

&lt;p&gt;Most integration issues were not caused by networking problems or authentication failures.&lt;/p&gt;

&lt;p&gt;They were caused by formatting.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h2&gt;
  
  
  Invalid newline characters
&lt;/h2&gt;

&lt;p&gt;Something as small as an unexpected newline character can create problems depending on template validation rules.&lt;/p&gt;

&lt;p&gt;This means data often has to be sanitized before it is sent.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sanitizeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple?&lt;/p&gt;

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

&lt;p&gt;Important?&lt;/p&gt;

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

&lt;p&gt;Because formatting is not cosmetic in systems like this.&lt;/p&gt;

&lt;p&gt;Formatting &lt;em&gt;is logic&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  CTA rules: where flexibility disappears
&lt;/h2&gt;

&lt;p&gt;Call-to-actions (CTAs) were another area with strict constraints.&lt;/p&gt;

&lt;p&gt;Templates only allow certain CTA structures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;limited number of buttons&lt;/li&gt;
&lt;li&gt;predefined action types&lt;/li&gt;
&lt;li&gt;strict ordering requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which means you cannot dynamically invent whatever UX the business wants.&lt;/p&gt;

&lt;p&gt;At some point, every integration engineer eventually says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“No, we cannot add a fourth button because Meta said no.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And surprisingly often, that becomes a real architectural discussion.&lt;/p&gt;




&lt;h2&gt;
  
  
  The integration layer became a validation system
&lt;/h2&gt;

&lt;p&gt;One of the biggest lessons from this workflow was realizing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The system is not really a messaging system.&lt;/p&gt;

&lt;p&gt;It is a validation system that occasionally sends messages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before anything gets sent, the workflow has to verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CTA counts are valid&lt;/li&gt;
&lt;li&gt;variables match template expectations&lt;/li&gt;
&lt;li&gt;required fields exist&lt;/li&gt;
&lt;li&gt;formatting rules are respected&lt;/li&gt;
&lt;li&gt;payload structure matches the approved template&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because once the payload reaches Meta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it may be accepted&lt;/li&gt;
&lt;li&gt;it may be rejected&lt;/li&gt;
&lt;li&gt;or in some cases, it may fail in ways that are not immediately obvious&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is why defensive validation matters so much.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the payload
&lt;/h2&gt;

&lt;p&gt;Here’s a simplified example of the kind of transformation logic involved in the integration layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildTemplatePayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowedCtas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CTA limit exceeded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sanitizedVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;messaging_product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;whatsapp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;template&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en_US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sanitizedVariables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
          &lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting part is not the JavaScript itself.&lt;/p&gt;

&lt;p&gt;It’s the design philosophy behind it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Data cannot be trusted to arrive API-ready.&lt;/p&gt;

&lt;p&gt;It has to be transformed into something the receiving system is willing to accept.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  “Message sent” is not success
&lt;/h2&gt;

&lt;p&gt;Another important lesson:&lt;/p&gt;

&lt;p&gt;Sending the request is only half the workflow.&lt;/p&gt;

&lt;p&gt;After the payload is sent, we still need to determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;was the request accepted?&lt;/li&gt;
&lt;li&gt;was the message processed correctly?&lt;/li&gt;
&lt;li&gt;did the delivery succeed?&lt;/li&gt;
&lt;li&gt;did downstream systems confirm the event?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So after sending the payload, the workflow performs additional checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://graph.facebook.com/v19.0/messages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API rejection:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But even a successful API response is not the final truth.&lt;/p&gt;

&lt;p&gt;The workflow still relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;response verification&lt;/li&gt;
&lt;li&gt;logging&lt;/li&gt;
&lt;li&gt;webhook confirmation&lt;/li&gt;
&lt;li&gt;retry handling&lt;/li&gt;
&lt;li&gt;reconciliation checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because in real integrations:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Accepted by API” does not automatically mean “delivered successfully”.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Real-time systems are actually reliability systems
&lt;/h2&gt;

&lt;p&gt;One thing I underestimated early on was how much of “real-time integration” is actually about resilience.&lt;/p&gt;

&lt;p&gt;You quickly realize the real engineering work is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;handling retries&lt;/li&gt;
&lt;li&gt;tracking failures&lt;/li&gt;
&lt;li&gt;validating edge cases&lt;/li&gt;
&lt;li&gt;preventing malformed payloads&lt;/li&gt;
&lt;li&gt;monitoring delivery status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not just sending requests quickly.&lt;/p&gt;

&lt;p&gt;The API call itself is usually the shortest part of the process.&lt;/p&gt;

&lt;p&gt;The surrounding system is where the complexity lives.&lt;/p&gt;




&lt;h2&gt;
  
  
  The most dangerous failures are silent ones
&lt;/h2&gt;

&lt;p&gt;Hard failures are annoying.&lt;/p&gt;

&lt;p&gt;Silent failures are terrifying.&lt;/p&gt;

&lt;p&gt;Because if a payload fails quietly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;messages disappear&lt;/li&gt;
&lt;li&gt;workflows become inconsistent&lt;/li&gt;
&lt;li&gt;debugging becomes archaeology&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why observability became extremely important in our workflow.&lt;/p&gt;

&lt;p&gt;Every step needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logging&lt;/li&gt;
&lt;li&gt;validation&lt;/li&gt;
&lt;li&gt;tracking&lt;/li&gt;
&lt;li&gt;explicit error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because eventually every integration engineer learns:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a system can fail silently, it eventually will.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usually on Friday afternoon.&lt;/p&gt;




&lt;h2&gt;
  
  
  Constraints actually improve engineering
&lt;/h2&gt;

&lt;p&gt;At first, strict APIs feel frustrating.&lt;/p&gt;

&lt;p&gt;But over time, I realized they force better engineering discipline.&lt;/p&gt;

&lt;p&gt;You stop making assumptions.&lt;/p&gt;

&lt;p&gt;You validate everything.&lt;/p&gt;

&lt;p&gt;You think more carefully about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structure&lt;/li&gt;
&lt;li&gt;consistency&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;system reliability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And ironically, those constraints often produce cleaner systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Working with the Meta WhatsApp Template API taught me something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most integration work is not about moving data.&lt;/p&gt;

&lt;p&gt;It’s about shaping data into something another system is willing to trust.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in marketing technology, the real challenge is not sending messages in real time.&lt;/p&gt;

&lt;p&gt;It’s building workflows reliable enough to survive strict APIs, validation rules, and the reality that every external system has opinions about your payload.&lt;/p&gt;

&lt;p&gt;Very strong opinions.&lt;/p&gt;

</description>
      <category>api</category>
      <category>backend</category>
      <category>marketing</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
