pokedex-go/README.md

2.5 KiB

Pokedex README

A simple Go-powered REST API kata.

HTTP Server

  • KISS: Use built-in http package. https://gin-gonic.com/ looks cooler but also adds dozens of dependencies 😮 No need for a "fully-featured" web framework.

Protobuf

Why? Separation of concerns; do not expose database/domain internals. Structs in pokemon.go should not leave the package. The .proto file serve as the official "contracts".

Is this over-engineered or what? On top of that, protojson's performance is much worse:

goos: darwin
goarch: arm64
pkg: pokedex/rest
BenchmarkJson-8        	 1275931	       928.9 ns/op
BenchmarkJson-8        	 1292184	       926.6 ns/op
BenchmarkJson-8        	 1292647	       926.0 ns/op
BenchmarkJson-8        	 1291228	       926.3 ns/op
BenchmarkJson-8        	 1294453	       927.3 ns/op
BenchmarkProtoJson-8   	  772567	      1510 ns/op
BenchmarkProtoJson-8   	  766005	      1517 ns/op
BenchmarkProtoJson-8   	  779281	      1512 ns/op
BenchmarkProtoJson-8   	  774534	      1513 ns/op
BenchmarkProtoJson-8   	  771370	      1511 ns/op
PASS
ok  	pokedex/rest	16.500s

And that's with indent! Without:

BenchmarkJson-8        	 4067257	       266.6 ns/op
BenchmarkJson-8        	 4503345	       266.5 ns/op
BenchmarkJson-8        	 4512295	       266.9 ns/op
BenchmarkJson-8        	 4505510	       266.7 ns/op
BenchmarkJson-8        	 4482391	       267.4 ns/op

The question then becomes: why use a .proto file to exchange a contract at all, if you're not using gRPC?

Swagger

Big bummer: annotations contain endpoint duplication...

Optimizing the binary

See Makefile; use https://upx.github.io/ to package after stripping some debug info.

Somehow doesn't work on OSX (process killed)?

Interesting philosophical questions

  1. Where should routing be defined? Central or with the domain package (which doesn't seem to be the idiomatic Go way?)
  2. To use or not use DTO or response objects?
  3. How to handle dependencies without dragging in Yet Another Unneeded Framework?
  4. Custom error wrapping or not?
  5. Custom Go web frameworks that ease muxing and exponential back-offs or not?
  6. Where should db migration go? Reusability in tests?