I started with Golang not too long ago, and I loved the fact that I can create a web application with a couple of lines of code. But, as always frameworks help to take that web application to places. Being a practical person who develops apps for side projects and for a living, I cannot simply overstate this fact. A production application is not simply a matter of responding to a hello world
JSON and frameworks take care of the routine tasks of providing structure, connecting to database, enforcing security and so on.
From get go, I liked Fiber framework.
Fiber is an ExpressJS inspired framework -
- easy for NodeJS developers to pick up
- fast (I mean really fast - see benchmarks)
- easy to develop
- flexible
Coupled with Go’s simplicity, light-weight nature, ease of async programming and deployment, Fiber is a formidable (albeit simple) tool to quickly develop web apps.
Also see: a small-scale developer’s view of NodeJS vs Golang.
In this post, let us see an example of developing simple CRUD APIs in Fiber v2. We will not be using an ORM or a database to keep things focused on Fiber and Golang.
Start with Go
First, download and install Go on your computer.
Ensure that your favourite editor (= VSCode) has support to code Go programs.
If you are looking at this in 2020, you may also need to enable Gopls
in VSCode to enable better module support and more modern features. Hit Ctrl + Shift + P
> type Settings
> Hit Enter
. Type in @ext:golang.go gopls
to see Go extension settings. Scroll down and enable Go: Use Language Server
.
You are all set.
Project Structure
Create a folder on your computer and open that folder in VSCode.
Create a new file server.go
. Code in the following -
|
|
Open terminal in VSCode (Ctrl + ~
) and run program.
|
|
You should see an output message if everything works fine.
Get started on Fiber
Enter below command in the VSCode terminal to install fiber.
|
|
We will now start coding the API in server.go
.
|
|
We have done a few simple things here -
- defined a basic structure for our todo using
type Todo struct {}
. We also provided the JSON equivalents of the fields - created a simple array of type
Todo
-var todos = []Todo{{ID: 1, Name: "abc", Completed: false},}
- initiated fiber with
app := fiber.New()
- enabled logging input requests with a single line
app.Use(logger.New())
- enabled a simple response at root using
app.Get("/", ...)
Run the program again using go run server.go
.
Use a REST client (like Insomnia), invoke your API at http://localhost:5000/
to see a hello world
response.
You can start seeing similarities with Express server in the simple program - more will follow.
At this stage, you may observe that any change you make will require a restart of server. There are multiple ways of solving this problem including using our dear own nodemon
. Let us stick to a Go solution though - we will use a package called air to monitor for changes in our project folder and restart server whenever there are changes.
In your VSCode terminal, input -
|
|
You can stop your own Go server and simply type -
|
|
The above command will run your server and automatically restart it whenever there are changes.
Onwards then.
(Pseudo) CRUD APIs in Fiber
Let us code in the APIs in our program.
Get Request
Introduce below line in main
function before app.Listen(":5000")
line.
|
|
Create a new function below main
.
|
|
The function is (more or less) self-explanatory. The pointer c
is fiber context that is injected in our function by fiber framework. We just return an ok
with our todos
array data. Simple enough.
Test the get
API using the URL http://localhost:5000/todo
and GET
method from the REST client. You will see the below JSON response.
|
|
Post Request
Introduce a new line after GET request in server.go
.
|
|
As it was earlier, create a new function called postTodo
-
|
|
We have accomplished quite a bit, but nothing out of ordinary -
- specified how our input JSON will look like (
request
struct) - included a body parser middleware to fetch input JSON data
- fetched the incoming data using
todo
variable - appended
todo
to ourtodos
array - returned a success message back
The below code block takes care of error checks (in our case, this handles parse errors) -
|
|
This type of error handling is typical to a Go program. Error checks are handled by an if
statement that checks error
returned from a previous statement.
Create a POST request in your REST client - http://localhost:5000/todo
. Input the following JSON as input -
|
|
Send the request and you will get the same response back. Do a GET request with the same URL and you will see the additional todo
record in the response.
Of course, we are dealing only with a variable that stays in memory. The changes will disappear when the server shutsdown or restarts.
Note: the id generation logic is flaky. We used the length of the array and increment by 1. Ergo, deleting a record can lead to duplicate ids.
Delete Request
You know the drill by now.
Introduce a new REST service in main
..
|
|
Create a new function..
|
|
We have used a new function for string type conversion. Include the package in the import
statement.
|
|
A couple of things to take note -
- We are not manipulating the array directly since the array itself but creating a new array each time there’s a change with this line
todos = append(todos[0:i], todos[i+1:]...)
. Not effective, but works. Instead we could have used a pointer and updated array directly. - We are using a convenient shortcut provided by fiber to create response JSON on the go -
fiber.Map{"error": "Record not found"}
Patch Request
Patch is similar to delete
- except that we change an element instead of removing it.
Include a new function call in main
.
|
|
Create the function.
|
|
All Code in One Place
We have created a program using Fiber to perform CRUD operations, but on a local variable. With a couple of more packages and a few lines of code we could connect to a DB and get to a more real-world program.
The below code represents the final state. You may also refer to this Git repo for the full code.
|
|
Now go create your magic. Enjoy Go!