Setting up a simple web server in Go with gofiber
Tags: webdev, go, beginners
Published: 2020-08-12 23:01:23

---
title: Setting up a simple web server in Go with gofiber
published: true
description: Building a basic web api in go using gofiber. Developers familiar with node.js and express.js will feel right at home with a very similar experience.
tags: [webdev,golang,beginners]
//cover_image: https://direct_url_to_image.jpg
---

This is the first part in a series of posts on building a full stack web application using vanilla JS, CSS, and Go. My goal is to show newcomers how to use the basics and very few dependencies to get something running across the entire stack. We want to demonstrate that we can build an entire application end-to-end including: a database, front-end single page application, components, an api, a front-end router, static content, authentication, modern reusable css and more. To start things out, we're going to build a simple web server that returns some data and basic HTML content.

## Installation

You're going to need to setup Go on your system if you haven't already. Head on over to https://golang.org/ and install the latest version of Go.

You can also use `gvm` to manage your Go installation. https://github.com/moovweb/gvm works great for this. 

Once you have `gvm` setup it is as simple as:

```
gvm install go1.15
gvm use go1.15 --default
```

Next up, instead of using the standard `net/http` that comes apart with `go` we are going to use `gofiber` https://gofiber.io/ to run our web server. Let's dig into that now.

## Why gofiber?

Performance optimizations with zero-copy memory overhead is one of the reasons to use gofiber. While performance benchmarks aren't always a great reason to choose a library, mostly because you are unlikely to run into these kind of issues until your project is massive. If you run into scaling problems, that would be called *a good problem to have*. In any case, you can check out some of the in depth benchmarks here https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite and https://docs.gofiber.io/benchmarks. Here's just a simple comparison from that benchmark page comparing Go fiber to Express.js 

```
Fiber      -   6,162,556 responses per second with an average latency of     2.0 ms.
Express -      367,069 responses per second with an average latency of 354.1 ms.
```

If you're coming from Node.js and Express you will the experience very familiar. Much of the ergonomics of fiber is modeled after express. Take a look at the simple `hello world` here:

```go
package main

import "github.com/gofiber/fiber"

func main() {
  app := fiber.New()

  app.Get("/", func (c *fiber.Ctx) {
    c.Send("Hello, World!")
  })

  app.Listen(3000)
}
```

## Hello Go!

We want to do a bit more than `hello world`, so let's add a route for when someone encounters a page we don't have yet. To start, create a new folder and call it `foobar`. Inside `foobar\` create a file called `main.go`. This is where we'll have our code below:

```go
package main

import "github.com/gofiber/fiber"

func main() {
    app := fiber.New()

    app.Get("/hello", func (c *fiber.Ctx) {
        c.Send("Hello world!")
    })

    app.Use(func(c *fiber.Ctx) {
        c.SendStatus(404) // Not found
    })

    app.Listen(3000)
}
```

To build it, you can use `go build` command below inside the `foobar\` directory. 

```go
go build .
```

> Fun Fact! You can use `go fmt main.go` to format the files. If you want to find out more about the `gofmt` command you can use `go doc cmd/gofmt` for detailed information. `go doc` is like `man` for go!

Now that you have a built package. You can run it with:

```
./foobar

____ / ____(_) /_  ___  _____   HOST   0.0.0.0  OS      DARWIN
_____ / /_  / / __ \/ _ \/ ___/   PORT   3000     THREADS 8
  __ / __/ / / /_/ /  __/ /       TLS    FALSE    MEM     16G
    /_/   /_/_.___/\___/_/1.13.2  ROUTES 3        PID     49104
```

You can check to make sure it's working with a simple curl or your browser.

```
curl -v localhost:3000
*   Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 3000 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Date: Wed, 12 Aug 2020 22:54:54 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 9
<
* Connection #0 to host localhost left intact
Not Found* Closing connection 0
```

And for the actual route we have:
```
curl -v localhost:3000/hello
*   Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 3000 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /hello HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 12 Aug 2020 22:55:13 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 12
<
* Connection #0 to host localhost left intact
Hello world!* Closing connection 0
```

## Helmet

If you're coming from Express.js, you may be familiar with https://github.com/helmetjs/helmet which helps secure various HTTP headers. Fiber has a similar middleware package for helmet that does the same thing. You can set that up with:

```
go get -u github.com/gofiber/helmet
```

Then in your hello world code above:

```go
package main

import (
    "github.com/gofiber/fiber"
    "github.com/gofiber/helmet"
)

func main() {
    app := fiber.New()

    app.Use(helmet.New())

    app.Get("/hello", func (c *fiber.Ctx) {
        c.Send("Hello world!")
    })

    app.Use(func(c *fiber.Ctx) {
        c.SendStatus(404) // Not found
    })

    app.Listen(3000)
}
```

## Conclusion

For more information, I suggest taking a deeper look at the documentation here https://docs.gofiber.io/ IMHO you should take advantage of great reference documentation as much as possible. When that doesn't work, you can go further by reading the code implementation itself. I have learned so much over my career learning how other projects work by reading their code in depth. It has helped me understand the fundamentals a lot better. 
Happy coding and stay tuned for the next post in the series!

If you liked this post, check out my post on [Debugging Go in VS Code](https://dev.to/nyxtom/debugging-in-go-in-vs-code-1c7f)! Thanks! Don't forget to like and follow :)