📰 Good News app. Backend in Golang. Project creation, Go Modules & GIN integration.

I am glad to see you on the second article out of six in this chapter.

If you are not familiar with what I am going to implement in this series of chapters, I would recommend you to read the introductory article:

All chapters of a “book”:

  1. 📰 Good News app. Backend in Golang behind Traefik reverse proxy with https available.
  2. [in progress] 📰 Good News app. Flutter for rapid mobile applications development.
  3. [in progress] 📰 Good News app. Hummingbird as a promising replacement for frontend frameworks.

And here are articles of current chapter:

  1. Prerequisites & Idea, project and database structure and API endpoints.
  2. Project creation, go modules & GIN (beautiful framework) integration.
  3. Colly usage.
  4. MongoDB setup using official Golang driver.
  5. Running all together locally with Docker and Docker Compose & Traefik v2.0 configuration.
  6. Publishing to Digital Ocean, Let’s Encrypt and DNS Challenge configuration.

So let’s start!

In this article we are going to create simple Golang project and run it. After it is successfully done, we will work with Go Modules, integrate GIN framework, launch simple server and get to know how to access environment variables in our project.

All the code with detailed comments is published in my Github repository that you can use to check current steps during the post progress if you misunderstand anything 🙂

Project creation

I suppose that you have followed all prerequisites from the first article and now you have everything installed. If that’s so, then we can start creating our project.

In order to do it correctly, go to where your $GOPATH is located. You can check it by typing go env in terminal and in the beginning of the list you will find it. Then create an empty folder good-news-backend under $GOPATH/src/github.com/<your_github_or_any_username>/. Please create folders which are absent on your machine. Inside our folder create a file main.go in any convenient editor for you (I am using VSCode).

So now we need to check if everything was created right. Let’s just print some string inside main function in main.go.

I suppose that you have your terminal opened in a root folder of the project, or if you are using VSCode, just open its built-in terminal with shortcut Ctrl + `. So now you can type go build, then ./good-news-backend and you should see Good news! printed.

So now as our project is created and everything works as intended, we can start using Go Modules in order to manage libraries which are being used in a project. It is integrated tool of Golang and if you would like to read more details about it, please follow this link.

First thing we need to do is to turn on GOMODULES. Fast and easy way to do it is to type export GO111MODULE=on in terminal. After that type go mod init and you will see that go.mod file was created inside the project folder. All the information about libraries used in the project will be located in it. Basically, Go Modules are used to avoid situations of having different versions of libraries while working on the same project. So if you clone the repository of this project from Github, I will be positive that we have the same versions of all libraries.

As we are going to use GIN web framework, let’s add it now and we will check if everything works. So you have to install it via go get tool — type it in the terminal go get -u github.com/gin-gonic/gin as mentioned in their Github repository. Now you will see that our file go.mod was changed and a new file go.sum was created.

One more note before proceeding to GIN integration, while developing any Go project, it makes sense to have all used libraries downloaded inside project folder so compiler knows where to refer to when importing a library in code. So Go Modules helps us to achieve it by typing go mod vendor and downloading all already imported libraries in code to vendor folder in the root of our project. However if you try to do it now, it will say go: no dependencies to vendor because we have not imported GIN yet so we will do it soon. One more hint for future projects — there is no need to upload vendor folder to a git repository (by adding it to .gitignore) because when we clone it we can run go mod vendor and it will download all needed libraries. And now we can start configuring our web server using beautiful GIN framework.

GIN (beautiful framework) integration

It is time to start integrating GIN framework and finally create first fake endpoints, launch the server on localhost and see the result. For the integration I have decided to separate it to as many small files as possible for better understanding and smoother maintaining in the future.

We are going to have only one function call inside the main.go file. As it was already mentioned in the previous article, we have /server folder where two files will be located which will do all the magic. They are server.go where GIN server launch is taking place as well as some pre-launch settings such as pre-filling a database with news sources and types information but the code for this will be added later in this post. Other file is routes.go where all endpoints will be described.

Before writing some code to those files, we need to know in which mode our server is going to be launched. There are two modes which are provided by GIN and they are debug and release. We use debug mode when we are on stage of development of a project so we can see extra information about incoming requests. However release mode is used when we run our backend in production. You can find more information about it in GIN docs.

So in order to set a GIN backend mode separately from the codebase, we will create file with environment variables that will contain this information and also it will be useful in the future when we will be adding some more configuration variables, for example, for MongoDB setup. Create .env file in the root folder (where main.go is located) and add this line to it API_GIN_DEBUG_MODE=true. To get access to environment variables in our project, I am going to use envconfig library that is easy to manage and set up. First of all we need to download it via go get github.com/kelseyhightower/envconfig, it will add some lines to go.mod and go.sum files. After that step is finished, please create utils.go under /utils folder and add the following code to it.

The code is pretty much easy to follow because it has comments for each logical element for better understanding. So here we create a struct that has all the environment variables (we will add more in the future) in the .env file. Also we have two functions to initialise it that will be called right before our server is launched and to get environment variables so we can use them during our server is running.

So now we can add some code to our server.go inside /server folder.

For now in this file we initialise our environment variables from utils package that was created earlier, create our new router which implementation will be in routes.go file and then run the server on port :6969. And the following code is for routes.go file.

As you can see here we have the NewRouter() function that we are using in server.go file within the same package. In this function we get environment variables and set a mode for GIN server depending on the variable we have set before in .env file. Then we create an instance of GIN, add some useful middlewares (you can read about them in GIN Github repository), set a static endpoint for serving images which will be located on our server and are going to be used in our mobile apps. Then we set API endpoints in a very beautiful and clear way that is provided by GIN with grouping routes.

In order to have our images available from our server, we have added router.Static("/images", "./images") in routes.go. We have to download and put those images under images/ folder. And in the end of this article we will check their availability.

Now is a good time to download libraries to the vendor folder. Type go mod vendor in terminal and then you can check the folder and it will contain all libraries that we have imported in our code.

It will show an error because now we don’t have any controllers however we can see that NewsController is being used. As you know in Golang instead of OOP approach, we create a struct and then “add” methods to a struct so only object with this type could call those methods. And in order to separate logic for each controller, we can create different structs and corresponding methods for them. Now we will fix the error and add some basic responses for each described route in routes.go. You need to create news.go file under /controllers folder and add the following code below.

Here you can see that we create a struct NewsController for intuitive usage and we add extra methods for this controller. Now we see that there are three methods Get, GetSources and GetTypes which are used for corresponding endpoint in /server/routes.go. Each of those methods returns simple response in JSON format. In the future we will add the code that we need with fetching data from database and checking for more errors.

So now as we finish configuring our GIN server, we have to launch it in our project entry point that is main.go file. After pasting code below, save the file and it should import needed file if you have previously installed Go extension for VSCode.

And it is a good time to check if GIN integration is working correctly and all endpoints return what we expect from them. We have to build our project by typing go build and then ./good-news-backend. If there are no errors, GIN server is running on port :6969.

And now open the browser and visit three endpoints which we described earlier.

  • News — localhost:6969/v1/news
  • News sources — localhost:6969/v1/news/sources
  • News types — localhost:6969/v1/news/types

And check availability of the images added earlier in this article.

  • images/secret_mag.png — localhost:6969/images/secret_mag.png
  • images/the_village.png — localhost:6969/images/the_village.png
  • images/theory_and_practice.png — localhost:6969/images/theory_and_practice.png

Also you will see some information about each request in terminal.

In order to stop server just press Ctrl + C while your terminal is active.

I am glad that you have read this far 🙌 Below you will find the link to the next article.

If you have any comments or suggestions, please feel free to write them down or email me at batr@ggc.team 🙂

If you would like to know when I post new articles, follow me on twitter 🐦

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Batyr

Batyr

Problems solver. Open Source Staff. MS in CS. https://batyr.io