<?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: Amorto Goon</title>
    <description>The latest articles on DEV Community by Amorto Goon (@mortogn).</description>
    <link>https://dev.to/mortogn</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1090060%2F62883f7f-93be-479e-a225-67bc172f6919.jpg</url>
      <title>DEV Community: Amorto Goon</title>
      <link>https://dev.to/mortogn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mortogn"/>
    <language>en</language>
    <item>
      <title>A Guide to Refresh Tokens: The Bare Minimum for Auth Security</title>
      <dc:creator>Amorto Goon</dc:creator>
      <pubDate>Sat, 15 Aug 2026 16:33:36 +0000</pubDate>
      <link>https://dev.to/mortogn/a-guide-to-refresh-tokens-the-bare-minimum-for-auth-security-38ho</link>
      <guid>https://dev.to/mortogn/a-guide-to-refresh-tokens-the-bare-minimum-for-auth-security-38ho</guid>
      <description>&lt;h2&gt;
  
  
  What motivated me to write this
&lt;/h2&gt;

&lt;p&gt;I was looking for good authentication tutorials when I was just starting with web development. Back then I didn't know any better. I came across a video on youtube and thought to myself, "WOW! It's that easy?"&lt;/p&gt;

&lt;p&gt;Most of the videos I came across back then had a lot of flaws, some were using refresh token only to refresh access tokens automatically  without doing anything else, while others were completely missing the point of refresh token.&lt;/p&gt;

&lt;p&gt;This tutorial will not make you the master of authentication but after reading this, I'm hoping you'll understand the &lt;em&gt;bare minimum&lt;/em&gt; that you need to implement a secure auth system for your web app. I'm also hoping to learn something new, and fix my own bad habits and mistake if you point it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we start
&lt;/h2&gt;

&lt;p&gt;This is going to be a general guide and not a programming language specific tutorial. However, to show coding snippets and example, I will be using Typescript as it is a popular language among web devs.&lt;/p&gt;

&lt;p&gt;In this article, we will take a look at basic auth flow, what tokens are and the use for a refresh token.&lt;/p&gt;

&lt;p&gt;In the next article in this series, I will show code snippets and how to actually implement this.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic auth flow
&lt;/h2&gt;

&lt;p&gt;When we visit a website and log into our account, we usually provide our email and password once. After that we can close the tab and even browser, but still are logged in. It'd be a hassle to log in every time we close the tab. This is why we use tokens. Once a user logs in, we send over a token from the server. After that for each request, the client/browser sends over the token and using that token we verify who the user is.&lt;/p&gt;

&lt;p&gt;Generally when we log in, the server verifies that the email and password is correct. Then the server generates a token and send it to the client. This is how the authentication flow looks like assuming the log in was successful.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fen8yjafry99i5xeqb54y.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fen8yjafry99i5xeqb54y.png" alt=" " width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the login is successful, the server sends a set of token (usually two) or session id as cookie. From there, every request will send that cookie to verify who the user is. The flow looks like this assuming the token is not expired and is correct.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flqr0s85cw1kl2t2hcyjf.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flqr0s85cw1kl2t2hcyjf.png" alt=" " width="799" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Password Hashing
&lt;/h2&gt;

&lt;p&gt;Repeat this with me, &lt;strong&gt;"Never store raw password in a database"&lt;/strong&gt;. Password is the key to our digital life and databases are not a secure home where no one can break in and steal that key.&lt;/p&gt;

&lt;p&gt;To avoid our users password getting leaked, we use a one way encryption known as password hashing.&lt;/p&gt;

&lt;p&gt;When user provides password to sign up, we hash the password and store it in our database.&lt;/p&gt;

&lt;p&gt;When user provides password to sign in, we use the password hashing algorithm's verification function to check whether the provided password matches with the hashed password.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzu1sf4z84llx43zmkn4r.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzu1sf4z84llx43zmkn4r.png" alt=" " width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a token
&lt;/h2&gt;

&lt;p&gt;In simple words, tokens in authentication are credentials that the server generates. To us, they might look like a randomized string.&lt;/p&gt;

&lt;p&gt;It has a payload that contains information that is required for secure authorization. We use these information to authorize the user to different resources.&lt;/p&gt;

&lt;p&gt;These tokens are cryptographically signed with a key. When the time comes for our server to verify the token, it verifies the signature to check if the token is valid and hasn't been tampered with.&lt;/p&gt;

&lt;p&gt;Json Web Tokens or JWT are commonly used for authentication. We store payload, that is user id for example and we set a time when the token will be expired.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why tokens should be short-lived
&lt;/h3&gt;

&lt;p&gt;Unlike traditional session based authentication, tokens can be verified without storing each of them in the database.&lt;/p&gt;

&lt;p&gt;If an attacker steals our token from a user, the attacker can pretend to be the user and use our services.&lt;/p&gt;

&lt;p&gt;We could store compromised tokens in our database, but hitting the database each time a request arrives to check if this token is compromised defeats the whole purpose of using a JWT in the first place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Short expiry time is a UX killer
&lt;/h3&gt;

&lt;p&gt;If your favorite app asks you to log in every 15 minutes, how would you feel?&lt;/p&gt;

&lt;p&gt;A shorter expiry time means our users need to log in every time the token is expired, to get a new one. To solve this issue, we can give our users two tokens, one will have aa expiry of 15 minutes and another will have a longer lifespan, like 14 days or even 30 days.&lt;/p&gt;

&lt;p&gt;When the short-lived token, A.K.A the access token expires, we can generate a new pair of token and set them as cookie.&lt;/p&gt;

&lt;p&gt;When we fresh the access token, we can store the token that was used to generate a new set somewhere (usually database). That way when a user tries to reuse an old token, we know that the token is stolen and we can immediately take action.&lt;/p&gt;

&lt;p&gt;Because we use the 2nd token to refresh the token pair. It is called &lt;em&gt;Refresh Token&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refresh token
&lt;/h3&gt;

&lt;p&gt;This is where most people mess up. The purpose of refresh tokens is to make sure our access token is short lived. That way if the tokens are stolen, we can minimize the damage.&lt;/p&gt;

&lt;p&gt;In most tutorials I've seen people just generating new tokens with refresh token when access token is expired. Some check if the user still exists in the database, and others are confused and only generate new set of tokens without verifying anything.&lt;/p&gt;

&lt;p&gt;That defeats the purpose.&lt;/p&gt;

&lt;p&gt;Ideally, when a refresh token is used, we should check if this token was already used before to generate a new set of tokens. &lt;br&gt;
Reuse of a used token is suspicious and it is better that we invalidate the entire token family as a security response.&lt;/p&gt;

&lt;p&gt;We do not know who stole the token, but we know that the token is probably stolen. In that case, we should revoke the entire refresh token family.&lt;/p&gt;

&lt;p&gt;We can mark each of our refresh tokens by a &lt;code&gt;familyId&lt;/code&gt; or something else. This information should be stored in a database to identify tokens that belong to the same token family.&lt;/p&gt;

&lt;p&gt;When a user logs in for the first time, we can create a familyId and attach it as payload to our refresh token.&lt;/p&gt;

&lt;p&gt;When access token is expired and a new token is needed, we can extract and attach the same familyId to the new refresh token.&lt;/p&gt;

&lt;p&gt;Of course a &lt;code&gt;jti&lt;/code&gt; or token id should be stored in the database along with familyId in the database. The schema should at least contain these information,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;userId - [id of the user]
familyId - [id that is attached to each refresh token]
usedAt - [timestamp when this refresh token was used, default NULL]
revokedAt - [when the refresh token was revoked, default NULL]
expiresAt - [when the token naturally expires]
jti - [primary key, unique for each refresh token]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a token is compromised, we should invalidate all the tokens with same family id.&lt;/p&gt;

&lt;p&gt;When user chooses an action to &lt;strong&gt;"Log out from everywhere"&lt;/strong&gt;, we should invalidate all the refresh tokens from our database containing the id of that user.&lt;/p&gt;

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

&lt;p&gt;To put everything together.&lt;/p&gt;

&lt;p&gt;When a user signs up for the very first time, we hash the password and store it. &lt;strong&gt;NEVER STORE PLAIN PASSWORDS TO DATABASE&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After successful login, we send two tokens to the user. Access Token and Refresh Token. Access tokens have shorter lifespan while refresh tokens have relatively longer lifespan.&lt;/p&gt;

&lt;p&gt;When access token is expired, use refresh token to generate a new access token. Prevent refresh token reuse.&lt;/p&gt;

&lt;p&gt;If we understand this much, we already have a good foundation to implement an authentication system.&lt;/p&gt;

&lt;p&gt;Of course there are many security concerns like Cookie security, CSRF protection, XSS etc but we cannot cover all of them in one article.&lt;/p&gt;

&lt;p&gt;The goal of the article is to understand why access tokens are short lived, the need for refresh tokens and a proper way to handle them together.&lt;/p&gt;

&lt;p&gt;In the next part, we will take a look at how to implement this.&lt;/p&gt;

&lt;p&gt;If you read it this far, thank you. Let me know what you think or if you know a better way this can be done.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Go + Echo: The Simple Way to Build a Web Server</title>
      <dc:creator>Amorto Goon</dc:creator>
      <pubDate>Sun, 22 Mar 2026 14:14:51 +0000</pubDate>
      <link>https://dev.to/mortogn/go-echo-the-simple-way-to-build-a-web-server-1eja</link>
      <guid>https://dev.to/mortogn/go-echo-the-simple-way-to-build-a-web-server-1eja</guid>
      <description>&lt;p&gt;Building a performant API shouldn't feel like a chore. If you're looking for a simple language that is fun and performant, look no further than go. There are a lot of frameworks for GO but today we will be choosing Echo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;TLDR&lt;/em&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project Setup:&lt;/strong&gt; Initializing a Go module&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Echo Basic:&lt;/strong&gt; Creating echo instance for route handling with v5&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing:&lt;/strong&gt; Handling Get Request&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Before we begin&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;In this guide, we will not go over how to install and setup go. It's assumed you already have go installed and configured.&lt;/p&gt;

&lt;p&gt;We are also assuming you know basic Go syntax and how to create a simple hello word program.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Project setup
&lt;/h3&gt;

&lt;p&gt;To start, we need to initialize a go module in our current working directory. Once you are in a folder where you'd like to build this application, initialize module.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Ideally, you'd put your source code location, for example &lt;code&gt;github.com/[your_username]/[repo_name]&lt;/code&gt; but for the sake of simplicity we will be using &lt;code&gt;myserver&lt;/code&gt; instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Echo Basic
&lt;/h3&gt;

&lt;p&gt;To use Echo as our framework, we need to create a main package first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Create a file and name it &lt;code&gt;main.go&lt;/code&gt;. We can also run the following command to create the file. Make sure we are still on our working directory.&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;touch &lt;/span&gt;main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Inside main file let's create a simple main function and print hello world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run our application and see &lt;code&gt;Hello World!&lt;/code&gt; printed on our terminal.&lt;/p&gt;

&lt;p&gt;To run this application,&lt;br&gt;
&lt;/p&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;&lt;strong&gt;Step 3.&lt;/strong&gt; Now that we have a basic working application, we can bring in Echo to create our server.&lt;/p&gt;

&lt;p&gt;To install Echo,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/labstack/echo/v5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4.&lt;/strong&gt; After installing Echo successfully we can start creating our API.&lt;/p&gt;

&lt;p&gt;After this guide, we want to visit &lt;code&gt;http://localhost:4000/hello&lt;/code&gt; and get a json response similar to this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello World!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To achieve our goal, let's start adding changes to our &lt;code&gt;main.go&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt; &lt;span class="c"&gt;// import net/http for HTTP status codes&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/labstack/echo/v5"&lt;/span&gt; &lt;span class="c"&gt;//import echo v5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Create a new Echo instance&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Define a route for GET requests to "/hello"&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c"&gt;// Start the server on port 4000 and log any errors that occur&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":4000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to start server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have made quite a bit of changes here. I have made to sure to add comments so we can understand what each chunk of code does even before you get to this line. However, let's a still dive a bit deeper.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Initializing Echo: Before we can use any of the functionality that echo provides us, we have to initialize it. We can do so by using &lt;code&gt;echo.New()&lt;/code&gt; and importing the echo package &lt;code&gt;github.com/labstack/echo/v5&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get request: In Echo, if we want to create an endpoint we can do so by using the variable where we stored our echo instance. Similarly we can also use &lt;code&gt;e.POST()&lt;/code&gt;, &lt;code&gt;e.PUT()&lt;/code&gt;, &lt;code&gt;e.DELETE()&lt;/code&gt; etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Returning JSON: To make our endpoint return a json response we have to use &lt;code&gt;c.JSON()&lt;/code&gt;. It accepts two parameters, one is the http status code. You might have noticed that we are using go http package to return the status code, you can also use &lt;code&gt;200&lt;/code&gt; instead of using &lt;code&gt;http.StatusOK&lt;/code&gt;. The other parameter is our response data. To return a JSON response, we are using map. We can return all sorts of data through the second parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging: Things can go south anytime, that's why we are making sure we are printing any errors that may occur, making things easy for debugging in future.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Starting the server: To Start the server, we used &lt;code&gt;e.Start()&lt;/code&gt;. Since we were planning to start our server on port 4000. We can pass &lt;code&gt;:4000&lt;/code&gt; through &lt;code&gt;e.Start()&lt;/code&gt; parameter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just like that, we now understand how to build an Echo server and a simple explanation of all the functions we used.&lt;/p&gt;

&lt;p&gt;But we are not done yet..&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Step 5:&lt;/em&gt; Now we have to test our API.
&lt;/h3&gt;

&lt;p&gt;Run our go application using,&lt;br&gt;
&lt;/p&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;If the application is running successfully, open your browser and visit &lt;code&gt;http://localhost:4000/hello&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We should see json response saying hello to the entire world.&lt;/p&gt;

&lt;p&gt;And that's it. You have successfully initialized a go module, initialized echo and created a basic performant custom api endpoint.&lt;/p&gt;

&lt;p&gt;Thank you everyone for reading! This is my first article on dev.to. I'd love to hear your feedback, or any tips you have for a new writer. Happy coding!&lt;/p&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
