<?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: Marble IT</title>
    <description>The latest articles on DEV Community by Marble IT (@marbleit).</description>
    <link>https://dev.to/marbleit</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%2F1280739%2Fe70b6913-22ad-4d78-89d4-f7d9611ace25.png</url>
      <title>DEV Community: Marble IT</title>
      <link>https://dev.to/marbleit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marbleit"/>
    <language>en</language>
    <item>
      <title>Hosting NodeJS application on Windows server</title>
      <dc:creator>Marble IT</dc:creator>
      <pubDate>Mon, 03 Jun 2024 11:50:46 +0000</pubDate>
      <link>https://dev.to/marbleit/hosting-nodejs-application-on-windows-server-312g</link>
      <guid>https://dev.to/marbleit/hosting-nodejs-application-on-windows-server-312g</guid>
      <description>&lt;p&gt;Yes, I know, I know—why would anyone ever like to host NodeJS apps on Windows, right? Well, you obviously haven't had a client who already has a Windows server (probably because of existing .NET applications on it) and wants to host one more app on that server. And that app is written in...(drumroll sound in the background)...NodeJS. Believe me, be thankful it's not WordPress; we'll cover that in another article.&lt;/p&gt;

&lt;p&gt;But if this is the first time this scenario has happened to you, Welcome to the world of commercial programming!&lt;/p&gt;

&lt;p&gt;This short guide will help you set up Express applications on that Windows bad boy in no time. Let's go through the steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install IISNode on the server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;IISNode is an open-source native IIS module written in C++ that allows node.js (node.exe) to be run inside Windows IIS. If you don't know what IIS is, you should read an article about it first.&lt;/p&gt;

&lt;p&gt;Download and install iisnode via the releases page. Feel free to choose the latest version, and make sure to pick the correct binary package for your architecture (x86/x64).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Tell IIS that you want to use the IISNode module for app.js requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can easily do this by adding the following line to your web.config. If you don't have a web.config file, create an empty one and add this line:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;add name="iisnode" path="app.js" verb="*" modules="iisnode" /&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your web config should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;
    &amp;lt;system.webServer&amp;gt;&lt;br&gt;
        &amp;lt;handlers&amp;gt;&lt;br&gt;
            &amp;lt;add name="iisnode" path="app.js" verb="*" modules="iisnode" /&amp;gt;&lt;br&gt;
        &amp;lt;/handlers&amp;gt;&lt;br&gt;
    &amp;lt;/system.webServer&amp;gt;&lt;br&gt;
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You can use the URL Rewrite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use URL Rewrite (IIS native module) to choose which requests get handled by iisnode and which requests will skip iisnode. This is required when setting up a socket.io server inside iisnode. In this case, your web.config would look something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;rewrite&amp;gt;&lt;br&gt;
  &amp;lt;rules&amp;gt;&lt;br&gt;
    &amp;lt;rule name="app"&amp;gt;&lt;br&gt;
      &amp;lt;match url="app/*" /&amp;gt;&lt;br&gt;
      &amp;lt;action type="Rewrite" url="app.js" /&amp;gt;&lt;br&gt;
    &amp;lt;/rule&amp;gt;&lt;br&gt;
  &amp;lt;/rules&amp;gt;&lt;br&gt;
&amp;lt;/rewrite&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Set up additional parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an introductory article, so I won't discuss theses parameters in depth, but here is a list of parameters and their default values for IISNode:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;attribute name="node_env" type="string" expanded="true" defaultValue="%node_env%"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="asyncCompletionThreadCount" type="uint" defaultValue="0"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="nodeProcessCommandLine" type="string" expanded="true" defaultValue="node.exe"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="interceptor" type="string" expanded="true"&lt;br&gt;
    defaultValue="&amp;amp;quot;%programfiles%\iisnode\interceptor.js&amp;amp;quot;" /&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxConcurrentRequestsPerProcess" type="uint" allowInfitnite="true" defaultValue="1024"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxNamedPipeConnectionRetry" type="uint" defaultValue="100"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="namedPipeConnectionRetryDelay" type="uint" defaultValue="250"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxNamedPipeConnectionPoolSize" type="uint" defaultValue="512"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxNamedPipePooledConnectionAge" type="uint" defaultValue="30000"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="initialRequestBufferSize" type="uint" defaultValue="4096"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxRequestBufferSize" type="uint" defaultValue="65536"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="uncFileChangesPollingInterval" type="uint" defaultValue="5000"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="gracefulShutdownTimeout" type="uint" defaultValue="60000"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="logDirectory" type="string" expanded="true" defaultValue="iisnode"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="debuggingEnabled" type="bool" defaultValue="true"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="debuggerExtensionDll" type="string" defaultValue="iisnode-inspector-0.7.3.dll"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="debugHeaderEnabled" type="bool" defaultValue="false"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="debuggerVirtualDir" type="string" defaultValue="" /&amp;gt;&lt;br&gt;
&amp;lt;attribute name="debuggerPathSegment" type="string" expanded="true" defaultValue="debug"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="debuggerPortRange" type="string" expanded="true" defaultValue="5058-6058"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxLogFileSizeInKB" type="uint" defaultValue="128"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxTotalLogFileSizeInKB" type="uint" defaultValue="1024"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="maxLogFiles" type="uint" defaultValue="20"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="loggingEnabled" type="bool" defaultValue="true"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="devErrorsEnabled" type="bool" defaultValue="true"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="flushResponse" type="bool" defaultValue="false"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="watchedFiles" type="string" expanded="true" defaultValue="*.js;iisnode.yml"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="enableXFF" type="bool" defaultValue="false"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="promoteServerVars" type="string" defaultValue=""/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="configOverrides" type="string" expanded="true" defaultValue="iisnode.yml"/&amp;gt;&lt;br&gt;
&amp;lt;attribute name="recycleSignalEnabled" type="bool" defaultValue="false"/&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It is important to set up these parameters properly in different scenarios. For example, you can alter this variable:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;n order to tell IISNode how many instances of the app it should spawn (similar to PM2 on Linux). It can easily serve as a load balancer!&lt;/p&gt;

&lt;p&gt;There are multiple benefits of using IISNode (quoted from the official documentation page):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Process management&lt;/strong&gt;. The iisnode module takes care of lifetime management of node.exe processes making it simple to improve overall reliability. You don’t have to implement infrastructure to start, stop, and monitor the processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Side by side with other content types&lt;/strong&gt;. The iisnode module integrates with IIS in a way that allows a single web site to contain a variety of content types. For example, a single site can contain a node.js application, static HTML and JavaScript files, PHP applications, and ASP.NET applications. This enables choosing the best tools for the job at hand as well progressive migration of existing applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability on multi-core servers&lt;/strong&gt;. Since node.exe is a single threaded process, it only scales to one CPU core. The iisnode module allows creation of multiple node.exe processes per application and load balances the HTTP traffic between them, therefore enabling full utilization of a server’s CPU capacity without requiring additional infrastructure code from an application developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrated debugging&lt;/strong&gt;. With iisnode integrated debugging you can debug your node.js application deployed to IIS from a browser running on Windows, Mac, or Linux. You get this support out of the box, no extra configuration or installation is necessary. The solution is designed in a way that is shared hosting, firewall, and proxy friendly. The integrated debugging in iisnode uses node-inspector by Danny Coates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auto-update&lt;/strong&gt;. The iisnode module ensures that whenever the node.js application is updated (i.e. the script file has changed), the node.exe processes are recycled. Ongoing requests are allowed to gracefully finish execution using the old version of the application, while all new requests are dispatched to the new version of the app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access to logs over HTTP&lt;/strong&gt;. The iisnode module provides access the output of the node.exe process (e.g. generated by console.log calls) via HTTP. This facility is key in helping you debug node.js applications deployed to remote servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimal changes to node.js application code&lt;/strong&gt;. The iisnode module enables hosting of existing HTTP node.js applications with very minimal changes. Typically all that is required is to change the listed address of the HTTP server to one provided by the iisnode module via the process.env.PORT environment variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrated management experience&lt;/strong&gt;. The iisnode module is fully integrated with IIS configuration system and uses the same tools and mechanism as other IIS components for configuration and maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Other IIS benefits&lt;/strong&gt;. Port sharing, security, URL rewriting, compression, caching, logging&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope that you've managed to set everything up. For a further dive, you can read the official Github README.md. If that does not help, feel free to contact us!&lt;/p&gt;

&lt;p&gt;Ivan Kockarević&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>backend</category>
      <category>windows</category>
      <category>node</category>
    </item>
    <item>
      <title>Elastic Beanstalk: Developer's AWS paradise</title>
      <dc:creator>Marble IT</dc:creator>
      <pubDate>Mon, 03 Jun 2024 10:24:56 +0000</pubDate>
      <link>https://dev.to/marbleit/elastic-beanstalk-developers-aws-paradise-41g5</link>
      <guid>https://dev.to/marbleit/elastic-beanstalk-developers-aws-paradise-41g5</guid>
      <description>&lt;h2&gt;
  
  
  Beanstalk in a nutshell
&lt;/h2&gt;

&lt;p&gt;Starting with the cloud can be pretty intimidating because of all the fancy words you hear while learning. Auto-scaling and resource provisioning are just a couple of phrases that may be confusing for new developers. Besides that, most developers just want their code to run without digging deep into hosting technology, especially when deadlines are approaching.&lt;/p&gt;

&lt;p&gt;Enters the room, Elastic Beanstalk. It is a managed service that helps developers run their web applications fast and without worrying about best practices in the AWS environment. It is used by both new and more experienced developers since it is easy to set up but also rich with features so you can tailor your system to your custom needs.&lt;/p&gt;

&lt;p&gt;But first, what does managed service even mean? It means AWS itself is managing everything. You don't need to worry about updates, security patches, and every other detail essential for running the application securely and consistently.&lt;/p&gt;

&lt;p&gt;What is your job, then? Provide an overview of what your system needs and upload code. It is that simple. You simply upload your code, and Elastic Beanstalk automatically handles the deployment, from capacity provisioning, load balancing, and automatic scaling to web application health monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works?
&lt;/h2&gt;

&lt;p&gt;Beanstalk works with the application/environment model. You create your application, and then you can have multiple environments for it. This basically means you can have completely different system architectures for different environments. For example, your server could run in only one instance for the development environment but have scaling functionalities implemented for production. And what do you need to do there? Just pick the options for scaling. Pick how many instances should be running minimally and maximally. Pick the thresholds for spinning new instances and terminating unused instances. Everything else is managed by Beanstalk itself.&lt;/p&gt;

&lt;p&gt;You have the freedom to choose the deployment options for your applications. Some of them are all at once, Rolling, and Blue/Green. These will not be covered in this blog post, but they are mentioned to point out the vast range of features Beanstalk has.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;p&gt;Beanstalk supports a wide variety of platforms. The list is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GO&lt;/li&gt;
&lt;li&gt;JAVA SE&lt;/li&gt;
&lt;li&gt;JAVA Tomcat&lt;/li&gt;
&lt;li&gt;.NET with IIS&lt;/li&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;li&gt;Packer builder&lt;/li&gt;
&lt;li&gt;Single Container Docker&lt;/li&gt;
&lt;li&gt;Multi Container Docker&lt;/li&gt;
&lt;li&gt;Preconfigured Docker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New platforms are added constantly. There is also one nice feature that makes Elastic Beanstalk perfectly capable of every need you can think of. It is called a Custom platform. You can completely configure the platform you need for your applications. This is very important for companies that have a lot of custom system configurations. The custom platform has a major drawback though. It is seen as a very advanced feature which means that it is not easy at all to create your personalized platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beanstalk CLI
&lt;/h2&gt;

&lt;p&gt;We can install an additional CLI called the EB CLI, which makes working with Beanstalk from the CLI easier. It’s helpful for your automated deployment pipelines!&lt;/p&gt;

&lt;p&gt;After configuring the environment, you can set up one command to deploy your whole application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your first Beanstalk web app
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Starting point&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, log into your AWS account and search for Elastic Beanstalk.When you land on the EB service home page, click on Create a new application.&lt;/p&gt;

&lt;p&gt;You will then be redirected to the page shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdr6tpla3mhq7m74z3emt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdr6tpla3mhq7m74z3emt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where you give your application a name, pick a platform, and upload your code. This is basically all you need to do for your application to be deployed. Of course, you can manually configure it in more detail by clicking the Configure more options button. This is what we will do to check more in-depth configurations.&lt;/p&gt;

&lt;p&gt;As you can see, you can use the Sample application code. AWS has sample source codes for every platform, so you can learn the most common Beanstalk features without writing any code yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview of most common environment configurations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After clicking on the Configure More options button, you will land on the Configure environment page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F29t63ai540xseifo7fel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F29t63ai540xseifo7fel.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where the magic happens. As you can see, configurations are categorized, making it easier to configure individual resources for your application.&lt;/p&gt;

&lt;p&gt;We will go through the most important ones, but feel free to experiment with them all. Just be aware that, even though Beanstalk is free, resources provisioned by it, that are out of the free tier will be charged, so don't forget to check the pricing pages or erase all of the resources if you are just researching Beanstalk capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Presets:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fja09ojei1yhiqkyjyhfr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fja09ojei1yhiqkyjyhfr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Presets, also called deployment modes, tell Beanstalk the overall architecture you want for your environment. Single-instance presets are great for development and testing. As the name suggests, they use one instance (server) to run your web app.&lt;/p&gt;

&lt;p&gt;High-availability presets are most commonly used in production. They leverage the load balancer features and use auto-scaling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fqhzekvgv4slwy1s9smg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqhzekvgv4slwy1s9smg4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the place where you can pick your platform and its version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffzhnopz8rdwp05sqrz9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffzhnopz8rdwp05sqrz9l.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The software category is used for your software-related configs. In software configuration, you can set your environment variables (called environment properties here). Bye-bye, env files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instances:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9iy4lokjxtb91iwt0quf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9iy4lokjxtb91iwt0quf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, you can configure your instances' memory resources and public availability. In high-availability applications, it is best practice to keep your instances private while the load balancer is public, which will route all the traffic to your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load balancer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F15sm4eo4if6ubjv268n8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F15sm4eo4if6ubjv268n8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Load balancer type, as well as listeners, protocols and ports, are configured here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capacity:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0rwaig20fr2rl12ewm1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0rwaig20fr2rl12ewm1z.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the capacity section, you choose your EC2 instance type and system image. This is basically the same old-school EC2 configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fl0pg3ljfz9gwxs1ci91u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fl0pg3ljfz9gwxs1ci91u.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least, security. This is where the role that performs all the deployment actions on your behalf is created. It is also where you will need to create and assign private keys for SSH access to your instance(s).&lt;/p&gt;

&lt;p&gt;After you are ready, click on Create an App and let Beanstalk create every resource for your application. After a few minutes, you should land on the page below, and if everything is OK, your application should be fully deployed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9fesdsxj4g2dj5m3k8ck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9fesdsxj4g2dj5m3k8ck.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the link below the environment name to visit your Beanstalk application.&lt;/p&gt;

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

&lt;p&gt;This is just scratching the surface of one of the most powerful tools AWS is providing to developers. I hope I can show you how EB can save developers time every day while also being a platform where developers can learn about cloud best practices. Elastic Beanstalk is the service you should definitely have in your cloud tools arsenal.&lt;/p&gt;

&lt;p&gt;Aleksandar Polić&lt;/p&gt;

</description>
      <category>web</category>
      <category>backend</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Unity UI System - Best Practices</title>
      <dc:creator>Marble IT</dc:creator>
      <pubDate>Fri, 26 Apr 2024 09:35:28 +0000</pubDate>
      <link>https://dev.to/marbleit/unity-ui-system-best-practices-2o24</link>
      <guid>https://dev.to/marbleit/unity-ui-system-best-practices-2o24</guid>
      <description>&lt;p&gt;During my development days, I've seen many Unity projects. Sometimes I've made them from scratch, other times I've continued someone else's project.&lt;/p&gt;

&lt;p&gt;In either case, when I had other developers in the team, I noticed that a lot of them had trouble with Unity's UI system, whether it's scaling of components, optimizing rendering calls or just plain structuring of game objects.&lt;/p&gt;

&lt;p&gt;I noticed that most of them didn't follow any guidelines and just worked based on their feeling of the best practice, which often turned out to be wrong. But that was also true for myself, until the experience taught me better. &lt;/p&gt;

&lt;p&gt;What I also found to be the problem is lack of summarized material for my cases, when I didn't want to waste time going through whole documentation. So this is my attempt to summarize key points and solutions that I've acquired over the years.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; note that these are not the official guidelines, and they might not be convenient for every type of project (VR for example) - but these are the ones I've found to be most effective for most projects that will run on screens (mobile, PC, PlayStation, Xbox).&lt;/p&gt;

&lt;h2&gt;
  
  
  Canvas Component
&lt;/h2&gt;

&lt;p&gt;The only way to start this discussion is to talk about the main UI Component - Canvas. Canvas is the main parent object, that contains all the UI components as children. I will not go into detail about how it works but instead, talk about two key properties when setting it up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canvas Render Mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can choose among 3 options: Screen Space - Overlay, Screen Space - Camera, or World Space.&lt;/p&gt;

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

&lt;p&gt;The main difference between &lt;strong&gt;Screen Space&lt;/strong&gt; and &lt;strong&gt;World Space&lt;/strong&gt; is that &lt;strong&gt;Screen Space&lt;/strong&gt; will render &lt;strong&gt;Canvas&lt;/strong&gt; in front of the whole game world; basically, it will be fixed on the user's screen in front of everything else. Meanwhile, &lt;strong&gt;World Space&lt;/strong&gt; will be rendered among other objects in the game world, and it can be anywhere, like a regular object that is not a part of UI.&lt;/p&gt;

&lt;p&gt;In most cases, your choice will be &lt;strong&gt;Screen Space&lt;/strong&gt;, as the UI components are mostly used for UI indicators inside the game that are always in front of the game world (such as health, inventory, number of lives, timers, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canvas Scaler (UI Scale Mode)&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;This is probably the more important part of the &lt;strong&gt;Canvas&lt;/strong&gt; setup - specifically the &lt;strong&gt;UI Scale Mode&lt;/strong&gt; property. By default, it's set to &lt;strong&gt;Constant Pixel Size&lt;/strong&gt;, which can cause scaling issues upon changing resolutions if left like that. In most cases, &lt;strong&gt;UI Scale Mode&lt;/strong&gt; should be set to &lt;strong&gt;Scale With Screen Size&lt;/strong&gt;, which will give you an option to set default resolution and make objects in UI scale, either with width or height, upon changing the resolution.&lt;/p&gt;

&lt;p&gt;Example of Canvas settings for Mobile UI:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  One Canvas or Multiple Canvases?
&lt;/h2&gt;

&lt;p&gt;This depends on the use case. Before answering the question, let's talk about draw calls in Unity and re-draws explicitly on &lt;strong&gt;Canvas&lt;/strong&gt;. Let's say that you have one &lt;strong&gt;Text&lt;/strong&gt; component inside canvas which shows the seconds passed since the start of the game. That means that each second, your &lt;strong&gt;Text&lt;/strong&gt; component is going to change. Every time a component changes, the &lt;strong&gt;Canvas&lt;/strong&gt; that contains that &lt;strong&gt;Text&lt;/strong&gt; is completely re-drawn. Now let's say, that you have a few static &lt;strong&gt;Image&lt;/strong&gt; components inside that same &lt;strong&gt;Canvas&lt;/strong&gt; with &lt;strong&gt;Text&lt;/strong&gt; timer. Now, each time a second passes, &lt;strong&gt;Canvas&lt;/strong&gt; is completely redrawn, meaning that not only &lt;strong&gt;Text&lt;/strong&gt; will be redrawn, but all the static &lt;strong&gt;Images&lt;/strong&gt; (which technically don't need that redraw since they didn't change). You can imagine how that issue can scale up when you have multiple components that change inside one canvas - &lt;strong&gt;and that's where the second Canvas comes to save the day&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you have &lt;strong&gt;Canvas&lt;/strong&gt; nested inside a &lt;strong&gt;Canvas&lt;/strong&gt;, when child &lt;strong&gt;Canvas&lt;/strong&gt; is redrawn, the parent &lt;strong&gt;Canvas&lt;/strong&gt; will not be influenced. So the smartest structuring of the game objects would look like this:&lt;/p&gt;

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

&lt;p&gt;This knowledge of &lt;strong&gt;Canvas&lt;/strong&gt; redraw behavior can greatly help when optimizing the game for lower-end devices. Think about it all the time, and it will most certainly improve your game's FPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Component
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Image&lt;/strong&gt; component is pretty simple by itself. The main challenge is making sure that the image will appear the same on different screens (resolutions). To ensure that behavior will happen, just make sure that &lt;strong&gt;Preserve Aspect&lt;/strong&gt; is ticked. This is how the &lt;strong&gt;Image&lt;/strong&gt; component should look:&lt;/p&gt;

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

&lt;p&gt;The second part of making sure it looks the same on every screen will be explained in the Anchoring section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Component
&lt;/h2&gt;

&lt;p&gt;Like the &lt;strong&gt;Image&lt;/strong&gt;, the &lt;strong&gt;Text&lt;/strong&gt; component is also pretty simple and presents the same challenge - making sure that it looks the same on all screens. This can be ensured by setting a custom &lt;strong&gt;Font Size&lt;/strong&gt; and making sure that &lt;strong&gt;Best Fit&lt;/strong&gt; is unticked! If &lt;strong&gt;Best Fit&lt;/strong&gt; is ticked, the size of the font (text) will vary from screen to screen, as Unity (and Canvas) will automatically change it to what they think is best fit, and you will get inconsistent UI as a result.&lt;/p&gt;

&lt;p&gt;Here is an example of how &lt;strong&gt;Text&lt;/strong&gt; component should look like:&lt;/p&gt;

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

&lt;p&gt;The second part of making sure it looks the same on every screen will be explained in the Anchoring section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anchoring
&lt;/h2&gt;

&lt;p&gt;Anchors define how your UI component will behave in relation to its parent, and it can be set on each object that has &lt;strong&gt;Rect Transform&lt;/strong&gt;, or in other words, is a part of UI. They look like this by default:&lt;/p&gt;

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

&lt;p&gt;You should never leave them in their default position. By clicking on the Anchor Rectangle in the Rect Transform, you can select predefined anchor positions (top, bottom, left, right, middle, each of the corners, etc.). That menu looks like this:&lt;/p&gt;

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

&lt;p&gt;However, what I suggest to ensure that every object will be placed exactly as you've set it up, regardless of screen resolution is to drag by hand each anchor to the corner of your UI Component. In practice, that would look like this:&lt;/p&gt;

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

&lt;p&gt;This way, however you change the resolution, the object will stay in the same position in relation to its parent.&lt;/p&gt;

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

&lt;p&gt;I hope this basics of UI have covered some of the troubles you are facing and managed to put you on the right way of building the best UI. Happy game creating!&lt;/p&gt;

&lt;p&gt;Luka Ćurčić&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>videogame</category>
      <category>unity3d</category>
      <category>development</category>
    </item>
    <item>
      <title>Test Driven Development</title>
      <dc:creator>Marble IT</dc:creator>
      <pubDate>Thu, 25 Apr 2024 08:23:29 +0000</pubDate>
      <link>https://dev.to/marbleit/test-driven-development-4m62</link>
      <guid>https://dev.to/marbleit/test-driven-development-4m62</guid>
      <description>&lt;p&gt;After working on multiple projects, I was able to see what difference writing tests make. Sometimes, it seems like writing tests would just eat up a bunch of time and that it's good to test features yourself. But as the project gets bigger and more complex, it's harder to make sure that the code you wrote doesn’t affect other parts of the project.&lt;/p&gt;

&lt;p&gt;One project I worked on had many features that affected each other, and our client wanted some significant changes that could break other features. Shortly after, bugs came along, and at this point, we couldn't recall why something was written the way it was and where else it was used. After implementing the change you have been asked to, you test it,  and everything seems okay - or so you think. Suddenly, someone reports that other parts of the application are broken, and you find yourself wasting hours on something a test would notify you about in seconds.&lt;/p&gt;

&lt;p&gt;This happens a lot. Programmers are being pressured to ship code as fast as possible and often don't push back and negotiate realistic estimates. And then you start to hear, “TDD is a waste of time because I can’t code that fast.” But in reality, you would have code that is easier to refactor and be sure that changes won’t affect the project. You'd spend far less time debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what is Test Driven Development?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TDD is an innovative software development approach in which you write tests before writing the bare minimum of code required for the test to be fulfilled. In simple terms, test cases are created before code is written. The purpose of TDD is to make the code clearer, more straightforward, and bug-free. TDD starts with designing and developing tests for every small functionality of an application. The simple concept of TDD is to write and correct the failed tests before writing new code. This helps to avoid code duplication as we write a small amount of code at a time to pass tests; TDD sometimes is also called "Test First Development."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use TDD?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The short answer is “because it is the simplest way to achieve both good quality code and good test coverage.”&lt;/p&gt;

&lt;p&gt;The longer answer comes from what TDD really is.&lt;/p&gt;

&lt;p&gt;For start, you need to follow these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You are not allowed to write any production code unless it is to make a failing unit test pass&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are not allowed to write any more of a unit test than it is sufficient to fail, and compilation failures are failures&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are not allowed to write any more production code than it is sufficient to pass the one failing unit test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rules define the mechanics of TDD, but they are definitely not everything you need to know. The process of using TDD is often described as a Red/Green/Refactor cycle.&lt;/p&gt;

&lt;p&gt;The red, green, refactor approach helps developers compartmentalize their focus into three phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Red – think about what you want to develop&lt;/li&gt;
&lt;li&gt;Green – think about how to make your test pass&lt;/li&gt;
&lt;li&gt;Refactor – think about how to improve your existing implementation&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The red phase is always the starting point of the cycle. The purpose of this phase is to write a test that informs the implementation of a feature. The test will only pass when its expectations are met.&lt;/p&gt;

&lt;p&gt;For example, imagine you want to create a function called sortArray that sorts the numerical values of an array in ascending order. You may start by writing a test that checks the following input and output:&lt;/p&gt;

&lt;p&gt;Input: [2, 4, 1]&lt;br&gt;
Output: [1, 2, 4]&lt;/p&gt;

&lt;p&gt;When you run this test, you may see an error message like:&lt;/p&gt;

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

&lt;p&gt;As you can see, the purpose of this phase was to define what you want to implement. The resulting error message from this test informs your approach to implementation. At this point, you are considered “in the red.”&lt;/p&gt;

&lt;p&gt;The green phase is where you implement code to make your test pass. The goal is to find a solution without worrying about optimizing your implementation.&lt;/p&gt;

&lt;p&gt;In our sortArray example, the goal is to accept an array like [2, 4, 1] and return [1, 2, 4].&lt;/p&gt;

&lt;p&gt;You can approach the problem by writing a loop that iterates over the array and moves the current number over if it is larger than the number to the right. Then nest this loop inside of a loop that repeats until all of the numbers are sorted. After implementing this, you should see a passing test message that could look something like this: &lt;/p&gt;

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

&lt;p&gt;At the end of this phase, you are considered “in the green.”&lt;/p&gt;

&lt;p&gt;Now, you can start thinking about optimizing your codebase while having a descriptive test if you do something wrong. In the refactor phase, you are still “in the green.” You can start thinking about how to implement your code better or more efficiently. And by that, I mean how to accomplish the same output with more descriptive or faster code.&lt;/p&gt;

&lt;p&gt;For example, instead of using a bubble sort method, you can use the merge sort algorithm because it has a faster average sorting speed than bubble sort.&lt;/p&gt;

&lt;p&gt;So, after refactoring the sortArray function and running the test, the test message would look something like this:&lt;/p&gt;

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

&lt;p&gt;Do you notice the difference? Instead of 19 ms, the code now needs only 7 ms to execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In test-driven development(TDD), a test is written first before writing the functional code. This doesn’t mean that TDD can replace traditional QA, but instead, it ensures effective unit testing. An effective unit test will ensure better code coverage, fewer bugs, and QA efforts in the long run. Implementing TDD can be challenging though, because you need people involved who have the necessary skill sets for using different unit test frameworks. If you have the right people, then it’s always good to implement TDD in your projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While it’s challenging to learn to use TDD, in my opinion, every developer should be familiar with it. Because in the long run, TDD is definitely not a waste of time, and is a way to keep code clean and optimized. Refactoring code could also cause other parts of the application to malfunction without us knowing. Then, you might have a situation where the project is “finished,” but you get a message from the client saying that something broke, and it is your responsibility to fix that. Most likely, you are already on some other project, so now you have to work on two sides, probably doing overtime, and at that moment, you realize that if you had written tests, this wouldn’t have happened. You already wasted more time on solving bugs, than just writing tests from the beginning.&lt;/p&gt;

&lt;p&gt;But what if you are working on a small app, that has few features and is not that complex. Is there a need to write tests for it? No, it's up to you or your team to decide if TDD will take more time or save it.&lt;/p&gt;

&lt;p&gt;The bigger the app, the more likely TDD will save you time and stress.&lt;/p&gt;

&lt;p&gt;Aleksandar Tišma&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>backend</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Application of S.O.D. in frontend development</title>
      <dc:creator>Marble IT</dc:creator>
      <pubDate>Mon, 22 Apr 2024 09:31:56 +0000</pubDate>
      <link>https://dev.to/marbleit/application-of-sod-in-frontend-development-3il0</link>
      <guid>https://dev.to/marbleit/application-of-sod-in-frontend-development-3il0</guid>
      <description>&lt;p&gt;In this post, we will show that SOLID matters for every software engineer, regardless of the area of expertise. In web UI development, engineers mostly work with HTML, CSS, and client-side JavaScript, which do not necessarily require knowledge of object-oriented design. This leads to engineers who never get in touch with SOLID, and less code quality in general. Let's fix this by introducing some of the principles that are a must in client-side development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Motivation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By knowing SOLID, you enhance the quality of your code in many ways - you benefit from readability, maintainability, minimal repetition and redundancy, agility, and cost of development in general. Not to mention the stress relief during RFCs (requests for change) and code maintenance!&lt;/p&gt;

&lt;p&gt;Principles are initially easy to adopt, but once you get better at them, they will reveal more and more things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The term "SOLID" was first introduced by the famous engineer Robert C. Martin. It marks a set of five principles that lead to better code quality. Although they are mostly followed in object-oriented design, they are also useful in front-end development.&lt;/p&gt;

&lt;p&gt;These principles are not rules, they are tenets that engineers need to adopt and use responsibly in their projects.&lt;/p&gt;

&lt;p&gt;The acronym "SOLID" stands for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single responsibility principle&lt;/li&gt;
&lt;li&gt;Open-closed principle&lt;/li&gt;
&lt;li&gt;Liskov substitution principle&lt;/li&gt;
&lt;li&gt;Interface segregation principle&lt;/li&gt;
&lt;li&gt;Dependency inversion principle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Liskov substitution and interface segregation principles are more related to object oriented design and aren't that crucial in frontend development, but, of course, in larger frontend applications, you will also find those. For today's post, let's go through S, O and D!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single responsibility principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This principle is really easy to adopt and demonstrate through simple CSS. The principle itself states that every module we write (classes, functions in JS, or even CSS selectors) should have one responsibility or, to be more precise, one reason to change. This means that we shouldn't write complex ninja classes, functions, or selectors that do and define everything. Instead, we should dissolve that module into smaller modules, each having one functionality. A level of separation of the modules in your code is called "granularity." As an engineer, it is your responsibility to find a perfect level of granularity for your project. Don't be stingy, but do not go nuts.&lt;/p&gt;

&lt;p&gt;Let's illustrate this principle with a CSS example. Let's imagine that we have a button in our project, that should be 40px in height, 100px in width and always red. We can write this in CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; .btn-red { 
    width: 100px; 
    height: 40px; 
    background-color: red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, a realistic scenario is that, at some point, we will have an RFC for a new button color, let's say blue. In that case, assuming that we cannot change our old code due to the fact that it is used all over the project, we can write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn-red { 
    width: 100px; 
    height: 40px; 
    background-color: red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn-blue { 
    width: 100px; 
    height: 40px; 
    background-color: blue;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not good since we duplicated some of our previous code. This is a small duplication, but it can become larger and create more significant problems. For example, you can have buttons in 10 colors, and you need to change their height to 30px. You would need to write that change in 10 places in your code. Let's take a look at a better example.&lt;/p&gt;

&lt;p&gt;We could follow the "S" principle and write our initial code like this (separated functionalities):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn { 
    width: 100px; 
    height: 40px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn.red { 
    background-color: red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the properly granulated code, we can easily do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn { 
    width: 100px; 
    height: 40px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn.red { 
    background-color: red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn.blue{ 
    background-color: blue;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We didn't change our original code, but we added a new feature, without code duplication. This is the point of single responsibility!&lt;/p&gt;

&lt;p&gt;Important thing to note: we could granulate our code even further without getting any benefits. For example, we could've written something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.width-100 { 
    width: 100px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.height-40 { 
    height: 40px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so on, for every CSS property. This level of granularity brings no value to our specific scenario, so watch out, do not over-engineer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open-closed principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This principle states that the code that you write should be OPEN for EXTENSION and CLOSED for MODIFICATION. What this basically means is that the developer that continues the work after you doesn't need to change the existing code but should be able to easily extend it. We can illustrate this principle on the exact same CSS example as the previous one.&lt;/p&gt;

&lt;p&gt;By writing code like this, we allow the next developer to easily extend our code and add a new color:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn { 
    width: 100px; 
    height: 40px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn.orange { 
    background-color: orange;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn.custom{ 
    background-color: #f2f2f2;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, our original example was CLOSED for extension.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency inversion principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, this principle comes in naturally with JavaScript since it doesn't support types, so there isn't much point in mentioning it in a JS context. But if you are using TypeScript, you need to know this principle!&lt;/p&gt;

&lt;p&gt;The dependency inversion principle states that nothing should depend on concrete implementations but on abstractions instead. What this means is that if you are using a certain module in your code, like FacebookService (e.g., for some logic related to Facebook SDK), it should reside behind its own abstraction (e.g. SocialNetworkService), so the actual implementation is minimally mentioned in the code. The reason to do this is to achieve an easier switch if, at some point, that FacebookService needs to become, let's say, Google Service.&lt;/p&gt;

&lt;p&gt;To follow the dependency inversion principle, you'd first need to create your interface with the same method signatures as the original implementation. Second, your concrete implementation should extend your newly created abstraction. Third, you'd need to write the logic in your code to ensure that a concrete implementation is returned each time someone requests the abstraction. Let's see how we can achieve this in TypeScript:&lt;/p&gt;

&lt;p&gt;At first, we will have a concrete service that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class FacebookService { 
    login() { 
        // Some logic with Facebook SDK 
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we need to create our interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default interface SocialNetworkInterface { 
    login: () =&amp;gt; void // The only important thing is that the method signature is the same as the concrete one
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, our concrete implementation should extend the interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class FacebookService extends SocialNetworkInterface ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, last but not least, we need to create a way to always get our concrete implementation behind our abstraction. We can use a factory method to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SocialNetworkServiceFactory { 
    getService() : SocialNetworkService { 
        return new FacebookService(); // This is the only place in the code where the concrete implementation will be mentioned so that it can be easily swapped with GoogleService 
    }
}

export default new SocialNetworkFactory();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, when we want to use our FacebookService in our code, we would write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let socialNetworkService: SocialNetworkService = socialNetworkFactory.getService(); // This will create a FacebookService, even though we haven't mentioned it in this line. A job well done!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some will argue that this isn't, in fact, dependency inversion, but a simple factory method instead. To them, I say - Do not mix dependency INVERSION with dependency INJECTION. Dependency inversion is a PRINCIPLE (that we achieved with this solution), and dependency injection is a PATTERN that is used in some technologies to achieve dependency inversion and inversion of control.&lt;/p&gt;

&lt;p&gt;Ivan Kockarevic&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>solid</category>
      <category>frontend</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
