DEV Community

Cover image for 📖 Go Fiber by Examples: How can the Fiber Web Framework be useful?
Vic Shóstak
Vic Shóstak

Posted on • Edited on

📖 Go Fiber by Examples: How can the Fiber Web Framework be useful?

Introduction

Hello and welcome, DEV friends! 👋

As you probably know, the printed book that we planned to release with Packt publisher called Easy Development with GoFiber is now canceled.

🤯 There are many reasons for this, both from my side and from the side of this respected publisher, I will not focus on this.

Therefore, I decided to release all of my written material in free access as a series of articles in my blog on Dev.to for everyone! 😉

Today, I start a new series of articles called Go Fiber by Examples, which will be a handbook for those who want to learn the Fiber web framework quickly and efficiently while developing a real web application.

Plan for the Chapter 1

In this first article (or chapter), we will take a look at the history of the Fiber web framework, find out which groups of programmers are best suited to it, and see how similar it is to Node.js framework Express, using real-world examples.

We are going to cover the following main topics 👇

📝 Table of contents

Coming from another programming language or Golang web framework

If you come from another language (such as Python, Ruby, or JavaScript), the Fiber web framework will help you to smoothly enter into the Go programming language.

It has very familiar elements and is designed to make the product development process as easy as possible for developers of different skill levels from other programming languages.

For developers who are already working with other Go web frameworks or API tools, Fiber can offer the following benefits:

  • Extreme performance and low memory footprint
  • Rapid server-side programming
  • Built-in middleware for most tasks
  • Rich and robust routing
  • Easy serve static files and work with databases
  • Support of all popular template engines
  • ...and much, much more to talk about in this series!

A friendly and supportive Fiber community around the World has already translated basic documentation into 15 different languages and is ready to support you in issues of the project repository on GitHub.

↑ Table of contents

Looking to swap NodeJS for Go

New gophers that make the switch from Node.js to Golang are dealing with a learning curve before they can start building their web applications, APIs, or microservices.

Fiber inspired by Express, the most popular web framework on the Internet. Its authors combined the ease of Express and the raw performance of Go.

And we will be surprised at how easy it is to make the transition from one language to a wholly different one, thanks to learning just the Fiber Web Framework!

🌐 Note: Also, I recommend visiting the GitHub repository by Miguel Mota called Golang for Node.js Developers. It describes the basic principles for a smoother transition of your backend from JavaScript to Go in a fairly straightforward way.

Therefore, if you have ever implemented a web application in Node.js (using Express or similar), then many methods and principles will seem very common to you.

We will discuss this in more detail near the end of this article.

↑ Table of contents

The philosophy behind using Fiber web framework

Fiber, as a web framework, was created with the idea of minimalism and follows the UNIX way, so that new gophers can quickly enter the world of Go with a warm and trusted welcome. That’s why Fiber is a very versatile Go framework.

But the main focus of its application is to create complete all-in-one web applications, like Django in Python or Ruby on Rails in Ruby, and efficient high-performance REST APIs, like FastAPI for Python.

This does not mean that you cannot create microservices or adapters for your infrastructure or even desktop network apps or else on Fiber. Absolutely no! Such areas are simply not a priority for the authors of this framework. But they always listen to its users in issues on GitHub repository, Discord channel, and all over the Internet.

The authors want to create a fast, flexible, and friendly Golang web framework for any task, deadline, and developer skill. Just like Express framework does in the JavaScript world.

↑ Table of contents

A brief comparison with Express

Being inspired by Express, the Fiber web framework may seem very familiar to you. We will break down the most basic things in the next sections, where you can see them for yourself.

👌 Note: Don't worry if you have never worked with Go or JavaScript, we have left comprehensive comments in the code examples below to help you get oriented.

Hello World

A classic example for every programming language or web framework is the minimally working Hello World program. Well, let's not deny ourselves that!

First, let's take a look at Express:



// ./js/hello_world.js

const express = require("express"); // add Express library
const app = express(); // create a new Express instance

// Create a new endpoint
app.get("/", (req, res) => {
  res.send("Hello World!"); // send text
});

// Start server on port 3000
app.listen(3000);


Enter fullscreen mode Exit fullscreen mode

Straightforward, isn't it? Just a couple of lines of code and a full-fledged web server is ready to receive users on the specified endpoint on port 3000.

And here's how the same functionality can be implemented with Fiber:



// ./go/hello_world.go

package main

import "github.com/gofiber/fiber/v2" // add Fiber package

func main() {
  app := fiber.New() // create a new Fiber instance

  // Create a new endpoint
  app.Get("/", func(c *fiber.Ctx) error {
    return c.SendString("Hello, World!") // send text
  })

  // Start server on port 3000
  app.Listen(":3000")
}


Enter fullscreen mode Exit fullscreen mode

Except for some JavaScript or Go-specific blocks at the beginning of the program, the code reads, feels, and works the same under the hood. And this state will follow us in almost all the code examples in this series.

↑ Table of contents

Basic routing and endpoints

As you know, any web application, microservice, or API includes a routing system based on endpoints describing an HTTP method and a handler function, which will be executed only after this endpoint receives a request from the client-side.

In the preceding Hello World program, we already touched the app.get(path, () => {}) (in case of Express) and app.Get(path, func() error {}) (in case of Fiber) endpoints, which serve the HTTP GET method and return a plain string when requested.

Let’s take a look at the other HTTP methods which we can use to describe the endpoint in our web application. Let's start, per tradition, with the Express:



// ./js/routing.js

// Endpoint for POST method
app.post("/", (req, res) => {
  // function that stores a new data
});

// Endpoint for PUT method
app.put("/", (req, res) => {
  // function that replaces the existing data
});

// Endpoint for PATCH method
app.patch("/", (req, res) => {
  // function that replaces part of the existing data
});

// Endpoint for DELETE method
app.delete("/", (req, res) => {
  // function that deletes the data
});


Enter fullscreen mode Exit fullscreen mode

It might seem that these HTTP methods are not enough to describe the endpoints of your web application, but in fact, Express, and Fiber support many more request HTTP methods.

☝️ Note: We have only described the most basic ones!

Now let's take a look at how the same basic HTTP methods look in Fiber:



// ./go/routing.go

// Endpoint for Post method
app.Post("/", func(c *fiber.Ctx) error {
  // function that stores a new data
})

// Endpoint for PUT method
app.Put("/", func(c *fiber.Ctx) error {
  // function that replaces the existing data
})

// Endpoint for PATCH method
app.Patch("/", func(c *fiber.Ctx) error {
  // function that replaces part of the existing data
})

// Endpoint for DELETE method
app.Delete("/", func(c *fiber.Ctx) error {
  // function that deletes the data
})


Enter fullscreen mode Exit fullscreen mode

Again, except for some blocks specific to each programming language, the code reads and works the same.

↑ Table of contents

Using middleware

The middleware functions have access to the HTTP request and response objects and the next middleware function. They can perform the following tasks:

  • Execute any code we need
  • Make any changes and modifications to the request and response objects
  • Complete the request-response loop
  • Call the next middleware function that is in the stack

We are not going to delve into middleware now. Our goal is only to compare the technical design of these web frameworks.

👌 Note: We will return to middleware in later articles of this series.

So, here is an example of a middleware function for the Express framework that outputs the current date and time to the browser console and simply passes the request to the next endpoint:



// ./js/middleware.js

// Middleware function
app.use(function (req, res, next) {
  // print current date and time to console
  console.log("Date:", Date.now());

  // passing the request to the next endpoint
  next();
});


Enter fullscreen mode Exit fullscreen mode

And this is how the same middleware will work with Fiber, but the date and time will be output to the normal terminal instead of the browser console:



// ./go/middleware.go

// Middleware function
app.Use(func(c *fiber.Ctx) error {
  // print current date and time to console
  fmt.Println("Date:", time.Now())

  // passing the request to the next endpoint
  return c.Next()
})


Enter fullscreen mode Exit fullscreen mode

Once again, we saw similarities between these web frameworks.

↑ Table of contents

Serving static files

If we want to create a Single-Page Application rather than an ordinary web application, we will need to be able to request a directory with static files.

These files are usually:

  • Images
  • CSS files
  • JavaScript files
  • HTML files
  • Template and other downloadable files

The process of working with them is based on this scheme:

  1. Define a folder to store static files.
  2. Specify it as a mount point in the web application.
  3. In the HTML file (or template) we make references to this mount point.

Let's look at a small example to get an understanding.

If we store statics in the ./public folder at the root of our directory, then using the Express built-in express.static() function, we can mount it at /static address as follows:



// ./js/static.js

app.use(
  "/static", // mount address
  express.static("public") // path to the file folder
);


Enter fullscreen mode Exit fullscreen mode

And here's a sample code for Fiber that will do the same thing for us:



// ./go/static.go

app.Static(
  "/static",  // mount address
  "./public", // path to the file folder
)


Enter fullscreen mode Exit fullscreen mode

As a result, all static files for both Express and Fiber will be available at the following address:



http://localhost:3000/static/images/background.jpg 
http://localhost:3000/static/css/style.css 
http://localhost:3000/static/js/app.js 
http://localhost:3000/static/index.html


Enter fullscreen mode Exit fullscreen mode

With this approach, we can easily set up a proxy server, such as NGINX, to send static files more efficiently.

↑ Table of contents

Working with templates

When we build a web application that not only has to return content in JSON format but also has to be able to render templates with that content, template engines come to the rescue.

Both web frameworks support a huge number of template engines right out of the box: Pug, Jade, Mustache, Handlebars, and many others. Let's take a look at the Pug engine to see how a template renders in Express works:



// ./js/templates.js

// Initialize Pug template engine for rendering
app.set("view engine", "pug");

// Initialize templates folder
app.set("views", "./views");

// Create a new endpoint
app.get("/", (req, res) => {
  // rendering the "index" template with content passing
  res.render("index", {
    title: "Hey!",
    message: "This is the index template.",
  });
});


Enter fullscreen mode Exit fullscreen mode

For Fiber, the same example will be a little more complicated but will remain just as familiar. The reason for this is that the configuration of the application cannot be changed after the Fiber instance has been created. It is read-only.



// ./go/templates.go

// Initialize Pug template engine in ./views folder
engine := pug.New("./views", ".pug")

// Create a new Fiber instance
app := fiber.New(fiber.Config{
  Views: engine, // set template engine for rendering
})

// Create a new endpoint
app.Get("/", func(c *fiber.Ctx) error {
  // rendering the "index" template with content passing
  return c.Render("index", fiber.Map{
    "Title":   "Hey!",
    "Message": "This is the index template.",
  })
})


Enter fullscreen mode Exit fullscreen mode

⚙️ Note: Both frameworks will only look for templates with *.pug extension in the ./views folder of the current directory. If this folder does not exist or does not contain a file named index.pug, an error will happen.

Even though Express and Fiber written in different programming languages and by different development teams, they have a very similar technical design of built-in functions and working principles. This is what makes Fiber so special among many Go-based web frameworks.

We will explain this in more detail later in the future articles.

↑ Table of contents

Summary

We hope this article of the series has shown you a different side of the Go language, if you've only ever written code for your web applications in JavaScript before.

Furthermore, we do numerous new things:

  • We learned what Fiber is good for and where it can be used effectively.
  • We compared the basic functions of the Express and Fiber web frameworks.
  • Dismantled the routing system of web frameworks using simple examples.
  • Understood what middleware is and how to work with it in Fiber.
  • We looked at an example of how Fiber works with static files.
  • We found out what popular template engines Fiber supports out of the box and how to work with them.

In the next articles, we will get even closer to the inner workings of the Fiber web framework, its built-in components and methods.

↑ Table of contents

Photos and videos by

P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.

support me on Boosty

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My main projects that need your help (and stars) 👇

  • 🔥 gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
  • create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.

Other my small projects: yatr, gosl, json2csv, csv2api.

Top comments (10)

Collapse
 
artydev profile image
artydev

Awesome,
Thank you very very much :-)

Collapse
 
bengarrett profile image
Ben

Hi Vic, thankyou for the series of articles on this. I have couple of questions.

In the /go/routing.go sample there is

// Endpoint for PATH method
app.Path("/", func(c *fiber.Ctx) error {
  // function that replaces part of the existing data
})
Enter fullscreen mode Exit fullscreen mode

Should this be Patch? There doesn't seem to be a Path method in fiber/v2 and app.patch is also used by routing.js.

Also in /go/templates.go there is no mention of the module that needs to be imported for pug?

Collapse
 
koddr profile image
Vic Shóstak

Hi,

Should this be Patch? [...]

Wow, nice catch! My bad... Thanks, I fixed it in article 👍

[...] Also in /go/templates.go there is no mention of the module that needs to be imported for pug?

Function for Pug (and other supported template engines) was included to gofiber/template module. Call it, like this: github.com/gofiber/template/pug.

Collapse
 
lexiebkm profile image
Alexander B.K.

I have a question of using Pug :
How to iterate on array/slice/map in Pug ?

For single values, we know the following will work :
h4= .Title
h4= .Message

This works too :
h4 #{.Title}
h4 #{ .Message}

But, how to use the usual pug syntax for iteration like the following ?
ul
each val in ["Java", "Go", "Rust", "C++", "FoxPro/Clipper"]
li= val

I have searched for this, but haven't found anywhere.

Collapse
 
jhoval profile image
Mauro Franchini

Thanks for sharing and writing this blogposts.. as someone said earlier, it's a shame that the development of the book stopped, but I guess it's for a good reason. Keep it rolling! Thanks for the time invested :)

Collapse
 
marcello_h profile image
Marcelloh

A pity the book is not coming, but the very good thing is, that you're willing to share.
(and written in an understandable way :-) )

Collapse
 
nasoma profile image
nasoma

Amazing! Looking forward to the series. I have dabbled with Gin but have been looking to give Fiber a try. This series will be a great help.

Collapse
 
koddr profile image
Vic Shóstak

You're welcome! New article is coming 😉

Collapse
 
junihh profile image
Junior Hernandez

I love it. Waiting for the next article. 😛

Collapse
 
rngallen profile image
Luqman Jr

A good post about fiber. I always find how to use fiber to create API's, I would like to ask if you will share how to use fiber to save html templates as well as static files.