<?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: Henrique Weiand</title>
    <description>The latest articles on DEV Community by Henrique Weiand (@henriqueweiand).</description>
    <link>https://dev.to/henriqueweiand</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%2F1179366%2F48f72873-6af3-442a-b196-4341ab171d04.png</url>
      <title>DEV Community: Henrique Weiand</title>
      <link>https://dev.to/henriqueweiand</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/henriqueweiand"/>
    <language>en</language>
    <item>
      <title>Running NestJS in a Lambda function with LocalStack and Serverless Framework</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Sun, 23 Feb 2025 17:41:05 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/running-nestjs-in-a-lambda-function-with-localstack-and-serverless-framework-enk</link>
      <guid>https://dev.to/nestjs-ninja/running-nestjs-in-a-lambda-function-with-localstack-and-serverless-framework-enk</guid>
      <description>&lt;p&gt;Hey there, tech enthusiasts! Ever found yourself needing a quick and efficient way to whip up QR codes for your projects? Well, in today's blog post, we will cover an awesome solution that brings together NestJS and AWS Lambda, all while keeping things super smooth with the Serverless Framework and LocalStack.&lt;/p&gt;

&lt;p&gt;In this post, we’ll dive into on &lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack" rel="noopener noreferrer"&gt;nestjs-lambda-qrcode-generator-with-local-stack&lt;/a&gt; project that tackles real-world challenges by turning NestJS applications into Lambda functions. We’ll also see how the Serverless Framework makes deploying these functions a breeze and how LocalStack lets you test everything locally without breaking a sweat.&lt;/p&gt;

&lt;p&gt;Whether you’re a seasoned developer or just starting out, this guide will show you how to create a scalable, serverless QR code generator that’s ready for any project you throw at it. Let’s get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Stack and Serverless ⚔
&lt;/h3&gt;

&lt;p&gt;It's important to give some context before going deeper into the two technologies that are applied to the project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.localstack.cloud/" rel="noopener noreferrer"&gt;LocalStack&lt;/a&gt; is a powerful tool that emulates AWS services on your local machine, enabling developers to test and develop cloud applications without the need to deploy them to the actual AWS environment. This local emulation accelerates development cycles and reduces costs associated with cloud deployments.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;The Serverless Framework&lt;/a&gt; is a popular open-source framework that simplifies the deployment and management of serverless applications across various cloud providers, including AWS. It streamlines the process of defining and deploying serverless functions, making it easier for developers to build scalable applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By integrating LocalStack with the Serverless Framework, developers can deploy and test their serverless applications locally, ensuring that everything works as expected before moving to the cloud. This combination provides a seamless workflow for building, testing, and deploying serverless applications efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running a NestJS project on lambda 🚀
&lt;/h3&gt;

&lt;p&gt;Running a NestJS application on AWS Lambda allows you to build serverless applications that automatically scale and reduce infrastructure management. By using tools like @vendia/serverless-express, you can adapt your NestJS app to function within the Lambda environment, handling cases like HTTP requests, cron-jobs, processing tasks internally by demand, and so on. This setup enables you to focus on developing features without worrying about server maintenance, as AWS manages the underlying infrastructure for you.  ￼&lt;/p&gt;

&lt;p&gt;NOW A BIG BUT! Running a NestJS application on a lambda function has its disadvantages, and the biggest is the &lt;code&gt;cold start&lt;/code&gt;. &lt;strong&gt;As big as your application gets with the usage of libraries, connections, async/await executions, or just because the project is complex and big, it can take more time for the lambda to start responding to a request or any execution&lt;/strong&gt;. It depends on the context, so it is recommended to pay attention to the requirements to design a better solution.&lt;/p&gt;

&lt;p&gt;I recommend you access the official NestJS documentation (&lt;a href="https://docs.nestjs.com/faq/serverless" rel="noopener noreferrer"&gt;https://docs.nestjs.com/faq/serverless&lt;/a&gt;), and spend a few minutes reading from the top to bottom. There are some important points about how to make the standalone application and also benchmarks with different approaches. A simple example is how you define your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// &lt;span class="c"&gt;#2 Nest (with @nestjs/platform-express)&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; NestFactory &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'@nestjs/core'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; AppModule &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'./app.module'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

async &lt;span class="k"&gt;function &lt;/span&gt;bootstrap&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const app &lt;span class="o"&gt;=&lt;/span&gt; await NestFactory.create&lt;span class="o"&gt;(&lt;/span&gt;AppModule, &lt;span class="o"&gt;{&lt;/span&gt; logger: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'error'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  await app.listen&lt;span class="o"&gt;(&lt;/span&gt;process.env.PORT ?? 3000&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
bootstrap&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

// &lt;span class="c"&gt;#3 Nest as a Standalone application (no HTTP server)&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; NestFactory &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'@nestjs/core'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; AppModule &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'./app.module'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; AppService &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'./app.service'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

async &lt;span class="k"&gt;function &lt;/span&gt;bootstrap&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const app &lt;span class="o"&gt;=&lt;/span&gt; await NestFactory.createApplicationContext&lt;span class="o"&gt;(&lt;/span&gt;AppModule, &lt;span class="o"&gt;{&lt;/span&gt;
    logger: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'error'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;app.get&lt;span class="o"&gt;(&lt;/span&gt;AppService&lt;span class="o"&gt;)&lt;/span&gt;.getHello&lt;span class="o"&gt;())&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
bootstrap&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See that we have an application without an HTTP server that will respond faster.&lt;/p&gt;

&lt;p&gt;For every solution, there will always be pros and cons, so think about the architecture before starting coding like crazy!&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting into the project 🎯
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you ask me how I come up with ideas for projects, I keep an eye on the websites with job opportunities, like &lt;a href="//upwork.com"&gt;Upwork&lt;/a&gt;, not because I want to get a job, but eventually, I find good ideas for projects (simple ones of course) that I can use as a context to practice, and this project was one of that cases. &lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;This is quite a simple project, the job description required a Lambda function that was able to receive a GET request and through the query params, a URL that should be used to build the QRCode. The QRCode should be storeged into an S3 bucket with a public link.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I did this idea two times, the first one I didn't wrote anything about, but, the first version was working only with Serverless, and the new one is working with both Serverless Framework and LocalStack, which makes everything much more real. This is the link of the first version → &lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, as I quickly explained before, we generate different types of NestJS instances, and with those requirements, I knew I needed an HTTP server, so that's why I am applying &lt;code&gt;NestFactory.create&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/serverless.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/serverless.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By the way, you will see two starting points, I mean, both serverless.ts and main.ts, and each one of them is creating a NestJS instance. The reason is that I wanted to be able to test it outside the Serverless and Local Stack, like a normal NestJS app, so the main.ts is executed as a normal NestJS application, while the serverless.ts is used for the Serverless Framework.&lt;/p&gt;

&lt;p&gt;The starting point for the Serverless framework is the &lt;code&gt;serverless.yml&lt;/code&gt;, which holds the recipe of the application, for example, the application needs to run in a lambda function, this method needs to be able to receive POST or GET requests, and it uses S3 and the AWS IAM roles should be XPTO… got it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/serverless.yaml" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/serverless.yaml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important to mention the initial method called by the lambda when executing. In this case, it is &lt;code&gt;serverless.handler&lt;/code&gt; which matches with &lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/serverless.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/serverless.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point I know you want to see the Lamda function running, but, I suggest making the application work first, so you can reduce the doubts that you might have when running the Lamda and seeing unexpected issues happen. &lt;/p&gt;

&lt;h3&gt;
  
  
  Code structure 🧠
&lt;/h3&gt;

&lt;p&gt;There's no right or wrong in terms of how to organize the application modules and files, so, create your application as you want, mine ended up like this&lt;/p&gt;

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

&lt;p&gt;The controller holds one route and receives a query parameter which will be the URL&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/qr/qrcode.controller.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/qr/qrcode.controller.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then QRCodeService only receives the URL and generates the QRCode, and then, the qrCodeBuffer is passed down to the s3Service for the upload.&lt;/p&gt;

&lt;p&gt;The s3Service has a few details, for example, when it's running for &lt;code&gt;production&lt;/code&gt; it is not getting the ENV files because the lambda will use the roles applied for the service itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/qr/s3.service.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-lambda-qrcode-generator-with-local-stack/blob/master/src/qr/s3.service.ts&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the project with and without Local Stack 🦾
&lt;/h2&gt;

&lt;p&gt;Instead of writing more, I decided to make a video with the 3 possible ways to run the application, they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running a normal NestJS application;&lt;/li&gt;
&lt;li&gt;Running NestJS Application with Serverless Framework + serverless-offline + serverless-s3-local;&lt;/li&gt;
&lt;li&gt;Running NestJS Application with Serverless Framework + Local Stack;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/h_u47QHLz1I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion 👨🏼‍🔧
&lt;/h2&gt;

&lt;p&gt;In this journey, we’ve explored how to build a scalable, serverless QR code generator using NestJS, AWS Lambda, the Serverless Framework, and LocalStack. By integrating these technologies, you can efficiently develop, test, and deploy applications that meet real-world needs without the hassle of managing server infrastructure. Remember to consider the specific requirements of your project, such as the necessity of an HTTP server, and be mindful of potential challenges like cold starts in Lambda functions. For more insights and detailed guidance, refer to the official NestJS documentation on serverless applications. Embrace these tools to streamline your development process and deliver robust solutions with ease.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pay attention to the necessities of your application, for instance, using HTTP or not;&lt;/li&gt;
&lt;li&gt;Add logs, it helps to debug the Lambda on the providers, even console.info, error, …&lt;/li&gt;
&lt;li&gt;Use as less libraries as possible;&lt;/li&gt;
&lt;li&gt;Keep the project simple, don't put lots of responsibility for each lambda;&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://docs.nestjs.com/cli/monorepo" rel="noopener noreferrer"&gt;Monorepo&lt;/a&gt; approach can help to share a common code while different lamdas;&lt;/li&gt;
&lt;li&gt;Be aware of the final size of your project, the providers have limits - &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Read the official documentation to get the most of different approaches to reduce the size and perform the project &lt;a href="https://docs.nestjs.com/faq/serverless" rel="noopener noreferrer"&gt;https://docs.nestjs.com/faq/serverless&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nestjs</category>
      <category>node</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Implementing Kubernetes Jobs with NestJS and nest-commander: A Practical Guide (Ex. implementation with Ticketmaster)</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Tue, 18 Feb 2025 20:30:37 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/implementing-kubernetes-jobs-with-nestjs-and-nest-commander-a-practical-guide-ex-implementation-2a5d</link>
      <guid>https://dev.to/nestjs-ninja/implementing-kubernetes-jobs-with-nestjs-and-nest-commander-a-practical-guide-ex-implementation-2a5d</guid>
      <description>&lt;p&gt;Hey there! Ever found yourself knee-deep in building NestJS applications and thought, “Man, I wish I could bring this awesome structure to my command-line tools”? Well, you’re in luck! The &lt;a href="https://docs.nestjs.com/recipes/nest-commander" rel="noopener noreferrer"&gt;nest-commander package&lt;/a&gt; does just that, letting you craft CLI applications with the same NestJS flair you know and love.&lt;/p&gt;

&lt;p&gt;But wait, there’s more! Imagine taking these slick CLI apps and running them as jobs in a Kubernetes environment. Sounds like a dream, right? That’s where the &lt;a href="https://github.com/henriqueweiand/nestjs-job-commander" rel="noopener noreferrer"&gt;nestjs-job-commander repository&lt;/a&gt; comes into play. It’s a nifty example showing how to set up a job processing system using NestJS and nest-commander, all within Kubernetes.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore the details of this setup, breaking down the implementation so you can try it out yourself. Let’s get started!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Technologies used 🛠️&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NestJS:&lt;/strong&gt; A progressive Node.js framework for building efficient and scalable server-side applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nest-commander:&lt;/strong&gt; A NestJS module that facilitates the creation of CLI applications with a structure similar to typical NestJS applications. Find out more about it &lt;a href="https://docs.nestjs.com/recipes/nest-commander" rel="noopener noreferrer"&gt;https://docs.nestjs.com/recipes/nest-commander&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeORM:&lt;/strong&gt; An ORM for TypeScript and JavaScript that supports various databases. Find out more about it &lt;a href="https://docs.nestjs.com/recipes/sql-typeorm" rel="noopener noreferrer"&gt;https://docs.nestjs.com/recipes/sql-typeorm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes (k8s):&lt;/strong&gt; An open-source system for automating deployment, scaling, and management of containerized applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monorepo:&lt;/strong&gt; A repository structure that holds multiple projects, allowing for shared code and unified project management. Find out more about it &lt;a href="https://docs.nestjs.com/cli/monorepo" rel="noopener noreferrer"&gt;https://docs.nestjs.com/cli/monorepo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Repository Structure 🗺️&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The repository is organized as a monorepo, containing multiple projects and shared libraries. Key components include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;apps/cli-enricher: The CLI application is built with NestJS and nest-commander.&lt;/li&gt;
&lt;li&gt;libs: Shared libraries utilized by the CLI application.&lt;/li&gt;
&lt;li&gt;k8s: Kubernetes configuration files for deploying the job.&lt;/li&gt;
&lt;li&gt;Dockerfile: Defines the Docker image for the CLI application.&lt;/li&gt;
&lt;li&gt;.env: Environment variables configuration file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this repository, we will get into just one CLI, but you can have as many as you need.&lt;/p&gt;

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

&lt;p&gt;Similar to a traditional NestJS application, an application with NestJS Commander is set up quite simply. In the main.ts we define the bootstrap method&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/main.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/main.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we need to create the AppModule, which will require the base modules like ENV Module, Database connection, and also the module for your CLI, in this case, I just have one, but, if you have more, don't forget to add them here!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/app.module.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/app.module.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AppModule needs to export the main command, that's why there's an export. Opening the &lt;code&gt;CliCommand&lt;/code&gt;, you will notice a base structure for a general CLI command, and the reason it is quite basic is that this project is not using the root command, it is using &lt;code&gt;subCommands&lt;/code&gt;. There's no big reason for that, I decided to use it as a subcommand instead of a root, but I will detail more about it later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/cli-command.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/cli-command.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm going to explain more about how to use the root command at the end of the article, for now, let's stick to the app context. &lt;/p&gt;

&lt;p&gt;Yet inside the CliCommand, we need to define the &lt;code&gt;subCommands&lt;/code&gt;, and then it is necessary to add the command file of that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/cli-command.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/cli-command.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the core of our CLI Enricher. In this file, we define the command name&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@SubCommand&lt;span class="o"&gt;({&lt;/span&gt; name: &lt;span class="s1"&gt;'ticketmaster-event-refresh'&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;TicketMasterEventRefreshCommand&lt;/code&gt; holds the logic of our CLI Job. The job gets the events from the Ticket Master API, verifies whether the event exists or not, and stores it. Again, the logic is not the focus of the post, but how to manage Nest Commander inside the Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/ticketmaster-event-refresh/ticketmaster_event_refresh.command.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander/blob/master/apps/cli-enricher/src/ticketmaster-event-refresh/ticketmaster_event_refresh.command.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;subCommands&lt;/code&gt;, in the end, we will execute it like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--&lt;/span&gt; cli ticketmaster-event-refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the job - outside k8s
&lt;/h3&gt;

&lt;p&gt;In case you need to test the application before putting it inside the k8s, which I strongly recommend. You can do that by running the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nest start &lt;span class="nt"&gt;--watch&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; cli ticketmaster-event-refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ Make sure you have everything that your application needs to run ready, for example, the database instance and the tables. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This project has a &lt;code&gt;how-to-run&lt;/code&gt; section in the &lt;a href="https://github.com/henriqueweiand/nestjs-job-commander" rel="noopener noreferrer"&gt;README&lt;/a&gt; file to help you to run this example locally without any issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running the job - inside k8s
&lt;/h3&gt;

&lt;p&gt;So far, we have a NestJS application with NestJS Commander, and we know that the application works! The next step is putting the app inside a Pod in the k8s, and for that, we will need to create two things!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The docker image;&lt;/li&gt;
&lt;li&gt;Kubeclt file for the cronjob;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the docker image, we only need to run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; ticketmaster-event-refresh-job &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will build the &lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/Dockerfile" rel="noopener noreferrer"&gt;Dockerfile&lt;/a&gt; available at the root level, and this Dockerfile doesn't have anything different from any other NestJS application with docker, but, feel free to take a look.&lt;/p&gt;

&lt;p&gt;Next, change the .env file and add the following envs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CLI-ENRICHER.HOST&lt;span class="o"&gt;=&lt;/span&gt;host.docker.internal
&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we are going to run the app inside the cluster, we need to set the correct host to make it able to reach the database. The NODE_ENV with the production value is required because of the logic for the EnvModule.&lt;/p&gt;

&lt;p&gt;Now, create a config map inside your cluster. Run the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create configmap env-config &lt;span class="nt"&gt;--from-env-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a config map and add the .env variables inside it. We will need the .env to run the application inside the cluster.&lt;/p&gt;

&lt;p&gt;The last step is running the &lt;code&gt;kubeclt&lt;/code&gt; command. Go to the k8s folder and execute&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; cronjob.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case you want to know, the &lt;code&gt;cronjob.yaml&lt;/code&gt; is a spec file to create a job inside the k8s.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-job-commander/blob/master/k8s/cronjob.yaml" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-job-commander/blob/master/k8s/cronjob.yaml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The job is being set to run each minute, and it follows the same sequence of commands as we tested outside the k8s previously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;command&lt;/span&gt;:
  - node
  - dist/apps/cli-enricher/main.js
  - cli
  - ticketmaster-event-refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recorded a video to help you to run everything in case is needed! &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GCfBnEMHVEE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;And there you have it! With &lt;strong&gt;NestJS Commander&lt;/strong&gt; and &lt;strong&gt;Kubernetes&lt;/strong&gt;, you can seamlessly build and deploy CLI applications using the familiar NestJS structure. This setup allows you to manage jobs efficiently, whether running them locally or within a Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;By leveraging &lt;strong&gt;subCommands&lt;/strong&gt;, &lt;strong&gt;Docker&lt;/strong&gt;, and &lt;strong&gt;Kubernetes CronJobs&lt;/strong&gt;, we’ve created a system that can scale and automate job execution while maintaining flexibility. If you’re working on task automation, scheduled jobs, or batch processing, this approach can help you streamline your workflow.&lt;/p&gt;

&lt;p&gt;I mentioned earlier that I’d dive deeper into &lt;strong&gt;root commands&lt;/strong&gt; and &lt;strong&gt;parameter handling&lt;/strong&gt;—don’t worry, that’s coming in a future post! Stay tuned, and in the meantime, feel free to check out the &lt;a href="https://github.com/henriqueweiand/nestjs-job-commander" rel="noopener noreferrer"&gt;nestjs-job-commander repository&lt;/a&gt; and try it yourself.&lt;/p&gt;

&lt;p&gt;Got questions or feedback? Drop a comment or reach out—I’d love to hear your thoughts! 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nestjs</category>
      <category>kubernetes</category>
      <category>node</category>
    </item>
    <item>
      <title>NestJS Vienna Meetup: Multi-Tenancy &amp; Module Management</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Sat, 08 Feb 2025 16:07:23 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/nestjs-vienna-meetup-multi-tenancy-module-management-14p9</link>
      <guid>https://dev.to/nestjs-ninja/nestjs-vienna-meetup-multi-tenancy-module-management-14p9</guid>
      <description>&lt;p&gt;The NestJS community recently gathered in Vienna for an insightful meetup featuring talks on multi-tenancy patterns and module management in NestJS. As the ecosystem continues to evolve, meetups like these play a crucial role in knowledge sharing and community growth. If you missed the event, don’t worry—I'll break down the key takeaways and connect them to a deep dive I previously wrote on multi-tenancy with NestJS and TypeORM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insights from NestJS Vienna
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multi-Tenancy in NestJS – Dustin Chabrowski
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/dustin-chabrowski/" rel="noopener noreferrer"&gt;Dustin Chabrowski&lt;/a&gt; delivered a talk on multi-tenancy patterns in NestJS, a crucial architecture for SaaS applications and enterprise solutions. He explored different approaches, including database-per-tenant, schema-per-tenant, and shared-database strategies. These approaches help businesses scale their applications while maintaining data isolation and performance.&lt;/p&gt;

&lt;p&gt;For those unfamiliar, multi-tenancy is a system where a single application serves multiple tenants (clients), each with its own data segregation strategy. Choosing the right model depends on the complexity of your application, compliance requirements, and expected scalability.&lt;/p&gt;

&lt;p&gt;In my previous blog post, &lt;a href="https://dev.to/henriqueweiand/nestjs-typeorm-and-multi-tenancy-ekl"&gt;NestJS, TypeORM, and Multi-Tenancy&lt;/a&gt;, I discussed how to implement multi-tenancy using TypeORM, covering practical solutions like dynamic database connections, middleware, and request-based context resolution. If you’re looking to implement this in your NestJS app, check it out!&lt;/p&gt;

&lt;h3&gt;
  
  
  Pragmatic Module Management – Maciej Sikorski
&lt;/h3&gt;

&lt;p&gt;Another highlight was &lt;a href="https://www.linkedin.com/in/maciej-sikorski-a01b26149/" rel="noopener noreferrer"&gt;Maciej Sikorski’s&lt;/a&gt; talk on module management in NestJS. He shared strategies for keeping module dependencies under control, which is often an overlooked yet vital aspect of building scalable applications. Managing modules effectively ensures better maintainability, reduced circular dependencies, and improved testability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for the NestJS Community
&lt;/h2&gt;

&lt;p&gt;Both of these topics—multi-tenancy and module management—are fundamental to designing scalable and maintainable NestJS applications. Multi-tenancy enables robust SaaS architectures, while proper module management keeps applications clean and structured. By combining these insights, developers can create well-architected solutions that scale efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;If you missed the meetup, you can still catch up on the talks:&lt;/p&gt;

&lt;p&gt;🎥 &lt;a href="https://www.youtube.com/live/ZxGfAxAE80k" rel="noopener noreferrer"&gt;Video Recording&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📄 &lt;a href="https://slides.com/maciejsikorski/deck-584bdf" rel="noopener noreferrer"&gt;Slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What are your thoughts on multi-tenancy in NestJS? Have you implemented it in your projects? Let’s discuss in the comments!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>tenancy</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Real-time chat with NestJS and Socket.io</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Fri, 24 Jan 2025 17:59:48 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/real-time-chat-with-nestjs-and-socketio-3e6e</link>
      <guid>https://dev.to/nestjs-ninja/real-time-chat-with-nestjs-and-socketio-3e6e</guid>
      <description>&lt;p&gt;Real-time communication is an intriguing topic, and I wanted to share my thoughts on it. I came across one of my old blog posts about micro frontends, where I developed an interface for a micro frontend chat feature that was shared across two other pages. In that project, I focused solely on the front end and interface without addressing the backend or ensuring everything functioned properly. So, what did I do next? I implemented the backend using NestJS with &lt;a href="http://Socket.io" rel="noopener noreferrer"&gt;Socket.io&lt;/a&gt; to facilitate chat functionality among the different pages utilizing the micro frontend chat.&lt;/p&gt;

&lt;p&gt;This is the old micro frontend project &lt;a href="https://dev.to/henriqueweiand/building-a-system-like-lego-with-react-and-micro-frontends-5b49"&gt;Building a system as lego with react and micro frontends&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Before we continue, I wanna let you know that this will be an important year for the blog, I am planning to start publishing more frequent blog posts and even videos! My advice for you is to subscribe to the page and don't miss any new publications or updates!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Target 🎯
&lt;/h3&gt;

&lt;p&gt;I'm building a simple system without much complexity in terms of modules and services to handle the pure and basic functionality of sending and receiving messages among the users connected to the chat.&lt;/p&gt;

&lt;p&gt;Backend project&lt;br&gt;
&lt;a href="https://github.com/henriqueweiand/nestjs-real-time-chat" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-real-time-chat&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Frontend project&lt;br&gt;
&lt;a href="https://github.com/henriqueweiand/nextjs-real-time-chat-with-micro-frontends" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nextjs-real-time-chat-with-micro-frontends&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Starting point
&lt;/h3&gt;

&lt;p&gt;I first created a project by using the &lt;a href="https://docs.nestjs.com/cli/overview" rel="noopener noreferrer"&gt;NestJS CLI&lt;/a&gt;. With the project ready, I make a module  with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nest generate module chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, you can create the module manually if you want. Then, I created one more file called &lt;code&gt;chat-gateway.ts&lt;/code&gt; with the content&lt;br&gt;
&lt;a href="https://github.com/henriqueweiand/nestjs-real-time-chat/blob/master/src/chat/chat-gateway.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-real-time-chat/blob/master/src/chat/chat-gateway.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the chat project, I have a few functionalities in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Notify when a user connects;&lt;/li&gt;
&lt;li&gt;Notify when a user disconnects;&lt;/li&gt;
&lt;li&gt;Broadcast the messages;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's go through some of the methods defined inside the &lt;code&gt;chat-gateway&lt;/code&gt; to detail how the gateway is addressing the features.&lt;/p&gt;

&lt;p&gt;ChatGateway is decorated with the &lt;code&gt;WebSocketGateway&lt;/code&gt;, which words as equal to a provider, which means we also have to add it as a provider inside the chat.module. WebSocketGateway has properties that can be set as needed, and in our case, I allowed the cors to work with any page and I also changed the port (because I wanted to, but it is not necessary). &lt;/p&gt;

&lt;p&gt;ChatGateway is implementing two interfaces, and those interfaces will allow us to implement two methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;handleConnection&lt;/li&gt;
&lt;li&gt;handleDisconnect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The name of the function is pretty self-explanation, right? One deals with new connections to the socket and the other for the disconnections.&lt;/p&gt;

&lt;p&gt;The official documentation about WebSocketGateway is available &lt;a href="https://docs.nestjs.com/websockets/gateways" rel="noopener noreferrer"&gt;https://docs.nestjs.com/websockets/gateways&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  handleConnection
&lt;/h3&gt;

&lt;p&gt;As described in the official documentation:  &lt;a href="https://docs.nestjs.com/websockets/gateways#lifecycle-hooks" rel="noopener noreferrer"&gt;https://docs.nestjs.com/websockets/gateways#lifecycle-hooks&lt;/a&gt; the &lt;code&gt;handleConnection&lt;/code&gt; receives an argument that is the library-specific client socket instance.&lt;/p&gt;

&lt;p&gt;In this example, I am emitting a message to the event &lt;code&gt;user-joined&lt;/code&gt;. Every client that is connected and listening to this event will know that somebody else joined. By the way, &lt;code&gt;broadcast&lt;/code&gt; emits to everybody but the user who is joining, which is perfect for what we need!&lt;/p&gt;

&lt;h3&gt;
  
  
  handleDisconnect
&lt;/h3&gt;

&lt;p&gt;This method also receives the client instance as a parameter, and for this example, the difference is that we are using the WebSocketServer instance to emit a message to everybody connected that someone left on the &lt;code&gt;user-left&lt;/code&gt;event. &lt;/p&gt;

&lt;h3&gt;
  
  
  Dealing with all messages
&lt;/h3&gt;

&lt;p&gt;The method &lt;code&gt;handleNewMessage&lt;/code&gt; is decorated with SubscribeMessage and defines the main event for all the messages. The name of the function could be anything else, ok? Just to let you know. Same here as we did for the disconnect event, we are emitting the message received to everybody.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend
&lt;/h2&gt;

&lt;p&gt;The frontend project as I said previously, is the same as I implemented and described in this post&lt;a href="https://dev.to/henriqueweiand/building-a-system-like-lego-with-react-and-micro-frontends-5b49"&gt;Building a system as lego with react and micro frontends&lt;/a&gt;, so please take a look at the other blog post to get more details about the frontend project. I will just explain where I applied the changes to make the real-time part work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding &lt;a href="http://Socket.io" rel="noopener noreferrer"&gt;Socket.io&lt;/a&gt; to the frontend
&lt;/h3&gt;

&lt;p&gt;This project runs three micro frontends, but there's one that is the chat component and the one that we have to apply the changes. All the changes were applied to this file&lt;br&gt;
&lt;a href="https://github.com/henriqueweiand/nextjs-real-time-chat-with-micro-frontends/blob/master/apps/chat/src/components/Chat/index.tsx" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nextjs-real-time-chat-with-micro-frontends/blob/master/apps/chat/src/components/Chat/index.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The changes made were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;socket.io-client library;&lt;/li&gt;
&lt;li&gt;Initiated the connecting with the port that we defined on the Backend project;&lt;/li&gt;
&lt;li&gt;Added the listening to all events defined on the backend

&lt;ul&gt;
&lt;li&gt;user-joined&lt;/li&gt;
&lt;li&gt;user-left&lt;/li&gt;
&lt;li&gt;message&lt;/li&gt;
&lt;li&gt;newMessage&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Minor changes to remove the old “bot replies”&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;It's quite easy to read the component and understand what is happening there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This blog post was directly to the point and without much complexity. I didn't make an abstraction or anything else; I just created the Chat module and added all that I needed, so I recommend you review the module and gateway according to all your necessities. &lt;/p&gt;

&lt;p&gt;I'm planning to continue this post soon with more details related to other features that are possible to apply to NestJS and Sockets.io&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>socketio</category>
      <category>socket</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Integrate Multiple Payment Gateways in NestJS (With Stripe Example)</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Thu, 23 Jan 2025 12:52:22 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/how-to-integrate-multiple-payment-gateways-in-nestjs-with-stripe-example-54pi</link>
      <guid>https://dev.to/nestjs-ninja/how-to-integrate-multiple-payment-gateways-in-nestjs-with-stripe-example-54pi</guid>
      <description>&lt;p&gt;One of the most common use cases that every project has is integrating and offering ways for the customers to pay for your software, which is quite important, isn't it? &lt;/p&gt;

&lt;p&gt;This post will cover some interesting strategies for making it on the backend with NestJS. A simple level of abstraction will allow your project to integrate with multiple payment gateways and even allow the customer to pay with more than one method! Pretty cool, right?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Before we continue, I wanna let you know that this will be an important year for the blog, I am planning to start publishing more frequent blog posts and even videos! My advice for you is to subscribe to the page and don't miss any new publications or updates!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Backend repository&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend repository&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nextjs-payment-gateway-integration" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nextjs-payment-gateway-integration&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the solution
&lt;/h3&gt;

&lt;p&gt;This solution will implement a few layers to make the payment abstraction clear and reusable. It will perform payments with one or more Payment Gateways, in special with Stripe for the implemented example. I won't focus so much on the details, and more on how the solution works! It's important to mention, that this solution is not the perfect one and of course, it can be implemented in many different ways. There will be possible improvements to the solution that I will be commenting on the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution flow
&lt;/h2&gt;

&lt;p&gt;The request flow starts at the Controller and goes through a few Modules and services. &lt;/p&gt;

&lt;p&gt;A big picture of the solution is:&lt;/p&gt;

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

&lt;p&gt;We are going to go deep down over a few of them to understand the solution starting by the Checkout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checkout
&lt;/h3&gt;

&lt;p&gt;This module is responsible for receiving the input from the controller or any other service that ended up implementing it, and it deals with some important steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/checkout.service.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/checkout.service.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only expose method in this service is &lt;code&gt;processPayments&lt;/code&gt;, which performs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It creates the checkout entity/record in the database. It's important because I want to have a common ID for one or many payments that will be processed;&lt;/li&gt;
&lt;li&gt;It processes each one of the payment inputs individually;&lt;/li&gt;
&lt;li&gt;It gets all successful and failed payments for that checkout;&lt;/li&gt;
&lt;li&gt;It performs the refunds for those successful payments if any payment fails;&lt;/li&gt;
&lt;li&gt;It updates the checkout status;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before understanding the methods that process each one of the payments and the processors, it's important to know that the input that we received on the method &lt;code&gt;processPayments&lt;/code&gt; has one attribute that &lt;code&gt;payments&lt;/code&gt; which receives an array of &lt;code&gt;SpecificPaymentInputs&lt;/code&gt; which allows us to receive multiple formats of inputs. This is an important detail because if any new gateway is integrated, &lt;code&gt;SpecificPaymentInputs&lt;/code&gt; needs to be updated!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/checkout.interfaces.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/checkout.interfaces.ts&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Taking &lt;code&gt;StripePaymentInput&lt;/code&gt; as an example, we have a class that implements an abstraction. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/stripe/dto/stripe-payment.input.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/stripe/dto/stripe-payment.input.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This abstraction requires the class to have two important fields that will be used before by the payment processor to identify the correct processor, they are &lt;code&gt;processorType&lt;/code&gt; and &lt;code&gt;paymentType&lt;/code&gt;, which are enum values also related to the payment gateways supported. In this initial example, I will implement &lt;a href="https://stripe.com/" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt; and a fake/custom voucher integration.&lt;/p&gt;

&lt;p&gt;OK! Let's return to the checkout.service and look at the private method &lt;code&gt;_processOnePayment&lt;/code&gt;. This method is responsible for calling the &lt;code&gt;PaymentProcessor&lt;/code&gt; which we will detail in a bit. Apart from the payment processor, we're just creating an object that holds the main information of the checkout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment processor
&lt;/h3&gt;

&lt;p&gt;The payment processor is the core logic behind external integrations like Stripe and the internal abstractions that deal with the processing itself. You'll notice that the &lt;code&gt;PaymentProcessorsModule&lt;/code&gt; includes the providers for each one of the implementations which is the class that follows the abstracted PaymentProcessor. The module also includes the external modules for the logic of the integrations, for example, the Stripe methods to pay, refund, and so on.&lt;/p&gt;

&lt;p&gt;Our starting point is the &lt;code&gt;_processOnePayment&lt;/code&gt; where we call getProcessor method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentProcessorsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProcessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;processorType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This service and method hold a switch case logic that will map and return the proper processor for the payment informed (&lt;code&gt;SpecificPaymentInputs&lt;/code&gt;). The returned class is the payment processor implementation for the specific payment gateway. Overall, the sequence of steps is something like this:&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/payment-processors/payment-processors.service.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/payment-processors/payment-processors.service.ts&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Stripe payment processor
&lt;/h3&gt;

&lt;p&gt;Each processor has to implement two methods: &lt;code&gt;_pay&lt;/code&gt; and &lt;code&gt;_refund&lt;/code&gt;. By the way, I'm not implementing the _refund part in this project, but, it's important to have in case a payment fails and you have to refund the customer automatically. The definition of the methods above is set inside the abstracted class PaymentProcessor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;_pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaymentData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paymentInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentTransactionResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;_refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentLog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaymentLog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentTransactionFailedResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;These methods aren't exposed, they are the main logic of the integration and they will be used later by an exposed method.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inside each processor we defined the logic with the external library, for example, the Stripe processor is calling the method &lt;code&gt;stripeService.createPaymentIntent&lt;/code&gt; to create the payment, and the same would work for the _refund method. To give you a better idea of the execution flow, let's take a look at the &lt;code&gt;pay&lt;/code&gt; method inside the abstracted class PaymentProcessor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/payment-processors/processors/payment.processor.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/payment-processors/processors/payment.processor.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two things are happening here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it's creating the payment log.&lt;/li&gt;
&lt;li&gt;it's calling the &lt;code&gt;_pay&lt;/code&gt; method implemented by the specific integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The payment log represents things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What we receiving as input;&lt;/li&gt;
&lt;li&gt;What the response was;&lt;/li&gt;
&lt;li&gt;Metadata of the payment/checkout;&lt;/li&gt;
&lt;li&gt;Status of the payment;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is important information for multiple things, for example, we can debug deeply if necessary to understand why a payment failed by looking at the input, response, and metadata; we can retry; we can easily know the payment methods used and their status.&lt;/p&gt;

&lt;p&gt;A big-picture view of the flow described above is&lt;/p&gt;

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

&lt;p&gt;OK! So far, we covered all the payment flow from the controller to the payment integration with the payment gateway! The remaining part is the refund, which happens when one or more payments fail with the payment gateway. Let's return to the service &lt;a href="https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/checkout.service.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-payment-gateway-integration/blob/master/libs/components/checkout/src/checkout.service.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the method &lt;code&gt;processPayments&lt;/code&gt;, after we process every payment informed, after the line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentInputs&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;paymentInput&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_processOnePayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paymentInput&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are filtering out the results to find the payment logs that were &lt;code&gt;failed&lt;/code&gt; and &lt;code&gt;completed&lt;/code&gt;, if we have any payments that failed, then we need to run the refund for all those that were completed. As I mentioned before, I implemented the refund partially, there's only the structure, but the main logic with Stripe, for example, is missing on purpose, I didn't want to go that further on the topic, but the documentation for Stripe's refund is available on &lt;a href="https://docs.stripe.com/api/refunds/create" rel="noopener noreferrer"&gt;https://docs.stripe.com/api/refunds/create&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Some extra notes about the implementation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instead of processing it during the request as we are doing with Promise.all inside the checkout.service, one option would be putting it in a queue and processing on depend. You can also respond after the processing with some kind of socket connected to the front end which is waiting for the response, or any other strategy you want.&lt;/li&gt;
&lt;li&gt;I didn't create a service only for the repository for example the checkout service is doing it and some other things, it would be nice to have a repository class and reduce the responsibility of some of the services.&lt;/li&gt;
&lt;li&gt;Don't take all the implementation too seriously, it's a base example of how to abstract modules and services to have an easy way to integrate with different payment gateways quickly and easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other packages inside libs
&lt;/h3&gt;

&lt;p&gt;You'll notice some libs inside the libs folder that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;env&lt;/li&gt;
&lt;li&gt;logger&lt;/li&gt;
&lt;li&gt;persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't explain them in this article because they are not the focus, but they are modules to deal with the env, logger, and persistence (TypeORM, migrations). They are useful modules that I use from time to time on my blog posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running frontend and backend project
&lt;/h3&gt;

&lt;p&gt;This article includes both frontend and backend projects with the Stripe integration to show the project working. In the example you can inform the Stripe card and a voucher, simulating everything that we implemented in this article.&lt;/p&gt;

&lt;p&gt;If you want to run the projects, please follow the instructions for each one.&lt;/p&gt;

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

&lt;p&gt;That's all for today! Don't forget to subscribe to follow the following post that is about to be released!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>stripe</category>
      <category>payments</category>
      <category>node</category>
    </item>
    <item>
      <title>NestJS TypeORM and Multi-Tenancy</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Sat, 14 Dec 2024 12:57:41 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/nestjs-typeorm-and-multi-tenancy-ekl</link>
      <guid>https://dev.to/nestjs-ninja/nestjs-typeorm-and-multi-tenancy-ekl</guid>
      <description>&lt;p&gt;Not so different from any other ordinary type of project, multi-tenancy is a software architecture that has been in place for quite a while, and as with any other approach, there are pros and cons. In this article, I plan to walk you through a simple solution I implemented to tackle basic architecture inside the universe of the NestJS framework with TypeORM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;I've been studying and trying new approaches whenever something pops up and I wonder how to do that technically, or when I found something cool! I've written a few articles with this idea in mind, and this one is no different! I was talking to my brother the other day and he is planning to migrate a project that runs with PHP to node and he asked me if I knew an example of multi-tenancy with NestJS. Despite being in the technology for a while, I worked on something with C++ in the past but not with Node or NestJS. In the end, it wasn't a problem, I took it as my new study subject and tried it! &lt;/p&gt;

&lt;p&gt;The final code is available on the link below on GitHub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don’t describe the details in this article, just the overview and how the application works according to the target, which is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NestJS project;&lt;/li&gt;
&lt;li&gt;Multiple databases, one for each customer;&lt;/li&gt;
&lt;li&gt;Use TypeORM to deal with the database connection;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Multi-tenancy
&lt;/h3&gt;

&lt;p&gt;Let me start by saying that multi-tenancy has different types, some of them are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A single application, single database;&lt;/li&gt;
&lt;li&gt;A single application, multiple database;&lt;/li&gt;
&lt;li&gt;Multiple applications, multiple databases;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;You can find more details about the concept online. (&lt;a href="https://bit.ly/4g8wmDN" rel="noopener noreferrer"&gt;What is multi-tenancy (multi-tenant architecture&lt;/a&gt;)).&lt;/p&gt;

&lt;p&gt;In case you want to know, this project uses a single application and multiple databases. 🎯&lt;/p&gt;

&lt;h2&gt;
  
  
  Developing
&lt;/h2&gt;

&lt;p&gt;Before I started, I researched NestJS packages, existing libraries, public projects, and articles and I found a few interesting contents, for example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/logeek/nestjs-and-typeorm-efficient-schema-level-multi-tenancy-with-auto-generated-migrations-a-dx-approach-jla"&gt;https://dev.to/logeek/nestjs-and-typeorm-efficient-schema-level-multi-tenancy-with-auto-generated-migrations-a-dx-approach-jla&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mguay22/nestjs-multitenancy" rel="noopener noreferrer"&gt;https://github.com/mguay22/nestjs-multitenancy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;None of them matched exactly what I needed, which motivated me to continue and implement it, and in the end, I got some shared knowledge from all the materials and included them into my project version. &lt;/p&gt;

&lt;p&gt;The project has two main folders that are essential for the idea. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/src/libs/database&lt;/li&gt;
&lt;li&gt;/src/libs/tenancy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Database
&lt;/h3&gt;

&lt;p&gt;Starting with the database, it is important to note that the service implements OnModuleInit, which executes a logic when the app starts and the service is instantiated. What I implemented consists of the following sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;App starts;&lt;/li&gt;
&lt;li&gt;The app initiates a default DB connection;&lt;/li&gt;
&lt;li&gt;This instance gets the data from a default database and table tenant which holds the database information for all the customers;&lt;/li&gt;
&lt;li&gt;This connection verifies if each database from the data is created and if so, it runs the migrations over the customer's database, otherwise, it creates a new database and also runs the migrations over it.&lt;/li&gt;
&lt;li&gt;An exclusive Data source is created for each one of the databases and stored in memory;&lt;/li&gt;
&lt;li&gt;Close the default connection (this connection is different from the other databases);&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The low point of this approach is that the app won't verify if new databases were created unless the app is restarted. I didn't want to focus on this, so I left this improvement open on the project. Feel free to help with 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All this logic is happening inside the &lt;a href="https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/libs/database/database.service.ts" rel="noopener noreferrer"&gt;database.service.ts&lt;/a&gt; in case you want to check it out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/libs/database/database.service.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/libs/database/database.service.ts&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tenancy
&lt;/h3&gt;

&lt;p&gt;Despite being a simple module if you take a look, it's a crucial part of the project and it put everything together! &lt;/p&gt;

&lt;p&gt;This module uses the library &lt;a href="https://github.com/Papooch/nestjs-cls" rel="noopener noreferrer"&gt;nestjs-cls&lt;/a&gt;, which is "A continuation-local storage module compatible with NestJS' dependency injection based on AsyncLocalStorage". You also can use the node implementation with async_hooks if you want. The module gets the &lt;code&gt;tenant-id&lt;/code&gt; from the request and adds it to the local storage which makes the info available through the request lifecycle.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Continuation-local storage allows to store state and propagate it throughout callbacks and promise chains. It allows storing data throughout the lifetime of a web request or any other asynchronous duration. It is similar to thread-local storage in other languages.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/libs/tenancy/tenancy.module.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/libs/tenancy/tenancy.module.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, with all that in place, one method inside the database.service.ts, will help us to connect the repositories later to the right database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Get the data source for the current tenant
 */&lt;/span&gt;
&lt;span class="nf"&gt;getDataSource&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;tenantId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TENANT_KEY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tenantConnections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tenantId&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;it will get the &lt;code&gt;tenant-id&lt;/code&gt; from the local storage as explained before and also the connection from the variable in memory&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡Speaking of memory, another possible improvement for the future is, making this memory part available in a cache layer or somewhere else, otherwise, if you scale the application the connection won't be shared, but each application will have its own. It is not a big deal, but it is a nice to have.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Connecting a repository to the database
&lt;/h2&gt;

&lt;p&gt;Different from the normal way of using TypeORM, I mean, by using the &lt;code&gt;forFeature&lt;/code&gt; method, etc, in this case, you need to do something a bit different. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/components/users/users.service.ts" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/src/components/users/users.service.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;DatabaseModule&lt;/code&gt; module added to your Module, you can import the Database service and call&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;databaseService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDataSource&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getRepository&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line will return an instance of the correct database according to the &lt;code&gt;tenant-id&lt;/code&gt; from the header and the User repository to use as needed. &lt;/p&gt;

&lt;p&gt;And that's all my friends! We did it!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Generating migrations
&lt;/h2&gt;

&lt;p&gt;This project is set up in a way that you can use the TypeORM generate command! After making any change in the entities, you can run &lt;code&gt;yarn typeorm:generate&lt;/code&gt;, and it will generate the migrations for you. You won't need to run with another command, because the application will run for you once it starts because of the &lt;code&gt;migrationsRun: true&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;In the readme file, you can find a section about how to run the application&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/README.md" rel="noopener noreferrer"&gt;https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/README.md&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this article, we explored a practical implementation of multi-tenancy using NestJS and TypeORM. The solution demonstrates how to handle multiple databases for different customers while maintaining a clean and organized codebase.&lt;/p&gt;

&lt;p&gt;The key achievements of this implementation include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Successfully setting up a NestJS project with multiple database support&lt;/li&gt;
&lt;li&gt;Creating a system that manages database connections for each customer&lt;/li&gt;
&lt;li&gt;Implementing database migrations and proper connection handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this implementation provides a solid foundation, there are opportunities for improvement, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding real-time database verification without requiring app restart&lt;/li&gt;
&lt;li&gt;Implementing a caching layer for better connection management across scaled applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, this approach offers a practical solution for implementing multi-tenancy in NestJS applications while maintaining flexibility and scalability.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>typeorm</category>
      <category>tenant</category>
      <category>multitenancy</category>
    </item>
    <item>
      <title>Mastering NestJS: Building Scalable Systems with Abstractions, ex: different databases</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Fri, 15 Mar 2024 20:43:26 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/mastering-nestjs-building-scalable-systems-with-abstractions-ex-different-databases-5cen</link>
      <guid>https://dev.to/nestjs-ninja/mastering-nestjs-building-scalable-systems-with-abstractions-ex-different-databases-5cen</guid>
      <description>&lt;p&gt;Hello, developers! Welcome to the second part of our NestJS + Clean Architecture + DDD series. In this post, we’ll delve into abstractions and explore how they can be used to create scalable systems that are agnostic to any technology. We’ll use Mongo and Postgres databases as examples to demonstrate this. The goal is to provide strategies that can elevate your application to the next level.&lt;/p&gt;

&lt;p&gt;I’ve received much feedback and numerous valuable comments. Thanks to everyone for your support in advance.❤️&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja/mastering-nestjs-unleashing-the-power-of-clean-architecture-and-ddd-in-e-commerce-development-97850131fd87" rel="noopener noreferrer"&gt;&lt;strong&gt;Mastering NestJS: Unleashing the Power of Clean Architecture and DDD in E-commerce Development —…&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement an abstraction
&lt;/h2&gt;

&lt;p&gt;Before diving into the code, let’s discuss the concept and its application. We’ll consider two examples: Stripe integration and database usage. These examples are relevant as an e-commerce entity may have multiple payment integrations and may wish to change or alternate between them in the future. Similarly, the technical team may decide to switch the database from non-relational to relational, or vice versa. Abstractions help us structure the code, ensuring changes are not overly complex or challenging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database case
&lt;/h2&gt;

&lt;p&gt;Inside a project with Clean architecture, the database (data persistency) is located in the most external layer, so we have to consider this Persistence as something that can’t influence the domain or any other layer, it must be something independent that is there to save, get and manage the data from the database.&lt;/p&gt;

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

&lt;p&gt;Our Persistence module is located in &lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/tree/master/src/infra/persistence" rel="noopener noreferrer"&gt;infra/persistence&lt;/a&gt;. As I explained, this project has two different databases (for a better exemplification), so this is a simple module, which receives parameters according to the interface, that will be used inside the register method.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface DatabaseOptions {
    type: 'prisma' | 'mongoose';
    global?: boolean;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/blob/master/src/infra/persistence/persistence.module.ts" rel="noopener noreferrer"&gt;(full code)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is basically a wrapper class that has both modules, if you want to use Postgres or Mongo. The register will return a DynamicModule which can be used as a normal module. You can check it out in &lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/blob/master/src/app.module.ts" rel="noopener noreferrer"&gt;app.module.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, nothing new, or almost nothing new… We will see some similarities when opening &lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/blob/master/src/infra/persistence/mongoose/mongoose.module.ts" rel="noopener noreferrer"&gt;MongooseModule&lt;/a&gt; and &lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/blob/master/src/infra/persistence/prisma/prisma.module.ts" rel="noopener noreferrer"&gt;PrismaModule&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The providers are the same! I mean, they provide attributes for each one of the objects inside providers. Let's take a look at one as example&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Order } from "@app/domain/ecommerce/order";

export abstract class OrderRepository {
    abstract findMany(): Promise&amp;lt;Order[]&amp;gt;;
    abstract findById(id: string): Promise&amp;lt;Order&amp;gt;;
    abstract create(data: Order): Promise&amp;lt;Order&amp;gt;;
    abstract update(id: string, data: Order): Promise&amp;lt;Order&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we introduce an abstract class that standardizes data from any database type. We also use the Domain definition, which defines a class and its properties.&lt;/p&gt;

&lt;p&gt;The attribute useClass in each module represents the class that implements this abstraction, adhering to input and output definitions.&lt;/p&gt;

&lt;p&gt;This is one approach to creating a scalable, agnostic, and flexible persistence solution. For instance, each module will contain library elements related to the ORM, located only on the external layer of our graph. Subsequent use cases will utilize the exported repositories without needing to distinguish between databases, focusing solely on the data. Quite magical! 🧙‍♀️&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am not going to cover the code inside the Persistence module, because it is only the implementations of the entities and the responses by the respositories. Using the domain declarations inside the mappers of course.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am going to cover more details of the database implementations soon in another post. Keep an eye on the community → &lt;a href="https://medium.com/nestjs-ninja" rel="noopener noreferrer"&gt;https://medium.com/nestjs-ninja&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Envs, HTTP, Payment, and any other
&lt;/h2&gt;

&lt;p&gt;The infra folder has other external layers and you can check out them &lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/tree/master/src/infra" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Persistence and Payment have a similar structure where I tried to explain the core of the usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting the layers
&lt;/h2&gt;

&lt;p&gt;In the previous post we went through an explanation of the layers being connected, so please take a look before diving deep into this new section (&lt;a href="https://medium.com/nestjs-ninja/mastering-nestjs-unleashing-the-power-of-clean-architecture-and-ddd-in-e-commerce-development-97850131fd87" rel="noopener noreferrer"&gt;Previous post&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The high-level explanation of the flow is&lt;/p&gt;

&lt;h2&gt;
  
  
  Controller → Use case → Entities
&lt;/h2&gt;

&lt;p&gt;Breaking a little bit, it would be like this&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/app.module.ts" rel="noopener noreferrer"&gt;app.module.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/application/ecommerce/ecommerce.module.ts" rel="noopener noreferrer"&gt;ecommerce.module.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/infra/http/http.module.ts" rel="noopener noreferrer"&gt;http.module.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/infra/http/product.controller.ts" rel="noopener noreferrer"&gt;product.controller.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/application/ecommerce/use-case/create-product.ts" rel="noopener noreferrer"&gt;use-case/create-product.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And looking at the use-case part we can see the data usage, logic, and many things happening, for example&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Order } from '@app/domain/ecommerce/order';
import { Injectable } from '@nestjs/common';
import { OrderRepository } from '../ports/order.repositoy';
import { OrderProduct } from '@app/domain/ecommerce/order-product';

interface CreateOrderUseCaseCommand {
  user: string,
  orderProduct: Pick&amp;lt;OrderProduct, 'product' | 'price'&amp;gt;[]
}

@Injectable()
export class CreateOrderUseCase {
  constructor(
    private orderRepository: OrderRepository,
  ) { }

  async execute({
    user,
    orderProduct
  }: CreateOrderUseCaseCommand): Promise&amp;lt;Order&amp;gt; {
    let total = 0;
    const order = new Order({
      user,
    })

    const createdOrderProduct = orderProduct.map((product) =&amp;gt; {
      total += product.price;

      return new OrderProduct({
        product: product.product,
        price: product.price,
      });
    });

    order.total = total;
    order.orderProduct = createdOrderProduct;

    const createdOrder = await this.orderRepository.create(order)
    const response = await this.orderRepository.findById(createdOrder.id);

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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/nestjsninja/nestjs-ecommerce/blob/master/src/application/ecommerce/use-case/create-order.ts" rel="noopener noreferrer"&gt;(full code)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this use-case, we are creating an order, so we have the input and inside the constructor, we are declaring the repository. Before we call the repository methods, we prepare the information according to the Domain and the abstraction. There’s also some logic that calculates the total price of the order.&lt;/p&gt;

&lt;p&gt;Here, we have a clear usage of the classes that represent the Domain, which also defines the way that the abstractions understand the interactions. Since our Domain is the main point of the whole application, it helps us to keep the data transition in harmony and flexible to be used and changed when necessary.&lt;/p&gt;

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

&lt;p&gt;We’ve completed another section of the article. Regardless of whether you’re using DDD, Clean Architecture, or any other approach, NestJS’s ability to abstract is a powerful tool. It can help us build well-structured, flexible modules with a low level of coupling. I hope this main idea has come across clearly in this part.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://medium.com/nestjs-ninja" rel="noopener noreferrer"&gt;https://medium.com/nestjs-ninja&lt;/a&gt; is a free and open community. If you have a post you’d like to link to the community, please let me know! Let’s contribute to the ecosystem together. You’re welcome to share not just case studies, but also real experiences that can provide value to all readers.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>nestjs</category>
      <category>cleancode</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Mastering NestJS: Unleashing the Power of Clean Architecture and DDD in E-commerce Development — part 1</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Sat, 09 Mar 2024 19:44:30 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/mastering-nestjs-unleashing-the-power-of-clean-architecture-and-ddd-in-e-commerce-development-part-1-5b7h</link>
      <guid>https://dev.to/nestjs-ninja/mastering-nestjs-unleashing-the-power-of-clean-architecture-and-ddd-in-e-commerce-development-part-1-5b7h</guid>
      <description>&lt;p&gt;Hello, dev! Let’s start one more sequence of exciting technical posts related to the NestJS ecosystem, and in this sequence, I am going to review and exercise with you concepts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;Clean Architecture;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design" rel="noopener noreferrer"&gt;DDD&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea is to only go through some parts of the application, ok? I recommend this post for those who have some knowledge about NestJS already and want to see &amp;amp; apply a different architectural approach to have applications with as little coupling as possible.&lt;/p&gt;

&lt;p&gt;There’s another post that I wrote in the past, that also applied this approach of less coupling. If you want to take a look the link is&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja/creating-smart-questions-with-nestjs-and-openai-83089829cdf5" rel="noopener noreferrer"&gt;&lt;strong&gt;Creating Smart Questions with NestJS and OpenAI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is going to be the project?
&lt;/h2&gt;

&lt;p&gt;This is a simple project that represents part of an e-commerce ecosystem. We are going to design a solution with four basic entities, they are&lt;/p&gt;

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

&lt;p&gt;Plus, we will integrate this solution with the Stripe payment platform and a Cache layer for the GET endpoints to respond faster! 🏃🏻‍♂️💨&lt;/p&gt;

&lt;h2&gt;
  
  
  Start 🎬
&lt;/h2&gt;

&lt;p&gt;For this project, I am going to use a few different technologies for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I want to share how Clean Architecture can help a project not rely on the technology; For example, if you want to change the database, or payment provider… it is going to be very simple.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To have a clear project pattern applied;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The technologies are going to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;NestJS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MongoDB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Postgres&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SWC&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am starting this project, following the same steps that I have shown in this post (I just skipped the deploy step)&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja/implementing-auth-flow-as-fast-as-possible-using-nestjs-bdf87488bc00" rel="noopener noreferrer"&gt;&lt;strong&gt;Implementing auth flow as fast as possible using NestJS&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the project created and the setup done, we can organize the folders and the main files. The final version is gonna be like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assets
├── prisma
└── src
    ├── application
    │   └── ecommerce
    │       ├── ports
    │       └── use-case
    ├── core
    │   └── entities
    ├── domain
    │   └── ecommerce
    └── infra
        ├── env
        ├── http
        │   └── dto
        ├── payment
        │   └── stripe
        └── persistence
            ├── cache
            │   └── interceptor
            ├── mongoose
            │   ├── entities
            │   ├── mapper
            │   └── repositories
            └── prisma
                ├── mapper
                └── repositories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To start with something visual, let’s start with the infra/http This HTTP, represents one of the external layers that compound the architecture, so, everything related to external technologies, for example, databases, presenters, and libraries, will be inside this folder.&lt;/p&gt;

&lt;p&gt;To make things clear, we are following this diagram. (don’t worry about everything else yet)&lt;/p&gt;

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

&lt;p&gt;As HTTP is a module, let’s create a module and its related files&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http
├── app.controller.ts
├── checkout.controller.ts
├── dto
│   ├── create-order-product.dto.ts
│   ├── create-order.dto.ts
│   ├── create-product.dto.ts
│   └── create-user.dto.ts
├── http.module.ts
├── order.controller.ts
├── product.controller.ts
├── user.controller-e2e-spec.ts
└── user.controller.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This is the final version with everything inside, but you can start off with the http.module.ts and product.controller.ts.&lt;/p&gt;

&lt;p&gt;The module is pretty simple, he initially is going to have the product.controller declared in it and speaking about the product.controller, you can create a simple GET method just to have something in it as well. (you can find the final version &lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/infra/http/http.module.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;With the HTTP module created, you can add it to the app.module and make things work.&lt;/p&gt;
&lt;h2&gt;
  
  
  Domain entities 🎨
&lt;/h2&gt;

&lt;p&gt;As you might have seen, we have a folder called src/domain/ecoomerce, and in there we are declaring the classes that will represent the three entities that I mentioned in the beginning.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ecommerce
    ├── order-product.ts
    ├── order.ts
    ├── product.ts
    └── user.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Each one is a Class and has its properties, for example, products&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
In this case, I am declaring a Product class and this domain contains fields, they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;id (optional, because at the moment of creating the record still doesn’t have value)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;title&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;price&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other entities 🦿
&lt;/h2&gt;

&lt;p&gt;The other entities are kind of similar to the Product, however, if we take a look at Order, we will see that this one has a relation to others like orderProduct.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Entity } from "@app/core/entities/entity";
import { OrderProduct } from "./order-product";

export interface OrderProps {
    id?: string;
    user: string
    total?: number
    status?: "paid" | "open" | "canceled"
    paymentId?: string,
    paymentMethod?: "stripe" | "paddle" | "paypal" | "other", // It is only working with stripe for now
    orderProduct?: OrderProduct[]
}

export class Order extends Entity&amp;lt;OrderProps&amp;gt; {
    constructor(props: OrderProps) {
        props.total = props.total ?? 0;
        props.status = props.status ?? "open";

        super(props);
    }

    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;(The final folder with all the entities → &lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/tree/master/src/domain/ecommerce" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The reason for those relations is simple, an order in this context has one or more products. One more detail that this entity knows can be seen in the construction method. If this Domain is declared without total and status defined, it will assume 0 as price and “open” as status. We could have more methods or conditions that we understand are correct for the domain if that is the case, okay?&lt;/p&gt;

&lt;p&gt;Just to reinforce, when we talk about Domain, we are referring to the main layer of the diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k5xo262yinywil2btmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k5xo262yinywil2btmy.png" width="107" height="109"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Connecting the layers 🥗
&lt;/h2&gt;

&lt;p&gt;Following the diagram, we have to follow the sequence:&lt;/p&gt;
&lt;h2&gt;
  
  
  Controller → Use case → Entities
&lt;/h2&gt;

&lt;p&gt;During usage, we can use anything from the external layer in order to execute the logic, and all of this is held in the use case, so we are going to connect the layers inside the HTTP + Use cases, especially because of the dependency injection that NestJS has.&lt;/p&gt;

&lt;p&gt;Check out this final version of the http.module&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
As I said, we have the Controllers that are going to receive the use cases, and the use cases rely on the Payment module and Database module. One detail, The Database module is declared as global , and for that reason, it is not included here. The database module is declared in the app.module like this final version &lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/app.module.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 It is important to understand the dependency injection and the module strategy that NestJS applied to understand the most from this example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To have a better understanding of all of these, let’s see the following files&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/app.module.ts" rel="noopener noreferrer"&gt;app.module.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/application/ecommerce/ecommerce.module.ts" rel="noopener noreferrer"&gt;ecommerce.module.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/infra/http/http.module.ts" rel="noopener noreferrer"&gt;http.module.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/infra/http/product.controller.ts" rel="noopener noreferrer"&gt;product.controller.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/henriqueweiand/nestjs-ecommerce/blob/master/src/application/ecommerce/use-case/create-product.ts" rel="noopener noreferrer"&gt;use-case/create-product.ts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the flow that the request follows when it is requested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion 👨🏼‍🏫
&lt;/h2&gt;

&lt;p&gt;We have covered a bunch of parts of this application and concepts so far, and as I said, it is a sequence of posts. For the next one, we are going to see and understand more about abstractions how to create a module, service, and functionality with as little coupling as possible. The idea is to apply this technique for the use cases and the repositories that later are going to persist the information in the database.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>cleancode</category>
      <category>ddd</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Empowering Language Learning with NestJS, NextJS, Vercel, and Neon.tech: A Tech-Infused Journey</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Fri, 08 Mar 2024 21:11:03 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/empowering-language-learning-with-nestjs-nextjs-vercel-and-neontech-a-tech-infused-journey-14j</link>
      <guid>https://dev.to/nestjs-ninja/empowering-language-learning-with-nestjs-nextjs-vercel-and-neontech-a-tech-infused-journey-14j</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftatb51f26az8s57v6gqy.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftatb51f26az8s57v6gqy.jpeg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Empowering Language Learning with NestJS, NextJS, Vercel, and Neon.tech: A Tech-Infused Journey
&lt;/h2&gt;

&lt;p&gt;Hi everybody, how’s it going?&lt;/p&gt;

&lt;p&gt;Today’s post is going to be a bit different. I want to share the journey that I have been taking related to the process of learning a new language and how technology can be connected to it. I know that everyone here likes technology, and for that reason, I am going to talk about two projects that I have done that are open-source and come to give the word something back in terms of education. I don’t want to give any spoilers already, but that’s going to be the main point! Grab a coffee or a lovely cup of tea and enjoy the text!&lt;/p&gt;

&lt;p&gt;As someone who isn’t a native English speaker and comes from Brazil, I’ve been on a journey to learn English for some time now. I’ve tried various things like apps, books, classes, podcasts, videos, and movies. Each of these resources has been helpful in its own way, and there are a few that I stick to every day. Learning a language isn’t easy, but one thing I’ve learned is the importance of sticking to what works for you and giving it time because learning is a process, right?&lt;/p&gt;

&lt;p&gt;As I explored different ways to learn languages, I felt something inside me growing. It took me a while to understand, but eventually, I realized what it was. Being a developer, I saw how these tools helped me reach an important goal. That’s when I decided to give back to the world. So, I started creating open-source projects that mix technology and education. One of them is a flashcard app for learning languages with OpenAI.&lt;br&gt;
&lt;a href="https://medium.com/@henrique.weiand/flash-cards-apps-with-chatgpt-1bf698a2dc30" rel="noopener noreferrer"&gt;&lt;strong&gt;Flash-cards app with OpenAI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another was a question generator, also using OpenAI.&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja/creating-smart-questions-with-nestjs-and-openai-83089829cdf5" rel="noopener noreferrer"&gt;&lt;strong&gt;Creating Smart Questions with NestJS and OpenAI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there’s one more that I haven’t written about yet, but it is online as a platform and also available to contribute or download for free. The website is &lt;a href="https://quiz-english.com/" rel="noopener noreferrer"&gt;quiz-english.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://quiz-english.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Quiz-English: Learn English by doing quizzes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is a platform where there are many different quizzes about many different subjects, but the main point here is, as I am a heavy user of podcasts, every podcast that I listen to that is a public transcription, I can convert to a quiz using OpenAI, it helps me to exercise the retention of the information from the podcast.&lt;/p&gt;

&lt;p&gt;If you’re on a similar journey to learn a new language or just passionate about education and technology, I encourage you to check out these projects. They might be the resources you’ve been looking for!&lt;/p&gt;

&lt;h3&gt;
  
  
  Projects and technologies
&lt;/h3&gt;

&lt;p&gt;In my projects, I’ve employed a variety of technologies such as NestJS, NextJS, React-Native, Postgres, Mongo, and more. Each technology has its pros and cons, but in my experience, I’ve found that if you’re looking to quickly bring your idea to life, Vercel and NextJS are excellent choices. With Vercel, you can host both the backend and frontend closer together, and easily integrate with services like Postgres or Mongo — all without any cost! &lt;a href="https://quiz-english.com/" rel="noopener noreferrer"&gt;Quiz-English.com&lt;/a&gt; is a prime example of this approach. Here’s a rundown of the technologies powering the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; (Host)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt; (Repository)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt; (Frontend and backend)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://Neon.tech" rel="noopener noreferrer"&gt;Neon.tech&lt;/a&gt; (Postgres database)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://clerk.com/" rel="noopener noreferrer"&gt;Cleark&lt;/a&gt; (Auth provider)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plans
&lt;/h3&gt;

&lt;p&gt;In the future, I aim to continue sharing my insights and experiences through technical blog posts on platforms like &lt;a href="https://medium.com/@henrique.weiand" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; and &lt;a href="https://dev.to/henriqueweiand"&gt;dev.to&lt;/a&gt;. My goal is to provide more real-world examples, use cases, and interesting topics that can benefit others in the tech community. Additionally, I’ve initiated a community centered around NestJS called NestJS Ninja, which you can find on Medium. Through this community, I hope to foster the growth of the JavaScript ecosystem and promote NestJS as a versatile framework.&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja" rel="noopener noreferrer"&gt;&lt;strong&gt;NestJS Ninja&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In conclusion, my journey in exploring language learning through technology has led me to develop projects like &lt;a href="https://quiz-english.com/" rel="noopener noreferrer"&gt;Quiz-English.com&lt;/a&gt; and embrace a variety of technologies like NextJS and Vercel. As I continue to share my experiences and insights through platforms like &lt;a href="https://medium.com/@henrique.weiand" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; and &lt;a href="https://dev.to/henriqueweiand"&gt;dev.to&lt;/a&gt;, I’m excited to contribute to the tech community and promote the growth of frameworks like NestJS through initiatives such as NestJS Ninja. I invite you to join me on this journey of learning, collaboration, and innovation. Together, let’s explore the endless possibilities that technology offers for education and beyond.&lt;/p&gt;

&lt;p&gt;🔭 If you have any posts to contribute to the community, please let me know!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>nextjs</category>
      <category>learning</category>
      <category>language</category>
    </item>
    <item>
      <title>Mastering Error Tracking: A Beginner’s Guide to Sentry in Your NestJS Project</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Mon, 20 Nov 2023 11:49:52 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/mastering-error-tracking-a-beginners-guide-to-sentry-in-your-nestjs-project-2glj</link>
      <guid>https://dev.to/nestjs-ninja/mastering-error-tracking-a-beginners-guide-to-sentry-in-your-nestjs-project-2glj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ad266l4dke04zq4wq1v.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ad266l4dke04zq4wq1v.jpeg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello fellow coders!&lt;/p&gt;

&lt;p&gt;The topic today is extremely important, it is something simple but can be a game change when we are running a service on production and suddenly, the users are having problems, errors, etc.&lt;/p&gt;

&lt;p&gt;We are going to have a hands-on example of implementing an error track inside a NestJS project, we are going to use Sentry as a tool to help us see and be ahead of the problem before they are properly reported by the users.&lt;br&gt;
&lt;a href="https://sentry.io/welcome/" rel="noopener noreferrer"&gt;&lt;strong&gt;Application Performance Monitoring &amp;amp; Error Tracking Software&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should I use a tool like that inside my project?
&lt;/h2&gt;

&lt;p&gt;There are many reasons, but the most important one is “to know the error with details in advance before they are reported”.&lt;/p&gt;

&lt;p&gt;Imagine that you have lots of microservices or even a large code base, many times a difficult large codebase, and eventually, bugs happen! Some bugs, sometimes require the context or the parameters to be able to simulate. Sometimes you have so many errors that you don’t know which one is the priority, or in which frequency they happen. So many different cases right? That’s why I always put a tool like that into my projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other options
&lt;/h2&gt;

&lt;p&gt;You can find easily many tools that do almost the same as Sentry, some are cool, some are easy to set up, some don’t have a nice view or require more of you to set up… I always choose Sentry or New Relic, but mostly Sentry because they solve my problems very well.&lt;/p&gt;

&lt;p&gt;Other options are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Da&lt;/strong&gt;tadog&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New Relic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elastic Observability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dynatrace&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AppDynamics&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting the project up
&lt;/h2&gt;

&lt;p&gt;For those who never read my articles, I am going to follow the basic setup from this post&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja/implementing-auth-flow-as-fast-as-possible-using-nestjs-bdf87488bc00" rel="noopener noreferrer"&gt;&lt;strong&gt;Implementing auth flow as fast as possible using NestJS&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because I want to run this project with SWC and the correct tsconfig configuration. Don’t worry, you can find the whole codebase at the end of this post as well.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest g application nestjs-sentry-configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Sentry account
&lt;/h2&gt;

&lt;p&gt;Visit the website &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;https://sentry.io/&lt;/a&gt; and create your account.&lt;/p&gt;

&lt;p&gt;Then, let’s create a new project and select Node.JS&lt;/p&gt;

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

&lt;p&gt;Install the dependencies and copy the DSN value.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save @sentry/node @sentry/profiling-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;p&gt;Now let’s go back to the NestJS project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an ExceptionFilter
&lt;/h2&gt;

&lt;p&gt;I am going to create an Exception called sentry.filter.ts. If you want to learn more about Exceptions and how they are handling inside the NestJS, check out this link&lt;br&gt;
&lt;a href="https://docs.nestjs.com/exception-filters" rel="noopener noreferrer"&gt;&lt;strong&gt;Documentation | NestJS - A progressive Node.js framework&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My exception file will be like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import * as Sentry from '@sentry/node';

@Catch()
export class SentryFilter extends BaseExceptionFilter {
    catch(exception: unknown, host: ArgumentsHost) {
        Sentry.captureException(exception);
        super.catch(exception, host);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is an ordinary exception and we are also extending the BaseExceptionFilter, because I want to keep the original Exception response as soon as the error is tracked. I was doing it when I called.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;super.catch(exception, host);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Is important to notice that our @Catch() is empty, it will make that this Exception handles every exception that can happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an exception to the global scope
&lt;/h2&gt;

&lt;p&gt;We need to add the Custom exception to the project, and we can do that by editing the main.ts&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import * as Sentry from '@sentry/node';
import { SentryFilter } from './sentry.filter';
import { AppModule } from './app.module';

async function bootstrap() {
  Sentry.init({
    dsn: process.env.SENTRY_DNS,
  });

  const app = await NestFactory.create(AppModule);
  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new SentryFilter(httpAdapter));

  await app.listen(3000);
}
bootstrap();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Please, don’t forget to put the SENTRY_DNS value! Otherwise, it won't work as we want.&lt;/p&gt;

&lt;p&gt;And we are done!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the changes
&lt;/h2&gt;

&lt;p&gt;First, let’s start the project&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A simple example can be an error like&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    throw new Error('Ops, theres a problem!');
    return 'Hello World!';
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I am forcing an error, and after requesting the route of this method, I got this report&lt;/p&gt;

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

&lt;p&gt;Here you can find for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How many times this issue happens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Plus (optional)
&lt;/h2&gt;

&lt;p&gt;If you want to implement it as a module and use dependency injecting etc to get more from the errors, and also to have it global, you can do it using the example below as a starting point.&lt;/p&gt;

&lt;p&gt;“Binding interceptiors” &lt;a href="https://docs.nestjs.com/interceptors#binding-interceptors" rel="noopener noreferrer"&gt;https://docs.nestjs.com/interceptors#binding-interceptors&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;More examples of using different approaches&lt;/p&gt;

&lt;p&gt;&lt;a href="https://abrialstha.medium.com/sentry-integration-with-nestjs-7f967c5cc8ab" rel="noopener noreferrer"&gt;Sentry Integration With NestJS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ericjeker/nestjs-sentry-example" rel="noopener noreferrer"&gt;https://github.com/ericjeker/nestjs-sentry-example&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;It’s been easy to add Sentry or any other Error tracker, and knowing how important it is for any project, I would suggest you add it right now 😄&lt;/p&gt;

</description>
      <category>sentry</category>
      <category>nestjs</category>
      <category>errors</category>
      <category>track</category>
    </item>
    <item>
      <title>Unlocking the Power of GraphQL for Beginners: A Step-by-Step Guide to Integrating GraphQL into Your Existing Project</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Fri, 17 Nov 2023 14:27:08 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/unlocking-the-power-of-graphql-for-beginners-a-step-by-step-guide-to-integrating-graphql-into-your-existing-project-51ob</link>
      <guid>https://dev.to/nestjs-ninja/unlocking-the-power-of-graphql-for-beginners-a-step-by-step-guide-to-integrating-graphql-into-your-existing-project-51ob</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55ufubffpb6qhl1fwyng.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55ufubffpb6qhl1fwyng.jpeg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello fellow coders!&lt;/p&gt;

&lt;p&gt;I’ve been noticing an increase in the number of companies requiring GraphQL experience for a job opportunity, and that triggers me to create another useful technical blog post in one interesting way, I want to implement GraphQL inside an existent project! Cool, right? My idea initially, is to implement something not so deep but that works at the same time.&lt;/p&gt;

&lt;p&gt;I am going to use my project, which is an AI question generator, that you can find in the link below.&lt;br&gt;
&lt;a href="https://medium.com/nestjs-ninja/creating-smart-questions-with-nestjs-and-openai-83089829cdf5" rel="noopener noreferrer"&gt;&lt;strong&gt;Creating Smart Questions with NestJS and OpenAI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s set the scope of this project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It must cover the user module, by offering a GraphQL interface to handle the functionalities below&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete user&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the project to work with GraphQL
&lt;/h2&gt;

&lt;p&gt;Let’s use the official documentation to follow the correct setup&lt;br&gt;
&lt;a href="https://docs.nestjs.com/graphql/quick-start" rel="noopener noreferrer"&gt;&lt;strong&gt;Documentation | NestJS - A progressive Node.js framework&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we have to install the dependencies&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then is necessary to set up GraphQL and I’m going to do it by adding the module into the app.module.ts like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { EnvModule } from '@app/common';
import { Module } from '@nestjs/common';
import { DevtoolsModule } from '@nestjs/devtools-integration';
import { Modules } from './modules/module';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot&amp;lt;ApolloDriverConfig&amp;gt;({
      driver: ApolloDriver,
      playground: true,
      autoSchemaFile: true,
    }),
    DevtoolsModule.register({
      http: process.env.NODE_ENV !== 'production',
    }),
    EnvModule,
    Modules,
  ],
})
export class AppModule { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;if you keep playground as true, it will enable the visual playground to try the queries and mutations on the browser. We will use it later.&lt;/p&gt;

&lt;p&gt;In my case, I also kept autoSchemaFile true and as I'm using the "code first approach”, the official documentation says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In the **code first **approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, the doc mentioned the case of using true as a value&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The autoSchemaFile property value is the path where your automatically generated schema will be created. Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the autoSchemaFile property to true&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configuring the resolvers
&lt;/h2&gt;

&lt;p&gt;Resolvers provide the instructions for turning a &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;**GraphQL&lt;/a&gt;** operation (a query, mutation, or subscription) into data. They return the same shape of data we specify in our schema — either synchronously or as a promise that resolves to a result of that shape. Typically, you create a &lt;strong&gt;resolver map&lt;/strong&gt; manually. The @nestjs/graphql package, on the other hand, generates a resolver map automatically using the metadata provided by decorators you use to annotate classes. To demonstrate the process of using the package features to create a GraphQL API, we'll create a simple authors API.&lt;/p&gt;

&lt;p&gt;In the code-first approach, we don't follow the typical process of creating our GraphQL schema by writing GraphQL SDL by hand. Instead, we use TypeScript decorators to generate the SDL from TypeScript class definitions. The @nestjs/graphql package reads the metadata defined through the decorators and automatically generates the schema for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code on
&lt;/h2&gt;

&lt;p&gt;Speaking about code, as we only need to apply GraphQL to the user module, I will start showing the files inside the folder /src/modules/user, just to show you some differences from the previous project. By the way, I will keep REST working at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The folder &amp;amp; file structure&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./user
├── controllers
│   ├── controllers...
├── dto
│   ├── args
│   │   └── get-user.args.ts
│   ├── create-user.dto.ts
│   ├── input
│   │   ├── create-user.input.ts
│   │   ├── delete-user.input.ts
│   │   └── update-user.input.ts
│   ├── update-user.dto.ts
│   └── user.dto.ts
├── resolvers
│   └── user.resolver.ts
├── use-case
│   ├── use-cases...
├── user.model.ts
└── user.module.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We are going to work on basically with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;user.model.ts;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;resolvers folder;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dto/args folder;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dto/input folder;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our resolver will provide an interface between the user and the use cases, which we have with the controllers when we use REST, right? So you can see that we are injecting the use cases as dependencies just because we need to call them with the required input for those use cases that need.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { GetUserArgs } from '../dto/args/get-user.args';
import { CreateUserInput } from '../dto/input/create-user.input';
import { UpdateUserInput } from '../dto/input/update-user.input';
import { CreateUserUseCase } from '../use-case/create-user';
import { DeleteUserUseCase } from '../use-case/delete-user';
import { GetManyUsersUseCase } from '../use-case/get-many-users';
import { GetUserByIdUseCase } from '../use-case/get-user-by-id';
import { UpdateUserUseCase } from '../use-case/update-user';
import { User } from '../user.model';

@Resolver('User')
export class UserResolver {
    constructor(
        private getManyUsersUseCase: GetManyUsersUseCase,
        private createUserUseCase: CreateUserUseCase,
        private updateUserUseCase: UpdateUserUseCase,
        private getUserByIdUseCase: GetUserByIdUseCase,
        private deleteUserUseCase: DeleteUserUseCase
    ) { }

    @Query(() =&amp;gt; User, { name: 'user', nullable: false })
    async getUser(@Args() getUserArgs: GetUserArgs) {
        return this.getUserByIdUseCase.execute(getUserArgs.id)
    }

    @Query(() =&amp;gt; [User], { name: 'users', nullable: false })
    async getUsers() {
        return await this.getManyUsersUseCase.execute();
    }

    @Mutation(() =&amp;gt; User)
    async createUser(
        @Args('createUserInput') createUserInput: CreateUserInput,
    ) {
        return await this.createUserUseCase.execute(createUserInput);
    }

    @Mutation(() =&amp;gt; User)
    async updateUser(
        @Args('updateUserInput') updateUserInput: UpdateUserInput,
    ) {
        return await this.updateUserUseCase.execute(updateUserInput.id, updateUserInput);
    }

    @Mutation(() =&amp;gt; User)
    async deleteUser(
        @Args('id') id: string
    ) {
        return await this.deleteUserUseCase.execute(id);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;(If you prefer the same code can be accessed &lt;a href="https://github.com/nestjsninja/nestjs-generate-questions-graphql/blob/main/src/modules/user/resolvers/user.resolver.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I am not going to detail this file yet, let’s do it later after having the complements of this file to work properly.&lt;/p&gt;

&lt;p&gt;As you may notice looking at the resolvers, we changed the approach of using the DTO as body and get parameters to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Args&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inputs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is a more usual way of talking when we are working with GraphQL. They will represent the DTO as it is, and there we specify the props according to the necessity. This is very easy work to be honest, because as we have already the DTO for the REST protocol, we can copy and change just a few details. Loot at this example&lt;/p&gt;

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

&lt;p&gt;Again, I am not going through each one of the inputs and args, so feel free to check all of them out.&lt;/p&gt;

&lt;p&gt;Last but not least, user.model.ts&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Field, ID, ObjectType } from '@nestjs/graphql';
import { User as UserDB } from '@prisma/client';

@ObjectType()
export class User {
    @Field(() =&amp;gt; ID)
    id: UserDB[`id`];

    @Field(() =&amp;gt; String)
    username: UserDB[`username`];

    @Field(() =&amp;gt; String)
    password: UserDB[`password`];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;(&lt;a href="https://github.com/nestjsninja/nestjs-generate-questions-graphql/blob/main/src/modules/user/user.model.ts" rel="noopener noreferrer"&gt;code&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This model is ObjectType which represents our User schema on Prisma, and in this file, we are mapping the fields properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the application
&lt;/h2&gt;

&lt;p&gt;After understanding and setting everything up, it’s time to run, right?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and then you can access &lt;a href="http://localhost:3000/graphql" rel="noopener noreferrer"&gt;http://localhost:3000/graphql&lt;/a&gt; , where you can play with your query, mutations, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutation&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Query&lt;/strong&gt;&lt;/p&gt;

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

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

&lt;p&gt;The final code can be found in this like&lt;br&gt;
&lt;a href="https://github.com/nestjsninja/nestjs-generate-questions-graphql" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub - nestjsninja/nestjs-generate-questions-graphql&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was pretty simple, right? Now I hope you feel a bit more comfortable applying GraphQL to your project when it’s necessary.&lt;/p&gt;

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

&lt;p&gt;The repository below is an old project in which I implemented the authentication and authorization modules using GraphQL. The funny part is that it is still up-to-date.&lt;br&gt;
&lt;a href="https://github.com/henriqueweiand/nestjs-account-graphql" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub - henriqueweiand/nestjs-account-graphql: NestJS and GraphQL based project simulating an…&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some good references&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.tomray.dev/nestjs-prisma" rel="noopener noreferrer"&gt;&lt;strong&gt;Ultimate Guide: How To Use Prisma With NestJS [2022]&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@shkim04/nestjs-graphql-prisma-postgresql-set-up-6cc76a624bde" rel="noopener noreferrer"&gt;&lt;strong&gt;NestJS GraphQL/Prisma/PostgreSQL Set Up&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>graphql</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Supercharge Your Testing Workflow: Creating Unit and E2E Tests 10x Faster with ChatGPT-3 Inside NestJS</title>
      <dc:creator>Henrique Weiand</dc:creator>
      <pubDate>Wed, 08 Nov 2023 21:48:00 +0000</pubDate>
      <link>https://dev.to/nestjs-ninja/supercharge-your-testing-workflow-creating-unit-and-e2e-tests-10x-faster-with-chatgpt-3-inside-nestjs-4kin</link>
      <guid>https://dev.to/nestjs-ninja/supercharge-your-testing-workflow-creating-unit-and-e2e-tests-10x-faster-with-chatgpt-3-inside-nestjs-4kin</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhs3hc64ufc9ssljr4nv4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhs3hc64ufc9ssljr4nv4.jpeg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello fellow coders! I have a polemic topic to talk about today, it is “using AI to create the unit and e2e tests” and how it can improve the velocity of writing tests!!!&lt;/p&gt;

&lt;p&gt;Before we dive into the topic, I want to be clear, that it is just one idea, and looking at the new worlds and new possibilities with AI I wonder if we don’t have to take advantage of these new technologies when we talk about tests!!!&lt;/p&gt;

&lt;p&gt;I have to be honest with you all readers, for all the posts that I have been doing I am using AI to help me write the code faster, it doesn’t mean that I don’t know about the content, code, etc, it means that I am taking advantage of ChatGPT-3 and Phind to have things done faster, for example.&lt;/p&gt;

&lt;p&gt;In this post, we have a few unit-tests&lt;br&gt;
&lt;a href="https://dev.to/henriqueweiand/applying-unit-tests-on-nestjs-with-jest-and-github-actions-a0j"&gt;&lt;strong&gt;Applying Unit Tests on NestJS with Jest and GitHub Actions&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post we have e2e-tests&lt;br&gt;
&lt;a href="https://dev.to/henriqueweiand/applying-integration-test-on-nestjs-with-jest-and-github-actions-2j85"&gt;&lt;strong&gt;Applying integration test on NestJS with Jest and GitHub Actions&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For both, during my circle of development, I didn’t use TDD or other methods, I just wrote the services, classes, and modules and then I went to the tests, at this time I already had the base structure, so I opened Phind or ChatGPT-3 and I asked them to create a test to cover as much cases as possible using &lt;a href="https://nestjs.com/" rel="noopener noreferrer"&gt;NestJS &lt;/a&gt;and its way of implementing tests, and in just a few seconds I have lots of tests ready! For a few of them I had to fix some small details, but overall, it was very good!&lt;/p&gt;

&lt;p&gt;One important point here is, that sometimes this approach does not guarantee some specific or important cases that just you know, so for those cases I had to implement it myself.&lt;/p&gt;

&lt;p&gt;Guys! It gives me back lots of time! So the question that I have is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Should we rethink the way of implementing tests? TDD? Whatever other method still relevant? Or we can have one approach like that?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m not sure about you all, but at the place where I work, we are both focused on quality but mainly on time and productivity, so the time aspect weighs a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real example
&lt;/h2&gt;

&lt;p&gt;I am going to use a real example that was implemented in our previous post&lt;br&gt;
&lt;a href="https://dev.to/henriqueweiand/creating-smart-questions-with-nestjs-and-openai-71b"&gt;&lt;strong&gt;Creating Smart Questions with NestJS and OpenAI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Using the use-case &lt;a href="https://github.com/nestjsninja/nestjs-generate-questions/blob/main/src/modules/question/use-case/create-question.ts" rel="noopener noreferrer"&gt;“modules/question/use-case/create-question.ts”&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open AI buddy tool, in my case &lt;a href="https://www.phind.com/" rel="noopener noreferrer"&gt;https://www.phind.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask ”I have the code below inside a NestJS project and I need to implement a unit-tests. Please write all possible cases to cover the class as much as possible. It must be written using the NestJS test module. CODE OF THE CREATE-QUESTION HERE”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the local test file and put the content over there&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Fix the necessary lines;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create new cases or change something (if necessary)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the tests npm run test&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;So amazing, isn’t it?&lt;/p&gt;

&lt;p&gt;You can see that it created the mocks for those necessary cases etc! 🧙‍♂️&lt;/p&gt;

&lt;h2&gt;
  
  
  Some possible approches
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use the AI tools to help you to remember something that maybe is not clear or you just don’t remember;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For those who are starting, try to notice the way of the implementation that AI is providing you and then use this content as input to understand better how it works;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For those who are more senior, try to get some codes from the AI and do the adjusts only on those areas that you know that are important;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The world and technology have been changing so fast this 2023 and I can assure you that 2024 will be much harder in terms of innovation, so let’s get out of our comfort zone and review the process of implementing and maybe be even better in this new moment.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>chatgpt</category>
      <category>testing</category>
      <category>jest</category>
    </item>
  </channel>
</rss>
