Skip to content

Go API-first and Database-first demo app with OpenAPI v3 and sqlc/xo codegen, OIDC auth, React TypeScript frontend, end to end tracing with OpenTelemetry and a smart Bash repo task manager.

License

danicc097/openapi-go-gin-postgres-sqlc

Repository files navigation

openapi-go-gin-postgres-sqlc

Go Report Card GoDoc tests

Example full stack app with an API-first and Database-first approach with OpenAPI v3, sqlc+xo codegen, generated backend, frontend client and validators and an unimaginative title.

What's this for?

An example fully featured app to showcase how an OpenAPI v3 spec and database schema become a real single source of truth at once. Any change to it is validated and cascades down to:

  • frontend: autogenerated complex, customizable and fully type-safe UI forms based on the OpenAPI spec converted to JSON schema. Generated API queries (orval). User-friendly generated client-side validation (via react-hook-form and ajv plus customized kin-openapi error messages for backend errors). Check out the frontend home page for available links.

  • backend: generated Gin server (custom oapi-codegen and post-generation). Request and response validation (kin-openapi). Generated CRUD and index queries via xo and custom queries via sqlc by leveraging custom xo template generation that ensures compatibility. Integrated OpenID Connect client via zitadel/oidc (and dockerized authorization server for development in cmd/oidc-server based on reusable mock server with generics in oidc-server). App events processing via Server Sent Events.

    Queries generated by xo use pgx exclusively and includes pagination, indexes, soft delete handling, extensible queries (parameterized where, having clauses), joins and much more (see xo integration tests) that will get you 95% there without resorting to ad-hoc queries. Found an edge case or want additional functionality just for your DB needs? Just edit xo-templates/, since codegen is interpreted by yaegi. Additionally, by using pgx, models can be easily re-exported as usable OpenAPI schemas via openapi-go and some magic Bash and Go utility programs that keep generated code in order.

    Since using DB models in all backend layers is considered an anti-pattern at some level of model complexity, you're not tied to generated schemas from DB models. Any struct can become a spec schema via openapi-go struct tags and some simple bash code behind to grab them, with minimal caveats. See rest package. It is even possible to reference openapi spec models in your xo generated models, as long as they don't create any circular dependencies. Since at the last generation step we generate all spec schemas back to Go models with oapi-codegen to a shared models package, this is not an issue (although you'd have to choose what models to use, since there'll duplication for the models that were already generated by openapi-go in the first place - ideally, use the originals).

Additionally, it features OpenTelemetry in both browser (automatic and manual instrumentation) and backend services (manual instrumentation) via Jaeger, TimescaleDB and Promscale (discontinued, should look at options like mimir).

Makefile alternative

You get dynamic x function and x options parameters documentation and autocompletion (complete -C project project) for free (from your own source itself and comments) so they're always up to date without any repetitive work: add/remove functions and flags at will. Custom internal autocompletion functions for each x function or x option can be easily setup.

All calls to x functions are logged (distinguishing stdout and stderr) for easier parallel execution and nested calls tracking:

And help for any x function is easily searchable when the app inevitably grows with --x-help:

Setup

Configuration and local development

Fill in .env.template's:

find . -name ".env*.template"

For dev environment, you may use env.ci as a starting point, replacing ci with dev and using REVERSE_PROXY_API_PREFIX="" since it will run the backend without docker containers.

Assuming a recent Ubuntu release:

sudo apt install direnv -y
direnv allow # you can also customize direnv with .envrc.local as you would a regular .envrc, see example

cp openapi-go.code-workspace.example openapi-go.code-workspace # edit as desired

project bootstrap # dependency and tools interactive installation
project gen
project recreate-shared-services
project run.all

For first test run:

project test.backend.setup
project test.backend
project test.frontend

Tracing, monitoring...

bin/deploy-instrumentation

Notes on code generation

Docs WIP:

  • Backend generation pipeline
  • Frontend generation pipeline
  • External tooling summary and upgrades

Architecture

Simplified:

Changelog

  • v0.2: discard OpenAPITools/openapi-generator with custom postgeneration for deepmap/oapi-codegen. Any change to fix broken generator functionality requires opening a PR or a disturbing amount of postgeneration code. Templates getting out of hand and also require a PR for custom functions. oapi-codegen much more extensible and idiomatic being already Go and properly maintained.

Known issues

  • Nested functions in project's x functions will break automatic documentation for that particular function due to a bug in declare where the last nested function line number is returned instead of the parent.

TODOs

  • Meaningful project name.

  • System design docs/diagrams.

About

Go API-first and Database-first demo app with OpenAPI v3 and sqlc/xo codegen, OIDC auth, React TypeScript frontend, end to end tracing with OpenTelemetry and a smart Bash repo task manager.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published