<?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: Dev Niklesh</title>
    <description>The latest articles on DEV Community by Dev Niklesh (@devniklesh).</description>
    <link>https://dev.to/devniklesh</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%2F870244%2Fd6da7031-7836-440d-af2e-837579df318c.jpg</url>
      <title>DEV Community: Dev Niklesh</title>
      <link>https://dev.to/devniklesh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devniklesh"/>
    <language>en</language>
    <item>
      <title>CRUD api with Go Gin framework (production ready)</title>
      <dc:creator>Dev Niklesh</dc:creator>
      <pubDate>Sat, 18 Jun 2022 09:56:47 +0000</pubDate>
      <link>https://dev.to/devniklesh/crud-api-with-go-gin-framework-production-ready-52jd</link>
      <guid>https://dev.to/devniklesh/crud-api-with-go-gin-framework-production-ready-52jd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is my second post on GO lang with Gin framework and PostgreSQL. Read my &lt;a href="https://dev.to/devniklesh/how-to-read-env-variables-in-golang-using-viper-2jd1"&gt;first post&lt;/a&gt; which takes you just 2 mins to setup the project and read env variables using viper!.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post, we are creating Library CRUD APIs to read data from PostgreSQL Database.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a book&lt;/li&gt;
&lt;li&gt;Delete a book&lt;/li&gt;
&lt;li&gt;Update a book&lt;/li&gt;
&lt;li&gt;Query book by ID&lt;/li&gt;
&lt;li&gt;Query all books
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Run these commands to create the necessary files needed to create the APIs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note that the project structure can be much simpler than this, but my intention is to create a production ready structure that is easy to maintain and extend the code base in future.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's create our folders,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p cmd pkg/books pkg/common/db  pkg/common/models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add some files,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch pkg/books/add_book.go pkg/books/controller.go pkg/books/delete_book.go pkg/books/get_book.go pkg/books/get_books.go pkg/books/update_book.go pkg/common/db/db.go  pkg/common/models/book.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final project structure should look something like this,&lt;br&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%2Fkq6fk7yva4quyczab8i3.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%2Fkq6fk7yva4quyczab8i3.png" alt="CRUD Project structure" width="299" height="562"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Package Installations
&lt;/h2&gt;

&lt;p&gt;Let's install the packages required,&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/gin-gonic/gin
go get gorm.io/gorm
go get gorm.io/driver/postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Book Model
&lt;/h2&gt;

&lt;p&gt;Here let's create the Book model. &lt;/p&gt;

&lt;p&gt;Let's add code to &lt;code&gt;pkg/common/models/book.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import "gorm.io/gorm"

type Book struct {
    gorm.Model
    Title       string `json:"title"`
    Author      string `json:"author"`
    Description string `json:"description"`
}

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;gorm.model&lt;/code&gt; will add properties such as &lt;code&gt;ID&lt;/code&gt;, &lt;code&gt;CreatedAt&lt;/code&gt;, &lt;code&gt;UpdatedAt&lt;/code&gt; and &lt;code&gt;DeletedAt&lt;/code&gt; for us out of the box.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Database Initialization
&lt;/h2&gt;

&lt;p&gt;Now that the Book Model is done, we need to configre GORM and auto migrate the schema we just created. This AutoMigrate function will create the books table in the database for us as soon as we run this application.&lt;/p&gt;

&lt;p&gt;Let' add code to &lt;code&gt;/pkg/common/db/db.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "log"

    "github.com/&amp;lt;YOUR-USERNAME&amp;gt;/go-gin-postgresql-api/pkg/common/models"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

func Init(url string) *gorm.DB {
    db, err := gorm.Open(postgres.Open(url), &amp;amp;gorm.Config{})

    if err != nil {
        log.Fatalln(err)
    }

    db.AutoMigrate(&amp;amp;models.Book{})

    return db
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Book Handlers
&lt;/h2&gt;

&lt;p&gt;Let's add some handlers to our Book API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Controller
&lt;/h3&gt;

&lt;p&gt;The book handlers/route will be based on so-called &lt;a href="https://go.dev/tour/methods/4" rel="noopener noreferrer"&gt;Pointer receivers&lt;/a&gt;, for that, we define its struct. &lt;/p&gt;

&lt;p&gt;This struct will receive the database information later, so whenever we call a book handler/route, we will have access to GROM. &lt;/p&gt;

&lt;p&gt;We're going to change this file once later again.&lt;/p&gt;

&lt;p&gt;Let's add code to &lt;code&gt;pkg/books/controller.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "gorm.io/gorm"
)

type handler struct {
    DB *gorm.DB
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Add Book Handler
&lt;/h3&gt;

&lt;p&gt;Here, We get the request body, declare a new book variable, merge the request body with this book variable, and create a new database entry. Then, we create a response with the book information.&lt;/p&gt;

&lt;p&gt;After the imports, we defile a struct for the request's body. You can see the pointer receiver (h handler) being used in the AddBook function. We are using h (handler) to access the database.&lt;/p&gt;

&lt;p&gt;Let's add the code to &lt;code&gt;pkg/books/add_book.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "net/http"

    "github.com/&amp;lt;YOUR-USERNAME&amp;gt;/go-gin-postgresql-api/pkg/common/models"
    "github.com/gin-gonic/gin"
)

type AddBookRequestBody struct {
    Title       string `json:"title"`
    Author      string `json:"author"`
    Description string `json:"description"`
}

func (h handler) AddBook(ctx *gin.Context) {
    body := AddBookRequestBody{}

    if err := ctx.BindJSON(&amp;amp;body); err != nil {
        ctx.AbortWithError(http.StatusBadRequest, err)
        return
    }

    var book models.Book

    book.Title = body.Title
    book.Author = body.Author
    book.Description = body.Description

    if result := h.DB.Create(&amp;amp;book); result.Error != nil {
        ctx.AbortWithError(http.StatusNotFound, result.Error)
        return
    }

    ctx.JSON(http.StatusCreated, &amp;amp;book)
}

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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Get Books Handler
&lt;/h3&gt;

&lt;p&gt;On this route, we going to return all books from our database. This works now pretty fast, but as soon as you have bigger data to handle, better go for a pagination approach.&lt;/p&gt;

&lt;p&gt;Let’s add code to &lt;code&gt;pkg/books/get_books.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "net/http"

    "github.com/&amp;lt;YOUR-USERNAME&amp;gt;/go-gin-postgresql-api/pkg/common/models"
    "github.com/gin-gonic/gin"
)

func (h handler) GetBooks(ctx *gin.Context) {
    var books []models.Book

    if result := h.DB.Find(&amp;amp;books); result.Error != nil {
        ctx.AbortWithError(http.StatusNotFound, result.Error)
        return
    }

    ctx.JSON(http.StatusOK, &amp;amp;books)
}

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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Get Book Handler
&lt;/h3&gt;

&lt;p&gt;Here, we just respond with only 1 book based on the ID which we get from a parameter.&lt;/p&gt;

&lt;p&gt;Let’s add code to &lt;code&gt;pkg/books/get_book.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "net/http"

    "github.com/&amp;lt;YOUR-USERNAME&amp;gt;/go-gin-postgresql-api/pkg/common/models"
    "github.com/gin-gonic/gin"
)

func (h handler) GetBook(ctx *gin.Context) {
    id := ctx.Param("id")

    var book models.Book

    if result := h.DB.First(&amp;amp;book, id); result.Error != nil {
        ctx.AbortWithError(http.StatusNotFound, result.Error)
        return
    }

    ctx.JSON(http.StatusOK, &amp;amp;book)
}

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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Update Book Handler
&lt;/h3&gt;

&lt;p&gt;If we add a book, we also should have the option to update created books. This route is similar to the &lt;code&gt;AddBook&lt;/code&gt; route we have coded earlier.&lt;/p&gt;

&lt;p&gt;Let’s add code to &lt;code&gt;pkg/books/update_book.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "net/http"

    "github.com/&amp;lt;YOUR-USERNAME&amp;gt;/go-gin-postgresql-api/pkg/common/models"
    "github.com/gin-gonic/gin"
)

type UpdateBookRequestBody struct {
    Title       string `json:"title"`
    Author      string `json:"author"`
    Description string `json:"description"`
}

func (h handler) UpdateBook(ctx *gin.Context) {
    id := ctx.Param("id")
    body := UpdateBookRequestBody{}

    if err := ctx.BindJSON(&amp;amp;body); err != nil {
        ctx.AbortWithError(http.StatusBadRequest, err)
        return
    }

    var book models.Book

    if result := h.DB.First(&amp;amp;book, id); result.Error != nil {
        ctx.AbortWithError(http.StatusNotFound, result.Error)
        return
    }

    book.Title = body.Title
    book.Author = body.Author
    book.Description = body.Description

    h.DB.Save(&amp;amp;book)

    ctx.JSON(http.StatusOK, &amp;amp;book)
}

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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Delete Book Handler
&lt;/h3&gt;

&lt;p&gt;This is our last route in this article. Here, we delete a book based on its ID, but only, if the desired entry exists inside the database. We only respond with an HTTP status code.&lt;/p&gt;

&lt;p&gt;Let’s add code to &lt;code&gt;pkg/books/delete_book.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "net/http"

    "github.com/&amp;lt;YOUR-USERNAME&amp;gt;/go-gin-postgresql-api/pkg/common/models"
    "github.com/gin-gonic/gin"
)

func (h handler) DeleteBook(ctx *gin.Context) {
    id := ctx.Param("id")

    var book models.Book

    if result := h.DB.First(&amp;amp;book, id); result.Error != nil {
        ctx.AbortWithError(http.StatusNotFound, result.Error)
        return
    }

    h.DB.Delete(&amp;amp;book)

    ctx.Status(http.StatusOK)
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Controller (again)
&lt;/h2&gt;

&lt;p&gt;The routes are done. Now we need to modify the controller file once again. This time, we create a function called &lt;code&gt;RegisterRoutes&lt;/code&gt;, it’s pretty self-explaining what it does, right?&lt;/p&gt;

&lt;p&gt;Do you remember the receiver pointer? Here we get the receiver pointer for our routes/handlers.&lt;/p&gt;

&lt;p&gt;Update controller code to this,&lt;br&gt;
&lt;/p&gt;

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

import (
    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
)

type handler struct {
    DB *gorm.DB
}

func RegisterRoutes(router *gin.Engine, db *gorm.DB) {
    h := &amp;amp;handler{
        DB: db,
    }

    routes := router.Group("/books")
    routes.POST("/", h.AddBook)
    routes.GET("/", h.GetBooks)
    routes.GET("/:id", h.GetBook)
    routes.PUT("/:id", h.UpdateBook)
    routes.DELETE("/:id", h.DeleteBook)
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Main File
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you are following from &lt;a href="https://dev.to/devniklesh/how-to-read-env-variables-in-golang-using-viper-2jd1"&gt;previous tutorial&lt;/a&gt;, you already have viper initialised to handle our environment variables&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are going to do a lot more here,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialise the database based on GORM&lt;/li&gt;
&lt;li&gt;Connect our Books router&lt;/li&gt;
&lt;li&gt;Starting the application&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will also make changes to this file further into the tutorial.&lt;/p&gt;

&lt;p&gt;Let's add the code to &lt;code&gt;/cmd/main.go&lt;/code&gt;&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 (
    "github.com/DevNiklesh/go-gin-postgresql-api/pkg/books"
    "github.com/DevNiklesh/go-gin-postgresql-api/pkg/common/db"
    "github.com/gin-gonic/gin"
    "github.com/spf13/viper"
)

func main() {
    viper.SetConfigFile("./pkg/common/envs/.env")
    viper.ReadInConfig()

    port := viper.Get("PORT").(string)
    dbUrl := viper.Get("DB_URL").(string)

    router := gin.Default()
    dbHandler := db.Init(dbUrl)

    books.RegisterRoutes(router, dbHandler)

    router.GET("/", func(ctx *gin.Context) {
        ctx.JSON(200, gin.H{
            "port":  port,
            "dbUrl": dbUrl,
        })
    })

    router.Run(port)
}

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

&lt;/div&gt;



&lt;p&gt;Let's run the code now,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make server

(OR)

go run cmd/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fworye8wcwdomhgqc9i0i.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%2Fworye8wcwdomhgqc9i0i.png" alt="Running the code, console output" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test out the APIs now!&lt;/p&gt;

&lt;p&gt;Now you can use this for all your micro-services and its much easier to maintain. &lt;/p&gt;

&lt;p&gt;In the next tutorial, we are going to see how to run CRON jobs using Golang. So make sure to follow me here as well as in &lt;a href="https://www.linkedin.com/in/devniklesh/" rel="noopener noreferrer"&gt;linkedIn&lt;/a&gt; to get notified about it. &lt;/p&gt;

&lt;p&gt;Please like and share, if you enjoy this series. Much Appreciated! Thanks.&lt;/p&gt;




</description>
      <category>go</category>
      <category>crud</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to read env variables in Golang using viper</title>
      <dc:creator>Dev Niklesh</dc:creator>
      <pubDate>Tue, 31 May 2022 04:55:46 +0000</pubDate>
      <link>https://dev.to/devniklesh/how-to-read-env-variables-in-golang-using-viper-2jd1</link>
      <guid>https://dev.to/devniklesh/how-to-read-env-variables-in-golang-using-viper-2jd1</guid>
      <description>&lt;p&gt;Using Env variables are one of the ways to secure your app's secrets and it is widely used in almost all the applications.&lt;/p&gt;

&lt;p&gt;You have to be aware of such production practices to secure your application!&lt;/p&gt;

&lt;p&gt;In this blog we will read environment variables (store our secret keys securely) using &lt;strong&gt;viper&lt;/strong&gt; package from GO.&lt;/p&gt;

&lt;p&gt;I have kept this post simple yet informative so, Let's jump right into it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Here we create the project structure for this tutorial.&lt;/p&gt;

&lt;p&gt;I suggest you to glance through this section even if you already have a project ready. This will help you understand this tutorial better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Start a new GO project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Go to go workspace&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd $GOPATH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create a project and go to the project&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir read-env-var
cd read-env-var
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Initialize the project&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go mod init github.com/YOUR_USERNAME/read-env-var
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Let's create the project structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p cmd pkg/common/envs pkg/common/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Create files&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch Makefile cmd/main.go pkg/common/envs/.env pkg/common/config/config.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, your project structure should look like this,&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%2Flvi9efs0zg8aa28uf66a.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%2Flvi9efs0zg8aa28uf66a.png" alt="Project structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Variables
&lt;/h2&gt;

&lt;p&gt;First, we need to add some environment variables where we store the application port and other secrets.&lt;/p&gt;

&lt;p&gt;Let’s add code to pkg/common/envs/.env&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT=:3000
DB_URL=postgres://DB_USER:DB_PASSWORD@DB_HOST:DB_PORT/go_api_medium
API_KEY=&amp;lt;YOUR_API_KEY_HERE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install viper
&lt;/h2&gt;

&lt;p&gt;Viper is the package, that we will be using to read the env variable and use it in our project&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/spf13/viper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Viper Configuration
&lt;/h2&gt;

&lt;p&gt;Let’s add code to pkg/common/config/config.go&lt;br&gt;
&lt;/p&gt;

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

import "github.com/spf13/viper"

type Config struct {
    Port  string `mapstructure:"PORT"`
    DBUrl string `mapstructure:"DB_URL"`
}

func LoadConfig() (c Config, err error) {
    viper.AddConfigPath("./pkg/common/config/envs")
    viper.SetConfigName("dev")
    viper.SetConfigType("env")

    viper.AutomaticEnv()

    err = viper.ReadInConfig()

    if err != nil {
        return
    }

    err = viper.Unmarshal(&amp;amp;c)

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Main file
&lt;/h2&gt;

&lt;p&gt;We will initialize viper to handle our env variables&lt;/p&gt;

&lt;p&gt;Let’s add code to cmd/main.go&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/spf13/viper"
)

func main() {
    viper.SetConfigFile("./pkg/common/envs/.env")
    viper.ReadInConfig()

    // add env variables as needed
    port := viper.Get("PORT").(string)
    dbUrl := viper.Get("DB_URL").(string)

    fmt.Println(port, dbUrl)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run the code
&lt;/h2&gt;

&lt;p&gt;Let add our script in MakeFile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server:
     go run cmd/main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then, run &lt;code&gt;make server&lt;/code&gt; script in terminal&lt;/p&gt;

&lt;p&gt;(or)&lt;/p&gt;

&lt;p&gt;Directly run command in terminal&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Output:&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%2Fv4d4sv7gdc66nlk2rdaf.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%2Fv4d4sv7gdc66nlk2rdaf.png" alt="Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it folks. To summarise, we&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Created a Go project&lt;/li&gt;
&lt;li&gt;Added env variables&lt;/li&gt;
&lt;li&gt;Installed viper package&lt;/li&gt;
&lt;li&gt;Added viper configuration&lt;/li&gt;
&lt;li&gt;Initialised viper in main.go file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/devniklesh/crud-api-with-go-gin-framework-production-ready-52jd"&gt;next tutorial&lt;/a&gt;, we will extend this project to add CRUD API using Gin framework. Make sure to follow and like this tutorial. Thanks for being here!&lt;/p&gt;

&lt;p&gt;Please share it with your friends &amp;amp; colleagues.&lt;/p&gt;

</description>
      <category>go</category>
      <category>viper</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
