Building enterprise-grade microservice using Go (GoLang).

Rajat Nigam
FAUN — Developer Community 🐾
5 min readNov 13, 2019

--

A step by step guide for developing microservice using close-to-metal programming language. It trumps in performance as compared to any other enterprise programming language.

A classic user management Microservice

Go(GoLang): A next-gen programming language for enterprise

Most of the modern times DevOps tools are written in Go, for example, Docker, etcd, Kubernetes, Terraform or ist.io. Each of these tools has a huge codebase. A large compilation time would have been spent if these codebases were written in C++/Java.

Small-sized projects can be written in almost any programming language. But, consider a scenario where a large number of developers collaborate under time-bound releases of a project that contains millions of lines of code.

This may lead to the following problems:
1. Long compile time.
2. Multiple programming styles by individuals.
3. Dependencies on many external libraries, that may now don’t exist in there original format.
4. Partially complete documentation

Go can come to rescue, alleviating these large engineering pains.

The following are the key features that will strengthen your confidence in Go.

1.Companies that are already using GoLang

  • Google
  • YouTube
  • Apple
  • Dropbox
  • Docker
  • BBC
  • The Economist
  • The New York Times
  • IBM
  • Twitter
  • Facebook

2. Funding
The funding of Go is backed by Google. Its originators are Robert Griesemer, Rob Pike, and Ken Thompson who previously contributed to writing C, B, Unix, and JVM.

3. Skyrocketing contribution
Go is an open-source language. And for being cleaner, better and effective it is very important for a programming language to be open-source.

There is a whole community of GoLang developers (known as Gophers) which is increasing really fast. They are committed to making the language better and eliminate any bug.

4. Superfast
Go has simple syntax and structure. It devoid classes and type inheritance. It has only functions, so it is easy and fast to learn. It is compiled so it provides faster feedback, shorter time to market, faster development and easy to maintain.

5. Made for concurrency
So far GoLang has claimed its excellence in concurrency. The concurrency in Go is aiming for this simple principle, Do not communicate by sharing a memory, instead share memory by communicating.

Many people misunderstood concurrency with parallelism. Go is designed to address concurrency. And Concurrency is not parallelism.

Thanks to goroutines, channels, and garbage collection concurrency are made to implement in a much effective and simple manner as compared to C/C++/Java.

6. Cross-Platform
Go works on many platforms Windows, Linux, Unix, and BSDs, also on mobile devices.

7. Garbage Collection
Go has its own garbage collector for automatic memory management. It increases performance and makes concurrency more efficient.

8. Cleanliness
Go is a compiled language. It has strict types. It is statically typed. It forces developers to write neat and clean code. Which minimizes the chances of introducing errors.

Comparison with Java

Go Vs Java

Blueprint for my example with code snippet

Controller Layer

An HTTP web framework Gin is used to create the controller layer. It’s Github documentation claims that APIs written in Gin perform 40x faster than other frameworks.

user_controller.go

Logging Layer

The code-base contains two implementations of logging.
Logrus: Structured, pluggable logging for Go.

log/logrus/logger.go

Zap: Blazing fast, structured, leveled logging in Go. This library is released by Uber.

log/zap/logger.go

Difference between Logrus and Zap:
Logrus implementation is more or less the same with the zap implementation with one difference being how we implement the WithFields method. Logrus creates a new type called logrus.Entry when we try to call a WithFields on Logrus.Logger.

Unit Testing

Testify: Go code (Golang) set of packages that provide many tools for testifying that your code will behave as you intend.

mvc/domains/userDao_test.go

Mocking

As we are going to test the service layer, the DAO layer should get mocked for a while.

Difference between Integration and Unit Testing
In Unit Test the intent is to verify or validate a small piece of code. The scope of the test case for the service layer is confined and only limited to itself. In order to place that limitation, the DAO layer has to get mock.

In Integration Testing, the test case is intended to validate the whole application. The request starts from the controller, and reach up to the persistence layer while executing its corresponding business logic written in the service layer. The response gets captured and sent via the same path. A typical integration test places the in-memory data source for the DAO layer.

mvc/services/user_service_test.go

Implementing OAuth

To avoid code duplication and the resulting problems, we can use NGINX to validate access tokens on behalf of backend services. This has a number of benefits:

  • Requests reach the backend services only when the client has presented a valid token
  • Existing backend services can be protected with access tokens, without requiring code changes
  • Behavior is consistent for every error condition, including missing or invalid tokens
oauth-api/src/api/controller/oauth/oauth_controller.go

Nginx Configuration for OAuth

auth_request.conf

proxy_cache_path /var/cache/nginx/oauth keys_zone=token_responses:1m max_size=2m;

location /_oauth2_send_request {
internal;
proxy_method POST;
proxy_set_header Authorization “Bearer SecretForOAuthServer”;
proxy_set_header Content-Type “application/x-www-form-urlencoded”;
proxy_set_body “token=$http_apikey&token_hint=access_token”;
proxy_pass localhost:8080/oauth/access_token;

proxy_cache token_responses; # Enable caching
proxy_cache_key $http_apikey; # Cache for each access token
proxy_cache_lock on; # Duplicate tokens must wait
proxy_cache_valid 200 10s; # How long to use each response
proxy_ignore_headers Cache-Control Expires Set-Cookie;
}

Conclusion

We have created a RESTful Microserservice in Go and successfully implemented the following:
1. MVC architecture.
2. OAuth API
3. Unit Tests

Links

Please click on the following link to view the complete code.

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--

I'm a lifetime student of software engineering. Professionally I work in the capacity of Individual Contributor, Trainer, Lead Engineer and an Architect.