# theflyingcoders > Go backends that take off and stay up. Go APIs and platforms, AI-assisted delivery without quietly dropping the review bar, and performance work on systems nobody else wants to touch. theflyingcoders is Mark Smith, a platform architect in Belfast writing about Go backend engineering: repo layout and architecture, error handling, OpenAPI spec-driven services, caching, testing, and AI-assisted delivery. The blog is the reasoning behind the work. ## Pages - [About](https://theflyingcoders.dev/about/): who is behind theflyingcoders and how the work is done. - [Services](https://theflyingcoders.dev/services/): what an engagement looks like. - [Contact](https://theflyingcoders.dev/contact/): how to get in touch. ## Work - [An interactive history of the Abbasid Caliphate](https://theflyingcoders.dev/work/abbasid-history/): A scroll-driven history of the Abbasid Caliphate, 750 to 1517, with a map that reshades as the empire grows and shrinks. Static HTML and a little Alpine, hosted free on Pages with no build step. ## Blog - [Spec-driven development: the OpenAPI file is the source of truth](https://theflyingcoders.dev/blog/spec-driven-development-openapi/): When I start a new service, I do not write the HTTP handlers by hand. I describe the API in an OpenAPI file first, and the handlers are generated from it. The compiler then will not let the spec and the code drift apart: you change the spec, run one command, and the build stays broken until the handlers match. I would not build a JSON API any other way now, and the reason is the mess it replaced. - [A REST error taxonomy: frozen codes and three shapes](https://theflyingcoders.dev/blog/rest-error-taxonomy/): If your API can return an error in fifty different JSON shapes, your clients handle none of them and everyone ends up parsing a message string with a regex. So pick a small fixed set of shapes, give every error a stable code, and never let an endpoint invent its own. This is the taxonomy I put on every API, and it is the other half of the lathos post from last time. - [Behaviour-driven error handling: lathos and one global handler](https://theflyingcoders.dev/blog/behaviour-driven-error-handling-lathos/): An error is a not-found because it says it is, not because of what type it happens to be. That one idea is what lets me delete the pile of errors.Is blocks out of every handler and put the whole HTTP-status decision in a single place. Here is how it hangs together, with the library I use for it, lathos. - [How I use sub-agents: separation of powers for writing Go](https://theflyingcoders.dev/blog/how-i-use-sub-agents/): One agent that writes the code, writes the tests, and reviews its own work has a problem you already know from humans: it grades its own homework. When a test it wrote fails against code it wrote, the cheapest way out is to edit the test, and a keen agent will take it. So I do not run one agent. I keep a handful of narrow ones, and I draw hard lines between what each of them is allowed to touch. - [How this blog is built and hosted for nothing](https://theflyingcoders.dev/blog/how-this-blog-is-built/): This site has no server and costs nothing to run. Here is the whole stack, why every piece is the boring choice on purpose, and how fast I can stand one up for you. - [How I lay out a Go repo: three layers, one direction](https://theflyingcoders.dev/blog/how-i-lay-out-a-go-repo/): Domain imports nothing and internal owns the logic. Transports hold none of it, whether that is an HTTP handler or a queue consumer, and the data layer swaps under the service without a handler noticing. - [Three is a pattern: conventions that survive generated code](https://theflyingcoders.dev/blog/three-is-a-pattern/): An agent will happily write the same function four times in four files, each slightly different, each passing its own test. So will a tired human on a Friday. The volume just went up, so the habit that keeps a codebase coherent has to be written down where anyone, and anything, working in the repo will read it. Here is the one I lean on hardest.