<?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: Sebastian Arrubia</title>
    <description>The latest articles on DEV Community by Sebastian Arrubia (@sarrubia).</description>
    <link>https://dev.to/sarrubia</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%2F1729764%2Faf27b148-8650-4b07-bc85-7599089e1d0b.jpg</url>
      <title>DEV Community: Sebastian Arrubia</title>
      <link>https://dev.to/sarrubia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sarrubia"/>
    <language>en</language>
    <item>
      <title>Creating Your First Project with Torpedo: A Step-by-Step Guide</title>
      <dc:creator>Sebastian Arrubia</dc:creator>
      <pubDate>Tue, 12 Nov 2024 17:22:30 +0000</pubDate>
      <link>https://dev.to/sarrubia/creating-your-first-project-with-torpedo-a-step-by-step-guide-2aad</link>
      <guid>https://dev.to/sarrubia/creating-your-first-project-with-torpedo-a-step-by-step-guide-2aad</guid>
      <description>&lt;p&gt;When building applications in Golang, adhering to the principles of Hexagonal Architecture can ensure clean, modular, and maintainable code. With &lt;strong&gt;Torpedo&lt;/strong&gt;, you can easily implement this architecture while speeding up your development process. In this guide, we’ll walk through how to create your first project with Torpedo, from installation to generating entities and use cases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post is a summary of the documented &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_create_project.html" rel="noopener noreferrer"&gt;quick start guide&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h4&gt;
  
  
  1. &lt;strong&gt;Getting Started with Torpedo&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Before we dive into creating a project, make sure you have Go installed on your system. Then, install Torpedo following the instructions at &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_install.html" rel="noopener noreferrer"&gt;installation guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This CLI tool will handle project generation, entity creation, and use case scaffolding for you. Once installed, you’re ready to create your first project.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Setting Up Your First Project&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Lets begging with our first application built with Torpedo!. We will be building a fly reservation app called Booking Fly.&lt;/p&gt;

&lt;p&gt;With Torpedo installed, creating a new project is as simple as running:&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;mkdir &lt;/span&gt;booking-fly &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;booking-fly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;torpedo init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will generate the folder &lt;code&gt;.torpedo&lt;/code&gt; where you should defines your entities and use cases. More info about this folder can be found at &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_create_project.html#torpedo-dir-struct" rel="noopener noreferrer"&gt;.torpedo dir struct&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Defining Your First Entity&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Next, you’ll want to define your domain entities. Entities are the core objects in your application’s business logic, representing things like &lt;code&gt;User&lt;/code&gt;, &lt;code&gt;Product&lt;/code&gt;, or &lt;code&gt;Order&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To define your first entity, create a YAML file under the &lt;code&gt;.torpedo/entities&lt;/code&gt; directory. For example, let’s create a simple &lt;code&gt;User&lt;/code&gt; entity:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.torpedo/entities/user.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;torpedo.darksub.io/v1.0&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;entity&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user"&lt;/span&gt;
    &lt;span class="na"&gt;plural&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;users"&lt;/span&gt; 
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;frequent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;flyer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user"&lt;/span&gt;
    &lt;span class="na"&gt;doc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;The user entity represents a system user but also a frequent flyer. &lt;/span&gt;
        &lt;span class="s"&gt;This entity is only for the example purpose.&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;reserved&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ulid&lt;/span&gt; 

        &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;name&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;full&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;email&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;contact&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;email"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt; &lt;span class="c1"&gt;# it is not recommended to save passwords, this is an example only&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;encrypted&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;password"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;plan&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;membership&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;plan"&lt;/span&gt;
            &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;GOLD&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SILVER&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BRONZE&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;miles&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;integer&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;accumulated&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;flyer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;miles"&lt;/span&gt;

    &lt;span class="na"&gt;relationships&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trips&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$rel&lt;/span&gt;
          &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.torpedo/entities/trip.yaml"&lt;/span&gt;
          &lt;span class="na"&gt;cardinality&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hasMany&lt;/span&gt;
          &lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nested&lt;/span&gt;
            &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;maxItems&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;

    &lt;span class="na"&gt;adapters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;

        &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt; 

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

&lt;/div&gt;



&lt;p&gt;Additionally the &lt;code&gt;Trip&lt;/code&gt; entity is required, so, let’s create a &lt;code&gt;Trip&lt;/code&gt; entity:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.torpedo/entities/trip.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;torpedo.darksub.io/v1.0&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;entity&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trip&lt;/span&gt;
    &lt;span class="na"&gt;plural&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trips&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fly&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;reservations"&lt;/span&gt;
    &lt;span class="na"&gt;doc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;The trip entity handles all data related with the frequent flyer trip&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;reserved&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ulid&lt;/span&gt;

        &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;departure&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;departure&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;airport"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arrival&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;arrival&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;airport"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;miles&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;integer&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;miles"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;from&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;date"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;to&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;date"&lt;/span&gt;

    &lt;span class="na"&gt;adapters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;

        &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Torpedo will generate the Go code for the &lt;code&gt;User&lt;/code&gt; and &lt;code&gt;Trip&lt;/code&gt; entities along with its corresponding CRUD operations, including the repository interfaces and any necessary database handling code.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. &lt;strong&gt;Creating Use Cases&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Once your entities are in place, it’s time to define how they’ll interact with the application’s workflows using &lt;strong&gt;use cases&lt;/strong&gt;. Use cases encapsulate the business rules and processes that act upon your entities.&lt;/p&gt;

&lt;p&gt;Create a YAML file under the &lt;code&gt;.torpedo/use_cases&lt;/code&gt; directory to define your use case. Here’s an example of a simple use case for &lt;strong&gt;booking a fly&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.torpedo/use_cases/booking_fly.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;torpedo.darksub.io/v1.0&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;useCase&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BookingFly"&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fly&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;reservation&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;case"&lt;/span&gt;
    &lt;span class="na"&gt;doc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt; 
        &lt;span class="s"&gt;Given a frequent flyer user should be able to do a booking fly from our well known fly routes, selecting the&lt;/span&gt;
        &lt;span class="s"&gt;departure airport and the arrival airport, also setting up the from-to fly dates. If the booking is successful, so the&lt;/span&gt;
        &lt;span class="s"&gt;system should calculate the user awards and upgrade it.&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;user.yaml&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;trip.yaml&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This definition tells Torpedo to create the skeleton code to put your custom logic for processing a fly reservation given a &lt;code&gt;Trip&lt;/code&gt; and a  &lt;code&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Torpedo will scaffold the complete use case, including interactions with your entities. &lt;/p&gt;

&lt;p&gt;After complete the next step (#5) please read the quick start guide to learn about how to code your logic within the generated skeleton use case at &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_use_cases.html" rel="noopener noreferrer"&gt;Use Cases&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. &lt;strong&gt;Wiring It All Together&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Once you’ve defined your entities and use cases, Torpedo ensures that the wiring between these components follows Hexagonal Architecture principles. The use cases will interact with the entities through the service interfaces, while your adapters (such as databases or APIs) handle persistence and external communication.&lt;/p&gt;

&lt;p&gt;Now it's time to write your app specification to put all together!. The application definition is the most important file because here is described your app. The following example shows how to define the Booking Fly app:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.torpedo/app.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;torpedo.darksub.io/v1.0&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Booking&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Fly&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;System"&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Application&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;example"&lt;/span&gt;
  &lt;span class="na"&gt;stack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go&lt;/span&gt;
    &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;github.com/darksubmarine/booking-fly"&lt;/span&gt; 
  &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;user.yaml&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;trip.yaml&lt;/span&gt;
    &lt;span class="na"&gt;useCases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;booking_fly.yaml&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;To generate the application code (entities, use cases and more) 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;torpedo fire
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will generate a project scaffold, setting up the directory structure based on the Hexagonal Architecture. The project will include core folders for &lt;strong&gt;entities&lt;/strong&gt;, &lt;strong&gt;use cases&lt;/strong&gt;, and &lt;strong&gt;adapters&lt;/strong&gt;. It ensures that your business logic and infrastructure remain decoupled from the get-go.&lt;/p&gt;

&lt;p&gt;You can now extend your project by adding more entities, use cases, and even custom adapters. Torpedo’s structure allows you to keep your code clean and modular, making it easy to scale your application as it grows.&lt;/p&gt;

&lt;p&gt;Also take a look at &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_use_cases.html" rel="noopener noreferrer"&gt;how to code your own logic withing generated Use Case code.&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. &lt;strong&gt;Running Your Application&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;After setting up entities and use cases, you’re ready to run your application. Torpedo includes a lightweight server, based on Gin Gonic project, that you can run for testing and development. Simply use:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't forget to run &lt;code&gt;go mod tidy&lt;/code&gt; before to update dependencies!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now interact with your application’s API, running the CRUD operations and use cases you’ve defined.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. &lt;strong&gt;What’s Next?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Torpedo makes it easy to generate clean, structured Go code with Hexagonal Architecture. But this is just the beginning! You can continue to explore Torpedo’s features by adding more complex workflows, integrating external services, and customizing the framework to suit your needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more advanced features coming soon to Torpedo, and feel free to share your feedback as you explore what’s possible!&lt;/p&gt;




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

&lt;p&gt;Creating your first project with Torpedo is simple and fast. By leveraging the power of entity schemas and use case definitions in YAML, you can quickly scaffold a robust Golang application while maintaining clean architectural principles. Now it's time to dive in and start building! Let us know what you think and how Torpedo can help your future projects.&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Introducing Torpedo: A Golang Framework Born Out of Frustration with Messy Codebases</title>
      <dc:creator>Sebastian Arrubia</dc:creator>
      <pubDate>Tue, 12 Nov 2024 17:21:40 +0000</pubDate>
      <link>https://dev.to/sarrubia/introducing-torpedo-a-golang-framework-born-out-of-frustration-with-messy-codebases-4gej</link>
      <guid>https://dev.to/sarrubia/introducing-torpedo-a-golang-framework-born-out-of-frustration-with-messy-codebases-4gej</guid>
      <description>&lt;p&gt;As a developer, I've spent countless hours wrestling with tangled codebases, trying to untangle business logic from the clutter of external dependencies like databases, APIs, and frontends. The deeper I went into complex projects, the more I realized how hard it was to keep things organized and maintainable over time. That’s when I started exploring architectural patterns that could help me build applications with a cleaner, more sustainable structure.&lt;/p&gt;

&lt;p&gt;After discovering &lt;strong&gt;Hexagonal Architecture&lt;/strong&gt; (aka Ports and Adapters), everything clicked. This architecture allowed me to separate my core business logic from the outside world, making my projects far more modular, testable, and adaptable. But even with this newfound clarity, implementing the architecture in Golang wasn’t as straightforward as I had hoped. I wanted a framework that embraced this pattern from the ground up—something that would not only speed up my development process but also ensure I was sticking to the principles of clean architecture without reinventing the wheel every time.&lt;/p&gt;

&lt;p&gt;That’s how &lt;strong&gt;&lt;a href="https://darksubmarine.com/docs/torpedo/index.html" rel="noopener noreferrer"&gt;Torpedo&lt;/a&gt;&lt;/strong&gt; was born.&lt;/p&gt;

&lt;p&gt;Torpedo is a Golang framework designed to take the headaches out of building well-structured applications. It streamlines the implementation of Hexagonal Architecture, making it easier to write clean, decoupled code that scales. In this post, I’ll share my journey of building Torpedo, explain its core features, and show how it can help you ship faster without sacrificing code quality.&lt;/p&gt;

&lt;p&gt;One of the standout features of &lt;strong&gt;Torpedo&lt;/strong&gt; is its ability to generate entity code and CRUD operations &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_create_project.html#entity-definition" rel="noopener noreferrer"&gt;from a simple YAML file.&lt;/a&gt; This file allows developers to define their domain entities in a clear, concise manner, specifying attributes and relationships without getting bogged down in boilerplate code. Once the entity schema is defined, Torpedo takes over, automatically generating the corresponding Go structs, repositories, and CRUD operations (Create, Read, Update, Delete) for each entity. This eliminates the need to manually write repetitive code, speeds up development, and ensures that the generated code is aligned with the Hexagonal Architecture principles—keeping your business logic clean and independent from infrastructure concerns.&lt;/p&gt;

&lt;p&gt;Torpedo also simplifies the creation of application logic by automatically generating &lt;a href="https://darksubmarine.com/docs/torpedo/quickstart_create_project.html#use-case-definition" rel="noopener noreferrer"&gt;&lt;strong&gt;use case code&lt;/strong&gt; based on a YAML definition file&lt;/a&gt;. In this file, developers can define the core actions or workflows that represent their application's business logic, such as processing payments, managing user accounts, or handling orders. Once the YAML file is set up, Torpedo generates the complete use case layer, including input and output handling, request validation, and interaction with repositories or external services. By automating the generation of this essential code, Torpedo helps developers stay focused on the unique business rules of their application, while ensuring that their use cases are neatly structured and adhere to the principles of Hexagonal Architecture.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Torpedo&lt;/strong&gt;, the relationship between &lt;strong&gt;entities&lt;/strong&gt; and &lt;strong&gt;use cases&lt;/strong&gt; is foundational to maintaining a clean separation of concerns, as per the Hexagonal Architecture. Entities represent the core business objects, encapsulating business rules and attributes, while use cases define how these entities are interacted with and manipulated based on specific workflows or actions. This clear division ensures that business logic remains isolated and independent from external systems, which makes the codebase more adaptable to change. The &lt;strong&gt;use case layer&lt;/strong&gt; interacts with entities to enforce business rules, while repositories (or adapters) handle data persistence without violating the entity's internal logic. &lt;/p&gt;

&lt;p&gt;Here’s a diagram to illustrate the flow between entities and use cases within Torpedo's Hexagonal Architecture:&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%2Fbzaqicbhj3kcz9ll0n7o.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%2Fbzaqicbhj3kcz9ll0n7o.png" alt="Hexagonal Flow of Entities and Use Cases" width="642" height="424"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This approach not only keeps the code modular and scalable but also allows for easier testing by decoupling external dependencies from core business logic.&lt;/p&gt;

&lt;p&gt;We’re just getting started with &lt;strong&gt;Torpedo&lt;/strong&gt;, and there’s so much more to come! This framework was built with the aim of making Golang development faster, cleaner, and more aligned with modern architectural principles. Whether you're working on a new project or refactoring an existing one, Torpedo can help you streamline your workflow, reduce boilerplate, and keep your business logic decoupled from external concerns. &lt;/p&gt;

&lt;p&gt;We invite you to give it a try, explore its features, and see how it fits into your development process. We’d love to hear your feedback—your insights will help shape the future of Torpedo as we continue to evolve and add more features to make it even better. Stay tuned more is coming soon, let’s build something great together!&lt;/p&gt;

&lt;p&gt;What's next? Take a look to &lt;a href="https://dev.to/sarrubia/creating-your-first-project-with-torpedo-a-step-by-step-guide-2aad"&gt;Creating Your First Project with Torpedo: A Step-by-Step Guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>microservices</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
