<?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: Luigi Escalante</title>
    <description>The latest articles on DEV Community by Luigi Escalante (@luigiescalante).</description>
    <link>https://dev.to/luigiescalante</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%2F1086363%2F947d9cf0-0b48-4622-b7b9-84ac49946170.png</url>
      <title>DEV Community: Luigi Escalante</title>
      <link>https://dev.to/luigiescalante</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/luigiescalante"/>
    <language>en</language>
    <item>
      <title>Choosing Your Path: Avenger (Front-End) vs Men in Black (Back-End)</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Mon, 05 Jan 2026 01:56:10 +0000</pubDate>
      <link>https://dev.to/luigiescalante/choosing-your-path-avenger-front-end-vs-men-in-black-back-end--44em</link>
      <guid>https://dev.to/luigiescalante/choosing-your-path-avenger-front-end-vs-men-in-black-back-end--44em</guid>
      <description>&lt;p&gt;While software engineers often find themselves performing both front-end and back-end tasks, it is common to develop a preference for one area or to possess stronger skills in either front-end or back-end development. This inclination typically shapes your professional identity and influences the type of work you seek out.&lt;br&gt;
One aspect that many newcomers overlook is the impact of the company's environment on these two roles. The work culture, team dynamics, and expectations can differ significantly between front-end and back-end positions, and understanding these distinctions is essential when deciding which path to follow.&lt;/p&gt;

&lt;p&gt;To illustrate the difference in a lighthearted way: ask yourself, do you want to be an Avenger or a member of the Men in Black? This analogy captures the contrasting nature of front-end and back-end roles in the world of software engineering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Front-End Developers: The Avengers of Software Engineering
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The “Heroes” from the Customer’s Perspective
&lt;/h4&gt;

&lt;p&gt;As a front-end developer, you often become the “hero” of the project in the eyes of the customer or end user. Your work is always the center of attention from the outside world. While a software project involves many areas—such as infrastructure, back-end development, project managers, designers, and testers—even a small successful change on the front end is highly appreciated by the customer. Most of the congratulations and recognition are based on the user experience you help create.&lt;/p&gt;

&lt;p&gt;Imagine this scenario: a new app update improves the user experience and makes it easier and faster to find results. All the comments and praise will focus on the great job you did. In contrast, consider if you migrate the database to a new engine to improve performance, but there’s no visible change to the user experience. In this case, no one will say, “I don’t know what you did, but the app is faster—thank you.” Infrastructure and back-end work often pass without comment or glory.&lt;br&gt;
Judged by the World&lt;/p&gt;

&lt;h4&gt;
  
  
  Front-end developers, like heroes, are judged by society.
&lt;/h4&gt;

&lt;p&gt;The entire world evaluates your work. Since everyone has an opinion, you will receive criticism and negative comments, and sometimes you’ll be blamed for problems beyond your control, the most famous example is the comment “The last version is better”, “I think is better if this is like …”. Everyone will be an expert. &lt;/p&gt;

&lt;h4&gt;
  
  
  Noncommon skills for Front-End Developers
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Effective Communication with Non-Technical Audiences&lt;br&gt;
Front-end developers spend a significant portion of their time—about 80%—interacting with a diverse range of individuals. This includes direct communication with end users, directors, external users, and even responding to feedback from people they may never meet in person. Each group brings its own unique perspectives and requirements, and front-end developers must be able to understand and address these varying needs effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic Understanding of UX and Design Principles&lt;br&gt;
Possessing foundational knowledge in user experience (UX) and design is vital for front-end developers. This expertise enables them to create interfaces that are both visually appealing and functional, ensuring that the final product aligns with user expectations and enhances overall satisfaction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Keen Eye for Detail and Perfectionism&lt;br&gt;
Much like artists, front-end developers must pay close attention to detail. Even the slightest deviation—such as a pixel out of place—will often be noticed and reported by users. Striving for perfection in the visual and interactive aspects of a project is essential, as these elements are constantly under public scrutiny.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prioritizing the Needs of End Users&lt;br&gt;
The primary goal of a front-end developer is to ensure that end users are satisfied with the final product. This means consistently considering what will make users happy, rather than prioritizing personal preferences or suggestions from other departments. The user experience should always come first in the decision-making process.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Back-End Developers: “We are men in black”
&lt;/h3&gt;

&lt;h4&gt;
  
  
  “Anonymous is your name, the silence your language, you will remember as maybe I saw you.”
&lt;/h4&gt;

&lt;p&gt;Back-end developers often operate behind the scenes, much like the agents in "Men in Black." Their contributions, though critical, generally remain anonymous to the wider world. Their achievements are challenging to showcase outside of technical circles.&lt;/p&gt;

&lt;p&gt;When it comes to presenting themselves professionally, whether on a resume or during a job interview, back-end developers may find it difficult to communicate the value of their work. They can display scripts or APIs, but these are only truly understood by other technical professionals. Non-technical individuals tend to respond with a polite “Ok, cool,” before moving on, not fully grasping the complexity or significance of the work involved.&lt;/p&gt;

&lt;p&gt;This lack of visibility extends to personal life as well. When a developer creates an app or a website, family members can proudly say, “My son made this.” However, for back-end engineers, their contributions often go unrecognized and unmentioned, even by those closest to them.&lt;/p&gt;

&lt;h4&gt;
  
  
  “You’re not belong to the system you are over the system”
&lt;/h4&gt;

&lt;p&gt;Back-end development teams frequently operate without the need to explain their actions to non-technical audiences. This is especially true when they are engaged in designing databases, adding or removing fields, executing migration processes, making critical changes, or requesting additional computational resources. Because these activities are largely invisible to end users and stakeholders outside the technical sphere, the teams can focus on ensuring the system’s stability and efficiency without needing to justify their decisions to those unfamiliar with the technical complexities involved.&lt;/p&gt;

&lt;p&gt;Team Structure and Resource Allocation&lt;br&gt;
Back-end development teams are sometimes larger than their front-end counterparts. This is often based on the understanding that the back end serves as the backbone of any software system. As a result, back-end teams tend to receive more financial and human resources. Whether or not this approach is ideal can be debated, but it reflects common practices in many organizations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Noncommon skills for Back-End Developers
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Global Risk Management&lt;br&gt;
Back-end developers must always prioritize safeguarding the entire system over accommodating minor requests. The integrity and security of information are paramount; if critical data is lost, the consequences can be catastrophic. Therefore, if a proposed change introduces risk for the sake of a few users, it is better to avoid it. Protecting the whole system is more important than meeting individual demands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintaining a Cold Mind&lt;br&gt;
Regardless of circumstances, back-end developers need to think precisely and respond quickly to problems. Unlike front-end developers, who may have others to help address visible bugs, back-end developers are often the last line of defense. When issues arise, there is no backup team; they are the backbone of the system and must solve problems directly and efficiently, even under pressure.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>discuss</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Go Redis Crud quickly example</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Sat, 17 Aug 2024 19:46:38 +0000</pubDate>
      <link>https://dev.to/luigiescalante/go-redis-crud-quickly-example-2agj</link>
      <guid>https://dev.to/luigiescalante/go-redis-crud-quickly-example-2agj</guid>
      <description>&lt;h2&gt;
  
  
  Install dependencies and environment variable
&lt;/h2&gt;

&lt;p&gt;Replace the values from database connection with yours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#env file
REDIS_ADDRESS=localhost
REDIS_PORT=6379
REDIS_PASSWORD=123456
REDIS_DB=0

#install on go
go get github.com/redis/go-redis/v9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Manager Redis
&lt;/h2&gt;

&lt;p&gt;Create a file to manage.go This will contain a method to get the connection with redis for instance in other modules and services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "github.com/redis/go-redis/v9"
    "os"
    "strconv"
)

const CustomerDb = 0

type RedisManager struct {
    Db     int
    Client *redis.Client
}

func NewRedisClient(customerDb int) (*RedisManager, error) {
    address := os.Getenv("REDIS_ADDRESS")
    if address == "" {
        return nil, fmt.Errorf("REDIS_ADDRESS is not set")
    }
    password := os.Getenv("REDIS_PASSWORD")
    if password == "" {
        return nil, fmt.Errorf("REDIS_PASSWORD is not set")
    }
    port := os.Getenv("REDIS_PORT")
    if port == " " {
        return nil, fmt.Errorf("REDIS_PORT is not set")
    }
    db := os.Getenv("REDIS_DB")
    if db == "" {
        return nil, fmt.Errorf("REDIS_DB is not set")
    }
    redisDb, err := strconv.Atoi(db)
    if err != nil {
        return nil, fmt.Errorf("REDIS_DB is not a number")
    }
    cli := redis.NewClient(&amp;amp;redis.Options{
        Addr:     fmt.Sprintf("%s:%s", address, port),
        Password: password,
        DB:       redisDb,
    })
    return &amp;amp;RedisManager{
        Client: cli,
        Db:     customerDb,
    }, nil
}
func (rd *RedisManager) SetDb(db int) {
    rd.Db = db
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Struct for manage the entity (customer) repository
&lt;/h2&gt;

&lt;p&gt;Create a struct for manage the redis connection and Get all methods to interact with the redis entity (CRUD operations and queries)&lt;br&gt;
With this struct, any time we need to access the entity (customer) data, we can instance and start to use it as a repository pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type CustomerRepo struct {
    Cli *RedisManager
    Db  int
}

func NewCustomerRepo() (*CustomerRepo, error) {
    cli, err := NewRedisClient(CustomerDb)
    if err != nil {
        return nil, err
    }
    return &amp;amp;CustomerRepo{
        Cli: cli,
    }, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Struct entity
&lt;/h2&gt;

&lt;p&gt;On Customers entity add the tags for mapped with bun fields.&lt;br&gt;
The redis:"-" make de relation with the fields to save on redis. If you want one file or the struct doenst save just dont add the tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Customer struct {
    ID    string `redis:"id"`
    Name  string `redis:"name"`
    Email string `redis:"email"`
    Phone string `redis:"phone"`
    Age   int    `redis:"age"`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CRUD methods
&lt;/h2&gt;

&lt;p&gt;A method example to store, update or get information from the entity.&lt;br&gt;
These methods are used from the CustomersRepo entity.&lt;br&gt;
They received a customer entity with the information and depending on the operation return the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Save a new record
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (c *CustomerRepo) Save(customer *Customer) error {
    return c.Cli.Client.HSet(context.TODO(), customer.ID, customer).Err()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get a record for ID
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (c *CustomerRepo) Get(id string) (*Customer, error) {
    customer := &amp;amp;Customer{}
    resMap := c.Cli.Client.HGetAll(context.TODO(), id)
    if resMap.Err() != nil {
        return nil, resMap.Err()
    }
    if len(resMap.Val()) == 0 {
        return nil, nil
    }
    err := resMap.Scan(customer)
    if err != nil {
        return nil, err
    }
    return customer, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update a new record
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (c *CustomerRepo) Update(customer *Customer) error {
    return c.Cli.Client.HSet(context.TODO(), customer.ID, customer).Err()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete a new record
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (c *CustomerRepo) Delete(id string) error {
    return c.Cli.Client.Del(context.TODO(), id).Err()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Review the code example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/luigiescalante/go-code-bucket/tree/main/redis" rel="noopener noreferrer"&gt;Redis example for test it&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>redis</category>
      <category>cache</category>
    </item>
    <item>
      <title>Go Bun ORM with PostgreSQL Quickly Example</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Mon, 12 Feb 2024 00:05:54 +0000</pubDate>
      <link>https://dev.to/luigiescalante/go-bun-orm-with-postgresql-quickly-example-394o</link>
      <guid>https://dev.to/luigiescalante/go-bun-orm-with-postgresql-quickly-example-394o</guid>
      <description>&lt;h2&gt;
  
  
  Install dependencies and environment variable
&lt;/h2&gt;

&lt;p&gt;Replace the values from database connection with yours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export DB_USER=admin
export DB_PASSWORD=admin123
export DB_NAME=code_bucket
export DB_HOST=localhost
export DB_PORT=5432

go get github.com/uptrace/bun@latest
go get github.com/uptrace/bun/driver/pgdriver
go get github.com/uptrace/bun/dialect/pgdialect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create table
&lt;/h2&gt;

&lt;p&gt;Bun have a migration system, but I think it will be required its own post. For this quickly example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create table customers(
    id serial not null,
    first_name varchar(80) not null ,
    last_name varchar(80) not null ,
    email varchar(50) not null unique,
    age int not null default 1,
    created_at timestamp not null DEFAULT now(),
    updated_at timestamp null,
    deleted_at timestamp null
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Manager DB
&lt;/h2&gt;

&lt;p&gt;Create a file to manage.go This will contain a method to get the connection db for instance in other modules and services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "database/sql"
    "fmt"
    "github.com/uptrace/bun"
    "github.com/uptrace/bun/dialect/pgdialect"
    "github.com/uptrace/bun/driver/pgdriver"
    "os"
    "sync"
)

var (
    dbConnOnce sync.Once
    conn       *bun.DB
)

func Db() *bun.DB {
    dbConnOnce.Do(func() {
        dsn := postgresqlDsn()
        hsqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
        conn = bun.NewDB(hsqldb, pgdialect.New())
    })
    return conn
}

func postgresqlDsn() string {
    dsn := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
        os.Getenv("DB_USER"),
        os.Getenv("DB_PASSWORD"),
        os.Getenv("DB_HOST"),
        os.Getenv("DB_PORT"),
        os.Getenv("DB_NAME"),
    )
    return dsn
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Struct entity
&lt;/h2&gt;

&lt;p&gt;On Customers entity add the tags for mapped with bun fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Customers struct {
    bun.BaseModel `bun:"table:customers,alias:cs"`
    ID            uint      `bun:"id,pk,autoincrement"`
    FirstName     string    `bun:"first_name"`
    LastName      string    `bun:"last_name"`
    Email         string    `bun:"email"`
    Age           uint      `bun:"age"`
    CreatedAt     time.Time `bun:"-"`
    UpdatedAt     time.Time `bun:"-"`
    DeletedAt     time.Time `bun:",soft_delete,nullzero"`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;the bun:"-" omit the field in queries.
You can review all tags option on the official bun documentation. 
&lt;a href="https://bun.uptrace.dev/guide/models.html#struct-tags"&gt;Bun tags&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create Struct for manage the entity (customer) repository
&lt;/h2&gt;

&lt;p&gt;Create a struct for manage the db connection and Get all methods to interact with the database entity (CRUD operations and queries)&lt;br&gt;
With this struct, any time we need to access the entity (customer) data, we can instance and start to use it as a repository pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type CustomersRepo struct {
    Repo *bun.DB
}

func NewCustomerRepo() (*CustomersRepo, error) {
    db := Db()
    return &amp;amp;CustomersRepo{
        Repo: db,
    }, nil
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  CRUD methods
&lt;/h2&gt;

&lt;p&gt;A method example to store, update or get information from the entity.&lt;br&gt;
These methods are used from the CustomersRepo entity.&lt;br&gt;
They received a customer entity with the information and depending on the operation return the result. &lt;/p&gt;

&lt;h3&gt;
  
  
  Save a new customer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cs CustomersRepo) Save(customer *models.Customers) (*models.Customers, error) {
    err := cs.Repo.NewInsert().Model(customer).Scan(context.TODO(), customer)
    if err != nil {
        return nil, err
    }
    return customer, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update a customer data (Required the field ID)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cs CustomersRepo) Update(customer *models.Customers) (*models.Customers, error) {
    _, err := cs.Repo.NewUpdate().Model(customer).Where("id = ? ", customer.ID).Exec(context.TODO())
    return customer, err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get a customer from one field
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cs CustomersRepo) GetByEmail(email string) (*models.Customers, error) {
    var customer models.Customers
    err := cs.Repo.NewSelect().Model(&amp;amp;customer).Where("email = ?", email).Scan(context.TODO(), &amp;amp;customer)
    return &amp;amp;customer, err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get a list of customers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cs CustomersRepo) GetCustomers() ([]*models.Customers, error) {
    customers := make([]*models.Customers, 0)
    err := cs.Repo.NewSelect().Model(&amp;amp;models.Customers{}).Scan(context.TODO(), &amp;amp;customers)
    return customers, err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete a customer (soft deleted)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cs CustomersRepo) Delete(customer *models.Customers) error {
    _, err := cs.Repo.NewDelete().Model(customer).Where("id = ?", customer.ID).Exec(context.TODO())
    return err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Review the code example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/luigiescalante/go-code-bucket/tree/main/bun-orm"&gt;BUN CRUD Example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>orm</category>
      <category>postgres</category>
    </item>
    <item>
      <title>AWS S3 (SDK v2) in Go Quickly example</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Fri, 26 Jan 2024 22:14:34 +0000</pubDate>
      <link>https://dev.to/luigiescalante/aws-s3-sdk-v2-in-go-quickly-example-ifk</link>
      <guid>https://dev.to/luigiescalante/aws-s3-sdk-v2-in-go-quickly-example-ifk</guid>
      <description>&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Get your AWS key and secrets from an Iam user in your AWS console and set as environments vars&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS_KEY= &amp;lt;aws iam user key&amp;gt;
AWS_SECRET= &amp;lt;aws iam user secret&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the go dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; go get github.com/aws/aws-sdk-go-v2
 go get github.com/aws/aws-sdk-go-v2/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ol&gt;
&lt;li&gt;Create a struct for manage the AWS Client
It's a good practice to get this struct on an independent file to used if we want to implement mor3 AWS services.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;File: manager.go&lt;br&gt;
&lt;strong&gt;Parameters:&lt;/strong&gt;&lt;br&gt;
region: the AWS region (ex. us-east-1)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const AwsKeyEnv = "AWS_KEY"
const AwsSecretEnv = "AWS_SECRET"

type AwsConfigClient struct {
    config aws.Config
    region string
}

func NewAwsConfigClient(region string) (*AwsConfigClient, error) {
    key := os.Getenv(AwsKeyEnv)
    secret := os.Getenv(AwsSecretEnv)
    prov := credentials.NewStaticCredentialsProvider(key, secret, "")
    cfg, err := config.LoadDefaultConfig(context.TODO(),
        config.WithRegion(region),
        config.WithCredentialsProvider(prov),
    )
    if err != nil {
        return nil, err
    }
    return &amp;amp;AwsConfigClient{
        config: cfg,
    }, err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a struct for manager the common types.
File: s3.go
&lt;strong&gt;Parameters:&lt;/strong&gt;
cfg : An instance from the struct config (step 1)
bucket: the name of the AWS Bucket
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type AwsS3Client struct {
    config aws.Config
    bucket string
    s3     *s3.Client
}

func NewAwsS3Client(cfg *AwsConfigClient, bucket string) (*AwsS3Client, error) {
    client := s3.NewFromConfig(cfg.config)
    return &amp;amp;AwsS3Client{
        config: cfg.config,
        bucket: bucket,
        s3:     client,
    }, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Upload a file to an AWS bucket
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Parameters:&lt;/strong&gt;&lt;br&gt;
path : the path and the file we want to upload (example: /files/test.txt)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cli *AwsS3Client) UploadObject(path string) (*manager.UploadOutput, error) {
file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer file.Close()
    client := s3.NewFromConfig(cli.config)
    uploader := manager.NewUploader(client)
    result, err := uploader.Upload(context.TODO(), &amp;amp;s3.PutObjectInput{
        Bucket: aws.String(cli.bucket),
        Key:    aws.String(filepath.Base(path)),
        Body:   file,
    })
    if err != nil {
        return nil, err
    }
    return result, nil
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Download a file from AWS bucket
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Parameters:&lt;/strong&gt; &lt;br&gt;
fileName : the name of the file in the AWS bucket&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cli *AwsS3Client) Download(fileName string) (*manager.UploadOutput, error) {
    client := s3.NewFromConfig(cli.config)
    downloader := manager.NewDownloader(client)
    file, err := os.Create(fileName)
    if err != nil {
        return nil, err
    }
    defer file.Close()
    _, err = downloader.Download(context.TODO(), file, &amp;amp;s3.GetObjectInput{
        Bucket: aws.String(cli.bucket),
        Key:    aws.String(fileName),
    })
    return nil, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete a file from AWS bucket
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Parameters:&lt;/strong&gt; &lt;br&gt;
fileName : the name of the file in the AWS bucket&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cli *AwsS3Client) DeleteObject(fileName string) error {
    objectIds := []types.ObjectIdentifier{
        {Key: aws.String(fileName)},
    }
    _, err := cli.s3.DeleteObjects(context.TODO(), &amp;amp;s3.DeleteObjectsInput{
        Bucket: aws.String(cli.bucket),
        Delete: &amp;amp;types.Delete{Objects: objectIds},
    })
    return err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get the AWS files list
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (cli *AwsS3Client) GetObjects() ([]types.Object, error) {
    output, err := cli.s3.ListObjectsV2(context.TODO(), &amp;amp;s3.ListObjectsV2Input{
        Bucket: aws.String(cli.bucket),
    })
    if err != nil {
        return nil, err
    }
    data := make([]types.Object, len(output.Contents))
    for i, object := range output.Contents {
        data[i] = object
    }
    return data, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GitHub code example
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/luigiescalante/go-code-bucket/tree/main/awstools"&gt;AWS s3 files&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Related links
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.github.io/aws-sdk-go-v2/docs/sdk-utilities/s3/"&gt;AWS S3 official documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/aws/aws-sdk-go-v2/"&gt;AWS S3 official examples&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>s3</category>
      <category>aws</category>
    </item>
    <item>
      <title>Agregar un acceso directo a una app en GNU/Linux Gnome</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Sun, 11 Jun 2023 01:34:11 +0000</pubDate>
      <link>https://dev.to/luigiescalante/agregar-un-acceso-directo-a-una-app-en-gnulinux-gnome-32mb</link>
      <guid>https://dev.to/luigiescalante/agregar-un-acceso-directo-a-una-app-en-gnulinux-gnome-32mb</guid>
      <description>&lt;p&gt;Uno de los principales problemas cuando comenzamos a utilizar GNU/Linux con la interface de Gnome en la versión 42.3 o superiores, es agregar un nuevo icono a los menús principales.&lt;/p&gt;

&lt;p&gt;Dependiendo la distribución de GNU/Linux que estemos usando puede haber opciones para poder hacerlo por medio de una interface grafica. En algunas versiones esta opción no está disponible.&lt;/p&gt;

&lt;p&gt;Para estos casos vamos a crear de manera nativa el acceso directo de una app al menú de aplicaciones. Usaremos como ejemplo la aplicación de Goland IDE de la familia InteliJ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crear un archivo de texto dentro de nuestro sistema.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo vi /home/{tuUsuario}/.local/share/applications/{nuestraApp}.desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo vi /home/kaiba/.local/share/applications/goland.desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Editar el contenido del archivo con la información de la app
&lt;/h2&gt;

&lt;p&gt;Agregar el siguiente contenido en el archivo que creamos. Cambiando los datos por los de nuestra aplicación.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Desktop Entry]
Version=13.0
Type=Application
Terminal=false
Exec=/opt/goland/bin/goland.sh
Name=Goland
Icon=/opt/goland/bin/goland.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y procedemos a buscar nuestro acceso directo en la sección de aplicaciones y ya nos aparece.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t60al_vP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nptbuzb1dg4dscpt55mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t60al_vP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nptbuzb1dg4dscpt55mh.png" alt="Image description" width="555" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Instalar Java JDK en GNU/Linux</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Sun, 11 Jun 2023 01:27:42 +0000</pubDate>
      <link>https://dev.to/luigiescalante/instalar-java-jdk-en-gnulinux-obo</link>
      <guid>https://dev.to/luigiescalante/instalar-java-jdk-en-gnulinux-obo</guid>
      <description>&lt;p&gt;Para instalar Java Jdk en linux son una serie de sencillos pasos.&lt;/p&gt;

&lt;p&gt;Descargar el paquete de Java Jdk de la pagina de Oracle:&lt;/p&gt;

&lt;p&gt;Se pude descargar de aquí. Es importante descargar la versión correcta si es de 32 o 64 bits. Ejemplo: jdk-8u40-linux-x64.tar.gz es la versión para Linux de 64 Bits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Descomprimir el paquete.
&lt;/h2&gt;

&lt;p&gt;En la terminal de Linux nos colocamos en la carpeta en donde descargamos el paquete para descomprimirlo con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tar xzfv jdk-8u40-linux-x64.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meter Java en los path de Linux&lt;/p&gt;

&lt;p&gt;Esto es para poder usar java sin necesidad de estar indicando la ruta cada vez que utilizemos Java.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurar el path
&lt;/h2&gt;

&lt;p&gt;Como super usuario y con un editor de texto como vim abrimos el archivo /etc/profile e introducimos lo siguiente al final del archivo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Java JDK
export PATH=/usr/local/jdk/bin/:$PATH
export PATH=/usr/local/jdk/jre/bin/:$PATH
export JAVA_HOME=/usr/local/jdk/jre
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Actualizar nuestras configuraciones
&lt;/h2&gt;

&lt;p&gt;Con el siguiente comando actualizamos nuestras variables sin la necesidad de reiniciar nuestro equipo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source /etc/profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comprobar que todo se instalo de manera correcta.&lt;/p&gt;

&lt;p&gt;en la terminal escribimos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y nos debera devolver lo siguiente:&lt;/p&gt;

&lt;p&gt;java version “1.8.0_40”&lt;/p&gt;

&lt;p&gt;Java(TM) SE Runtime Environment (build 1.8.0_40-b26)&lt;/p&gt;

&lt;p&gt;Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)&lt;/p&gt;

&lt;p&gt;Y con esto tenemos nuestro Java Jdk instalado.&lt;/p&gt;

&lt;p&gt;Si tenemos 2 versiones de Java en nuestro equipo ejemplo Oracle JDK y Open-Jdk podemos cambiar cual queremos usar con el siguiente comando:&lt;br&gt;
&lt;code&gt;sudo update-alternatives --config java&lt;/code&gt;&lt;br&gt;
Con esto nos muestra un listado con los JDK de Java instalados y solo tenemos que seleccionar el que queramos usar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Selection    Command
-----------------------------------------------
   1           java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.4.1.1-1.fc36.x86_64/bin/java)
*+ 2           /usr/lib/jvm/jdk-19-oracle-x64/bin/java

Enter to keep the current selection[+], or type selection number: 2    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Usar repositorios privados de GitHub en GO</title>
      <dc:creator>Luigi Escalante</dc:creator>
      <pubDate>Sun, 11 Jun 2023 01:21:25 +0000</pubDate>
      <link>https://dev.to/luigiescalante/usar-repositorios-privados-de-github-en-go-4gi0</link>
      <guid>https://dev.to/luigiescalante/usar-repositorios-privados-de-github-en-go-4gi0</guid>
      <description>&lt;p&gt;En ocasiones tenemos la necesidad de tener librerías provenientes de repositorios privados en GO, como por ejemplo librerías propietarias de la empresa, proyectos que aun estén en Sealthy Mode o funciones que no podemos exponer al publico en general.&lt;/p&gt;

&lt;p&gt;Esto en GO puede generar problemas sobre todo al momento de querer descargar nuestra librería ya que se necesita de un proceso de autenticación de nuestra cuenta de Github.&lt;/p&gt;

&lt;p&gt;Vamos a proceder a descargar una librería de un repositorio de GitHub privado.&lt;/p&gt;

&lt;p&gt;PD: Dejo el repositorio con la &lt;a href="https://github.com/luigiescalante/package-helloworld"&gt;librería de ejemplo (Como publica)&lt;/a&gt;, la cual puedes hacer un fork a tu cuenta de GitHub y volverla privada para hacer al prueba con ella.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generar token de autenticación en GitHub
&lt;/h2&gt;

&lt;p&gt;En nuestra cuenta de GitHub ingresar a la sección de Settings &amp;gt; Profile &amp;gt; Developer Settings &amp;gt;Personal access token&lt;/p&gt;

&lt;p&gt;Generar un personal access token y asignarle permisos full access private repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PoPRqD2_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf5zb2kcq6bk87g4azsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PoPRqD2_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf5zb2kcq6bk87g4azsa.png" alt="Image description" width="785" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copiarlo en algún block de notas de manera temporal, se usara mas tarde. Este token no lo vuelve a mostrar GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FYotmAl9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4uuddge5hujx2w0g13kv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FYotmAl9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4uuddge5hujx2w0g13kv.png" alt="Image description" width="800" height="293"&gt;&lt;/a&gt;&lt;br&gt;
En la terminal dentro de la carpeta de nuestro proyecto en GO&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuramos el token en Git
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global url."https://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:x-oauth-basic@github.com/".insteadOf "https://github.com/"
git config --global --add url."git@github.com:".insteadOf "https://github.com/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Agregamos una variable de ambiente en nuestro sistema para que GO reconozca el repositorio aunque sea privado y vaya a buscarlo. Cambiar el valor GOPRIVATE por tu repositorio personal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export env GOPRIVATE=github.com/luigiescalante
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Proceder a descargar en tu proyecto en GO
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/luigiescalante/package-helloworld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya puedes usar la librería privada dentro de tu proyecto en GO, Ejemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lNUSFXgq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd0lrze7ul3dqh7bgvd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lNUSFXgq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd0lrze7ul3dqh7bgvd5.png" alt="Image description" width="800" height="872"&gt;&lt;/a&gt;&lt;/p&gt;

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