Create authorization header for Cosmos DB with Go

I started a side project to create a client package for Cosmos DB SQL API with Go so I can try Go in a real project. My plan is to implement something similar to .NET Core SDK with Go. As this is a project for learning and practice, I will do it little by little, and there is no timeline regarding when it can be done.

I build the project based on SQL API via REST. To access resources in Cosmos DB with SQL API via REST, an authorization header is required for the requests. The value of the authorization header has the following format, as it is mentioned in this document.

type={typeoftoken}&ver={tokenversion}&sig={hashsignature}

In the above string, the values of type and version are simple: type is either master or resource, while the current version is 1.0. The value of signature is a bit complex. It is a hash of several other values by using the access key of Cosmos DB as the hash key. The document has all details in it and even better it has a sample written in C#.

So following the document and the sample, I implemented a Go equivalence as follows. It is a good example to try the base64 encoding and HMAC hash in Go.

The date format in the signature is required to be in HTTP-date format defined by RFC7231. However, the time package in the Go standard library doesn’t seem to support this format out of the box, but it provides a very easy way to create custom format. The utcNow() function in the above code is what I implemented to format the time to RFC7231 format.

Go语言笔记

最近接了个业余任务,给对Go语言感兴趣的同事讲讲Go语言是怎么回事。

说起来我对Go语言也不是很懂。记得我第一次听说Go,是在大概2011年的时候。那时听说Google开发了一种新语言,看了一眼,留下的第一印象是丑。那时候我正好在研究比特币是怎么回事,没时间玩这个新语言。2013年的时候,Go忽然在国内火了起来,很多网站开始用Go来写后台。我于是好奇这个语言有什么特别,花了点时间了解了一下。只是在工作中一直没有机会用,所以也谈不上精通了。这次趁着准备这个技术分享,我又深入学习了一下Go语言。

准备材料的时候,我在想怎么跟有其他语言经验的人介绍Go。我觉得作为一个简介,如果能回答好下面三个问题,应该就算不错了吧。

什么是Go?

不同于C#或Java这样依赖虚机的语言,或者Python这样的解释型动态语言,Go是一种编译型的静态类型语言,更接近C。实际上,C是直接影响go的语言之一。看看Go的三个创始人的背景,就大概知道Go会有怎样的基因了。编程语言领域转了一圈又回来了,十几年前我刚工作时,C/C++几乎一统天下。后来为了解决内存管理问题,Java和C#流行起来。然后随着机器性能的提升和解释器的改进,Javascript和Python在不同的领域崛起。现在随着云计算的普及,静态编译语言如Go和rust又开始流行了,所不同的是,它们提供了比C/C++更好的内存管理。

Go的最突出的几个特性是,可编译;静态类型,但也有部分类型推导;垃圾收集,这是其它大部分编译型静态类型语言所没有的;基于CSP(Communicating sequential processes)的并发编程;等等。

这两年,Go语言社区成长很快。据说Go是2017年,GitHub上用户增长最多的语言。而stack overflow的2017年开发者调查中,Go是most loved第五名,most wanted第三名,足见其火爆。

Most Wanted vs. Most Loved

为什么需要Go?

可是我们已经有无数种编程语言了,为什么还需要go呢?这就要从go试图解决什么问题说起了。根据go的创始人之一,Rob Pike,的说法,go的设计初衷是为了解决两个问题:

  1. Google的问题:big hardware, big software. 编译慢;依赖关系复杂;每个程序员都有自己的风格,不易合作;缺少文档;升级困难;经常重复造轮子;等等。
  2. 让Go的设计者的日常工作能够更轻松,生活更美好。

为此,Go的设计哲学遵循了下面两条核心规则。

  1. 极简:使用类Pascal语法,语法简单,关键字少;不支持类,继承,泛型等语言特性。
  2. 正交:数据结构和方法分开,通过聚合而非继承来联系二者;类型抽象通过接口实现;数据结构和接口都可以通过内嵌的方式来扩展。

虽然关于Go的设计哲学,不同的人可以列举出不同的项目,但极简和正交是最重要的两条。这两条使得Go简单易学,容易上手。这是Go受欢迎的重要原因之一。

但也由于这两条哲学,我觉得导致Go,至少是Go 1,并没有很好的解决所有它的设计者打算解决的问题。比如,Go的依赖通过package实现,但是它并没能解决大型项目的依赖问题。这个问题Go通过不同的package试了好几次,不过看来又要推倒重来,Go 1.11会有新的依赖管理工具。再比如不支持泛型,导致重复造轮子变成了免不了的问题。这些都是Go在大受欢迎的同时,为人诟病的问题。

目前Go有哪些应用场景?

目前看了,Go使用比较多的场景,还是在服务端的后台程序。容器领域里,Go俨然成为了标准语言。Docker, Kubernetes等等都是Go编写的。根据Go 2017 Survey的结果,其它go比较流行的领域包括中间件,微服务等等。Go比较不适合用来写桌面GUI应用。