<?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: Prageeth Silva</title>
    <description>The latest articles on DEV Community by Prageeth Silva (@prageethsilva).</description>
    <link>https://dev.to/prageethsilva</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2658910%2F035fdcbb-79d4-4dc4-80c8-01f188367ed3.jpeg</url>
      <title>DEV Community: Prageeth Silva</title>
      <link>https://dev.to/prageethsilva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prageethsilva"/>
    <language>en</language>
    <item>
      <title>Human-Readable IDs in PrismaJS with a few lines of code</title>
      <dc:creator>Prageeth Silva</dc:creator>
      <pubDate>Sat, 05 Apr 2025 16:12:03 +0000</pubDate>
      <link>https://dev.to/prageethsilva/human-readable-ids-in-prismajs-with-one-line-of-code-528l</link>
      <guid>https://dev.to/prageethsilva/human-readable-ids-in-prismajs-with-one-line-of-code-528l</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use &lt;code&gt;prisma-prefixed-ids&lt;/code&gt; to automatically generate prefixed, human-readable IDs (like &lt;code&gt;usr_abc123&lt;/code&gt;) in your Prisma models. Inspired by Stripe’s article on designing APIs for humans, this drop-in extension improves clarity and structure with just one line of set up. No schema changes needed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Use Prefixed IDs?
&lt;/h2&gt;

&lt;p&gt;Ever debugged an API and thought “What even is this ID?”&lt;br&gt;
Stripe solves this by prefixing object IDs: &lt;code&gt;cus_&lt;/code&gt;, &lt;code&gt;pi_&lt;/code&gt;, &lt;code&gt;sub_&lt;/code&gt;, etc. That little prefix gives context instantly. I wanted that in my Prisma projects—so I built &lt;code&gt;prisma-prefixed-ids&lt;/code&gt;. Now all my Prisma models get smart, readable IDs like &lt;code&gt;usr_xyz123&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install &amp;amp; Use
&lt;/h2&gt;

&lt;p&gt;Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;prisma-prefixed-ids
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add one line to your Prisma setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@prisma/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;extendPrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prisma-prefixed-ids&lt;/span&gt;&lt;span class="dl"&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;prisma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrismaClient&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extendPrismaClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;usr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Organization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;org&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use your extended client as usual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;data&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alice@example.com&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="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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "usr_xxxxxxxx"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No need to manually set IDs—they’re generated automatically with the correct prefix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use &lt;code&gt;nanoid&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Instead of UUIDs, this plugin uses nanoid for shorter, URL-safe, high-entropy IDs.&lt;/p&gt;

&lt;p&gt;✅ ~128-bit randomness&lt;br&gt;
✅ Shorter than UUID (24 vs. 36 chars)&lt;br&gt;
✅ Customizable alphabet/length&lt;br&gt;
✅ Great performance&lt;/p&gt;
&lt;h2&gt;
  
  
  Bonus: Custom ID Generator
&lt;/h2&gt;

&lt;p&gt;Want hex IDs? Shorter strings? You can plug in your own generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;customAlphabet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nanoid&lt;/span&gt;&lt;span class="dl"&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;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;nanoid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;customAlphabet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234567890abcdef&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prefix&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="nf"&gt;nanoid&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="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;extendPrismaClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;usr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;idGenerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;generator&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;h2&gt;
  
  
  Deep Dive (For the Curious)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Works only on models with String IDs.&lt;/li&gt;
&lt;li&gt;Uses Prisma’s native extension API (clean, no hacks).&lt;/li&gt;
&lt;li&gt;You can override the ID manually if needed.&lt;/li&gt;
&lt;li&gt;I use it in production on &lt;a href="https://verex.ai" rel="noopener noreferrer"&gt;Verex.ai&lt;/a&gt; — it’s rock solid.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;Give &lt;code&gt;prisma-prefixed-ids&lt;/code&gt; a spin in your next project.&lt;br&gt;
It’s open source, easy to use, and makes your data more readable for devs, support, and even end users.&lt;/p&gt;

&lt;p&gt;Feedback and contributions are welcome on &lt;a href="https://github.com/pureartisan/prisma-prefixed-ids" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>prisma</category>
      <category>database</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Dispatched: The Background Queue/Task Runner for Your Serverless Apps</title>
      <dc:creator>Prageeth Silva</dc:creator>
      <pubDate>Sun, 05 Jan 2025 08:58:51 +0000</pubDate>
      <link>https://dev.to/prageethsilva/dispatched-the-background-queuetask-runner-for-your-serverless-apps-1g74</link>
      <guid>https://dev.to/prageethsilva/dispatched-the-background-queuetask-runner-for-your-serverless-apps-1g74</guid>
      <description>&lt;p&gt;Serverless platforms like Vercel, Netlify, AWS Amplify, and Cloudflare Functions make it incredibly easy to spin up modern web apps. However, one missing piece has always been how to handle background tasks efficiently. As a developer working on multiple projects, I’ve encountered this problem time and again—and after trying several solutions, I decided to create my own: &lt;a href="https://dispatched.dev" rel="noopener noreferrer"&gt;Dispatched.dev&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Background Tasks Are Important
&lt;/h2&gt;

&lt;p&gt;In serverless environments, handling tasks that require long processing times (e.g., sending emails, resizing images, or calling external APIs) directly in your app can lead to timeouts and a poor user experience. Offloading these tasks to a background worker is often the best solution.&lt;/p&gt;

&lt;p&gt;However, implementing background workers in serverless platforms can be challenging. Popular options like AWS SQS or Google Cloud Tasks require significant setup, and you’re often responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing custom integration code.&lt;/li&gt;
&lt;li&gt;Setting up retry mechanisms.&lt;/li&gt;
&lt;li&gt;Monitoring for failures.&lt;/li&gt;
&lt;li&gt;Managing infrastructure scaling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introducing Dispatched
&lt;/h2&gt;

&lt;p&gt;Dispatched is a lightweight, developer-friendly background task runner specifically designed for serverless apps. Here’s how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Simple HTTP-Based Integration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dispatch jobs via a simple HTTP POST request.&lt;/li&gt;
&lt;li&gt;Receive a webhook when the task is ready to execute.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Works with Any Framework&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compatible with Next.js, Node.js, Flask, Laravel and virtually any other language or framework.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automatic Retries&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Failed jobs are retried automatically, so you don’t need to worry about building custom logic for it. If you don't want any retries for a particular job, you can configure it per job.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flexible Scheduling&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can schedule tasks for the future, making it great for delayed jobs like reminders or periodic updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Pros and Cons of Using Dispatched
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Use&lt;/strong&gt;: No need to manage queues or complex infrastructure—just use HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable&lt;/strong&gt;: Built for serverless platforms, so it scales automatically with your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-Saving&lt;/strong&gt;: Eliminates the need to set up and maintain custom task runners.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Webhook Dependency&lt;/strong&gt;: Your app needs to handle incoming webhooks reliably. The maximum duration of the task depends on your application's maximum timeout (e.g. Vercel Pro plans have a limit of 5 minutes per request).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted Solution&lt;/strong&gt;: If you prefer fully self-hosted solutions, Dispatched might not fit your needs right now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;After dealing with the same pain points repeatedly across different projects, I realized there had to be a simpler way to handle background tasks in serverless environments. Dispatched is the result of those lessons, and I’m continuously improving it based on feedback from developers like you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;If you’re struggling with background tasks in your serverless apps, feel free to give &lt;a href="https://dispatched.dev" rel="noopener noreferrer"&gt;Dispatched&lt;/a&gt; a try. There’s a free tier available to help you get started quickly. I’d also love to hear your feedback—whether it’s feature requests or ideas for improvement.&lt;/p&gt;

&lt;p&gt;Serverless development doesn’t have to mean sacrificing simplicity for scalability. With tools like Dispatched, handling background tasks can be seamless and hassle-free.&lt;/p&gt;

&lt;p&gt;Feel free to leave comments if you have any questions, and thanks for reading!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
