Quick Summary:
Enough of assumptions about the strict Golang programming language. Cutting the rumors out and hearing it straight from an experienced developer, how and what it feels working with Golang.
This blog is a kick-starter for those who want to learn and start working with Golang. Do share your feedback on this blog in the comments below. Also share it with your friends if you find it useful.
Table Of Content
The Domination of Golang
The very first thing that you need to know about Golang is that it is a very dominating language. If you want to write an optimum Golang code, you need to inherit the coding standard set by it. Golang is just like the terrifying aunt in the neighborhood who’d scream at you if your ball goes in her yard. Add one extra unused variable, and the code won’t run at all, start the variable name with a small case letter, and you won’t be able to use it anywhere. Declare a function inside a package starting with a small case, and you won’t be able to use it anywhere else. Golang is pretty serious about its linting and documentation. If you strictly follow the rules and get along with them, Golang is ergonomic and intuitive. And that helps when you code in other languages too. Your coding standards(even for other technologies) start improving after you do one project in Go.
Coding in Golang is not just about getting the work done or expressing your thoughts or what you have like an idea of a mere algorithm. If you take up a code snippet from C or C++ or Java and translate it to go, it has very little chance of being optimum. To be truly able to get the best out of Golang, you need to understand the gifts that the language has to offer.
Why Golang?
The main reason behind Google to develop Go is to overcome the main two problems it faces. First, COMPILE TIME: Google builds up software that is so gigantic that it takes hours and hours to complete the build. To build up Chrome from scratch, it takes up to 5 hours even on a big fat i7 system. Second up, STRING PROCESSING: Google spends a lot of time reading and analyzing web pages. Which are Strings? Lots and Lots of Strings. Thus, it helps to be efficient. Therefore, in Go, they have mainly focused on a quick compilation and fast string processing. Google has built up a profound library for string manipulations. Even the Garbage Collection in Go makes strings efficient and straightforward to think about unlike some other string libraries (C++). As Golang is statically typed and with the help of efficient linting, go compiles too quickly without the need for dependency checking, thus reducing the expense incurred in creating the build.
Also Read:
Go Benefits & Use-Cases
How to code in Packages?
The approach that I mainly follow in creating golang packages is to set it up in the abundance of different small packages. That is isolated and encapsulated within themselves. So what should an efficient package in golang contain? According to me, a package in Go should include the following:
1. Data Types are relevant to the package. This will consist of the structs used in the package. I also prefer creating mutex locks on particular local resources.
type Data struct { Size float64 Name string mu sync.Mutex cache map[string]string } - The `mu sync.Mutex protects the Cache used below it.
2. The use of interfaces for behavior definition, functions, or methods for logical execution on the structs created.
3. The functions that are the main CRUX of the package. The ones that contain the main logic.
4. And for the last but not least. Differentiate between the functions or structs that need to be private and the ones that need to be public.
The practice that I think is the most suitable is to have a file in each package named `init.go.` In this file, there would be the basic and necessary setup for the package. Default Values, refresh tokens, launching different goroutines, etc.
Let’s have a look at the project structure I am working with. The main.go file (not shown in image) is the entry point for any go program. It starts the execution and will import the server from the service package.
As it is visible, each different aspect is bifurcated into a different package.
The  rethink package is for reading, connecting or writing into the rethink database.
The auth package is for performing the authentication and the jwt token based logic.
The config package is for manipulating or reading the configurable files.
Now as all the packages cover different aspects, we can write unit tests for each independently. You see the service_test.go file placed in the service package. Similar to it you can have a separate test file for each package.
Beware For The Middleware
Implementing Middleware is one of the most important and useful points. A lot of issues that come with serving content can be handled using simple middleware. Else you’ll require repetitive and annoying code at way too many places. May it be authentication or header checks or even if it is gzip-ing your response. These features are typical for all web services, which can create a lot of pandemonium if you don’t plan them well.
The idea for it is as simple as it can get. All we need to do is create a function that accepts the handler function. Wraps it up with the custom authentication and returns a request handler at the end. The pseudo-code for it is as below:
func MyHandler(h *http.Handler) *http.Handler { return http.handlerFunc(func(w http.ResponseWriter, r *http.Request){ fmt.Println(“Doing job before calling the actual handler”) h.ServeHttp(w, r) fmt.Println(“Doing job after calling the actual handler”) }) }
As all the extra logic of the handlers are coded differently, what we can do is, we can modify our requests or the response object for all the basic stuff as per our heart’s desire. And the controller logic is left with just the implementation logic.
This comes in handy when all you need is to do a few alterations in every request and response object the Apis process and server. Now I would advise to write up by yourself. The modifications become super easy. But if you don’t want to do so. There are plenty of custom packages available that you can download.
Made up your mind for Golang programming language for your upcoming project?
Our salient Go developers will materialize your idea.
Hire Golang Developers Now!
Custom http.Client turned interceptor
It is really frequent in our backend that we need to make API calls to different services for data. We might scrape some data of a custom website or hit up google for location details. But the requirement to make network calls will arise. So the easiest solution that comes to mind is to use HTTP.Post(…) Method predefined in Go’s HTTP package. BUT PLEASE DON’T!
Instead of using the default HTTP Client object to make the network calls, what we can do is to write up a separate function that defines a custom client object. And the first thing that you should do is to SET A NETWORK TIMEOUT. The default HTTP. The client DOES NOT have a timeout. So the amount of time required if the Third-Party API is down will increase the response time way too much.
Image Source
So how do we convert this HTTP.Client to an interceptor? Or what will be the use of it? Well if the interceptor is well coded, then that function will be the singular pipe, that every network call will have to pass through. If so, you can apply authentication, redirections, modifications of res/req, and many more things. This function will be the junction, where you can do all so awesome stuff aside from just making the network calls. Whatever you want, you name it; you got it! Statistics, analytics, customization, redirection logic. Your creativity enforces the limits. Here is a code that I use myself:
// Fetch makes network calls using the method (POST/GET..), the URL // to hit, headers to add (if any), and the body of the request. // Feel free to add more stuff to before/after making the actual n/w call! func Fetch(method string, url string, header map[string]string, body io.Reader) (*http.Response, err) { // Create client with required custom parameters. // Options: Disable keep-alives, 30sec n/w call timeout. client := &http.Client{ Transport: &http.Transport{ DisableKeepAlives: true, }, Timeout: time.Duration(10 * time.Second), } // Create request. req, _ := http.NewRequest(method, url, body) // Add any required headers. for key, value := range header { req.Header.Add(key, value) } // Perform said network call. res, err := client.Do(req) if err != nil { glog.Error(err.Error()) // use glog it's amazing return nil, err } // If response from network call is not 200, return error too. if res.StatusCode != http.StatusOK { return res, errors.New("Network call did not return SUCCESS!") } return res, nil }
Conclusion
All this code will do is use your written HTTP. Client to make the network call for you. You can use and modify the code given above to measure response time, log metrics of error cases, modify cookies, etc. In case if you don’t know how to get it done, then hire Golang developer from us and leverage our top-of-the-line Golang development services Go ahead, have fun!
From one Gopher to all of you out there, keep building amazing stuff, stay awesome!
FAQs
-
What are some of the unmatched features of Go language?
No Generics, Single Executables, and no dynamic Libraries are the three unmatched features of Golang.
-
Which solutions does Go provide?
Some of the amazing results that Golang offers:
⦿ Speedy compilation and execution
⦿ Reliable code & documentation
⦿ Language consistency
⦿ Program versioning facilitation
⦿ Development with multiple languages
⦿ Dependency maintenance -
Can we say that Go is OOP language?
The answer is both- yes and no. Golang is an object-oriented language, but still, it doesn’t follow any hierarchy./p>
-
Can I use Golang as a scripting language?
Yes, you can use Golang in place of scripting languages such as javascript.
-
What are the drawbacks of using Golang?
Go’s interface methods do not support default implementations, Go lacks generics, it is quite a naive and young programming language, and there is no reusability opinion with Go.