There are quite a few traps for the unwary, like that a unitialized pointer to a concrete type will not test as null/nil if it was passed as any of its interface types, that channels ( for concurrenct ) isn't easy except in a few special cases, an that a closed listening socket isn't necessarily closed immediately, and all sorts of shenanigans. You could expect all those from a relatively new language, but not one that is ostensibly very simple.
If you, however, refrain from using any concurrency, interfaces, slices, and maps ( maps and slices are really reference types made to look superficially like they are passed by value ), and accept that the first element in an iteration over a string should give a different result than indexing the first element in that string.
Well, then it's as easy as it looks, for anything where you don't need to actually handle errors, or where you can always handle them where they occur. Also please do remember that log.Fatal() is actually going to kill your process, because calling os.Exit() is obviously the task of the loggin framework!
But yes, Go could have been that easy to read, but there are quite a few really odd decisions that make a lot of the apparent simplicity be rather superficial unless you happen to use a specific subset of the language.
I'm not a Go expert by any stretch of the imagination and I can tell you that almost everything you would want to know about a given request is exposed through the request object passed to your handler if you are using the standard Go http stuff.
We also have to give credit to the author. Good programmers have programs that are easy to read and understand.
However like all languages that are easy to read, it can be deceptive. Once you dive into any big/complex project. Context and design decisions matter more than anything else.