Go and Network API: The Silver Bullet

27 Sep 2017

 

First of all, what do we mean by the term “network API”? It’s simple: we’re referring to any API that’s called remotely. This includes mobile app backends, the AJAX backend for a single page site, RTB services, internal data exchange services for the complicated distributed application, and so on.

Let’s say we’ve been working with network APIs every day for last 10 years. We have favorite libraries, test suites, etc for the languages we’re using. Should we throw them away and switch to the Go programming language?

Yes, we should — let me explain why.

Below are the standard requirements for network API software:

  • A network API is usually designed to be part of something bigger. The API itself is fixed and changes are hard to implement, since they could affect every single part of the application.
  • Most of the APIs we’re dealing with are just gateways to something else, like DB or a more sophisticated service. There’s no need to implement a complicated logic, or to utilize complex computations. Instead, we simply accept a request, get the answer from an underlying system, and return a result.
  • Most of the network API tasks are pretty standard — the specs are usually straightforward enough just to implement them.
  • Network API software requires massive parallelism. It’s important that we to utilize the power of our multicore CPU to minimize our overhead.
  • High performance is a prerequisite — we need our APIs to be CPU-effective.
  • Long-term support is required. We cannot remove or recreate any of the individual APIs since each is an integral part of the larger system.

Keeping this list in mind, let’s take a look at the options we have today to create a network API.

Network API Option 1: PHP / Python / Perl

Traditional PHP/Python/Perl was the natural choice 20 years ago.

Pros:

  • Large community to provide support
  • Extensive open source library

Cons:

  • These are interpreted languages, and therefore it’s hard for them to compete with compiling ones
  • The parallelism overhead is too large — there is no suitable way to write concurrent code. This is not ideal.

 

Network API Option 2: PHP / Python / Perl + Event Loop or Node.JS

This combination may cross our minds when we realize traditional programming languages are not suited to handle today’s requirements.

Pros:

  • JS is the world’s largest developer community, and Node.JS programmers make up the bulk of the JS crowd. PHP/Python/Perl eventloops developers are also highly active.
  • There’s also a sizeable open source library, which addresses almost any need you could imagine.
  • The parallelism overhead is smaller

Cons:

  • These languages perform a task, return, and then call you later to perform the next task, which makes it difficult to implement business logic.
  • Most of your app’s actions happen inside the eventloop, which makes this option a nightmare to maintain. When we experience an error, it’s difficult to isolate which part of our code caused it.

Network API Option 3: Java

Java is a little too bloated, but it’s excellent in terms of performance and maintainability.

Pros:

  • Sizeable community with excellent support
  • Extensive open source library. It’s rare to find a need that’s not already covered.
  • Topnotch performance — JVM is fast and NIO buffers are highly effective.
  • Excellent parallelism support. The JVM threads subsystem is advanced and the Java NIO subsistem is effective as well.

Cons:

  • Enterprise-grade ecosystem — yes, this is a con, not a pro. This is the main reason the development community complains about Java being “slow.” The libraries and tools are optimized for large, complicated enterprise tasks.
  • Not suitable for small services and utilities. JVM is a bit bloated, difficult to install, and so on.
  • Substantial RAM footprint. Remember, Java’s enterprise users are equipped with enterprise hardware.
  • Java can be difficult to maintain. Every Java app is complex, due to the fact that the Java ecosystem is complex. You need your app compiled, you need all the JARs you use, and you need the JVM itself. You need the startup scripts and you need them to start your JVM with the right parameters. We can overcome this complexity, at least partially, by using uberjar for deploy, etc. — but these solutions are not ideal.
  • Java is not suitable for the agile development cycle. The language allows you to build an amazing class hierarchy — however this hierarchy would be incredibly difficult to adjust after completion. This is my humble opinion, though I know some may disagree.

Network API Option 4: .Net

.Net — another enterprise-grade tool. It has its strengths, but…

Vendor lock is bad. Period.

Network API Option 5: C and C++

C and C++? Are you kidding? Where to begin…

Pros:

  • Performance is unmatched. We all know we have to use C or C++ if we need to reach our hardware’s peak performance.

Cons:

  • A network API needs to be composed of stable, error-free code — however it’s difficult to write safe code in C and C++.
  • Difficult to support. Do you know any large C++ project you can support if its author is not available? Me neither. Its difficult to audit a specific line of C++ code without familiarizing yourself with the entire project.
  • Most C and C++ libraries are designed to be as compact as possible, and they frequently lack documentation

Network API Option 6: Go

Finally, Go, in all its glory and majesty.

Pros:

  • Go has a fairly large community — it’s not as big as the JS community, but it’s quickly growing as the language gains more momentum
  • Helpful open source library — it’s not huge in terms of lines of code, but excellent in terms of coverage.
  • Easy to write — the language is very compact.
  • Easy to maintain — Go is famous for its readability. It’s actually difficult to write a line of code which isn’t self-explaining.
  • Go comes close to matching the performance of JVM and C++ on some tasks, despite it being a compiling language.
  • Excellent parallelism support. The green threads mapped to the OS threads pool, accompanied by the event-driven IO backend is highly effective.
  • Suitable for both small utilities and heavily loaded network services. Small utilities are small and self-contained, while heavy loaded services are fast and effective.

Cons:

  • Since the language is young, most Go developers have backgrounds in other languages. This means they’re bringing other architecture approaches with them, which are not always suitable for Go. This can get messy.
  • There are not many junior Go programmers, since nobody tends to learn it as their first language. However, this means most of the developers who know Go are open-minded and willing to challenge themselves to expand their skillsets. So, is this really a con?

Conclusion

Of course, this analysis is just my point of view, based on years of experience. When constructing a network API, every organization must assess their unique needs and select a solution that meets them. What technology works for one company many not work for another. However, I urge you to consider Golang for the next net API project you work on.