惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
IT之家
IT之家
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
U
Unit 42
爱范儿
爱范儿
博客园 - 聂微东
F
Fortinet All Blogs
V
Visual Studio Blog
Blog — PlanetScale
Blog — PlanetScale
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
L
LangChain Blog
雷峰网
雷峰网
B
Blog RSS Feed
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
H
Hackread – Cybersecurity News, Data Breaches, AI and More

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I got tired of setting up Go projects from scratch, so I ...
Alexey · 2026-05-17 · via DEV Community

Before I wrote any actual business logic in my last project, I spent days just setting up the infrastructure around it. Parsing configs, writing Dockerfiles, wiring up Compose, connecting Postgres and Redis, getting the server to actually start. At some point I just gave up and went to play Dota instead.

I'd done this before in .NET — dotnet new generates a working project from a template in seconds. Go has nothing like that out of the box. So I built it.

It's called gofro.


What it does

One command:

gofro new myapi --postgres --redis --grafana --github johndoe --git

Enter fullscreen mode Exit fullscreen mode

You get:

  • cmd/main.go with graceful shutdown wired up
  • Config loading via koanf (TOML + env vars, env wins)
  • Docker Compose with only the services you asked for
  • Multi-stage Dockerfile
  • pgxpool connection + goose migrations runner (if --postgres)
  • go-redis client (if --redis)
  • Prometheus scrape config + Grafana in Compose (if --grafana)
  • OpenAPI spec + oapi-codegen setup so you can define your API and generate typed handlers
  • Generic storage layer — GetAll, GetOne, Create, Update, Delete over pgx
  • Module path set to github.com/johndoe/myapi automatically
  • git init if you pass --git

Then go mod tidy and docker compose up -d and you're writing actual code.


Why I built this instead of using something existing

Coming from .NET, dotnet new was just there. Pick a template, get a project, start working. In Go I kept doing the same dance every time: copy the config parser from the last project, rewrite the Compose file, remember how pgxpool initialization works, set up graceful shutdown again.

The last time I did it was for a college logistics platform. I had a tight deadline, hadn't touched Go in a while after a stressful hackathon, and spent way too long just building the scaffolding before writing a single handler. That's when I decided to just solve it once.

gofro is opinionated. It picks the stack for you — chi for routing, koanf for config, pgx for Postgres, goose for migrations, oapi-codegen for API generation. If you want something different, it's probably not for you. But if you're fine with that stack, you skip a day of setup.


The flags

--postgres    pgxpool + goose migrations + generic storage layer
--redis       go-redis/v9 client
--prometheus  Prometheus scrape config
--grafana     Grafana in Compose (enables --prometheus automatically)
--github      sets module path to github.com/<nick>/<project>
--module      full custom module path
--git         runs git init

Enter fullscreen mode Exit fullscreen mode

You can mix and match. Minimal API with no databases:

gofro new myapi --github johndoe

Enter fullscreen mode Exit fullscreen mode

Full stack with observability:

gofro new myapi --postgres --redis --prometheus --grafana --github johndoe --git

Enter fullscreen mode Exit fullscreen mode


What the generated project looks like

myapi/
├── cmd/
│   └── main.go              # graceful shutdown, signal handling, dependency wiring
├── configs/
│   ├── config.toml          # base config
│   └── prometheus.yml       # only with --prometheus
├── internal/
│   ├── api/
│   │   ├── api.swagger.yaml # define your endpoints here
│   │   ├── gen.go           # go:generate directive for oapi-codegen
│   │   └── oapi-codegen.yaml
│   ├── config/
│   │   └── config.go        # struct + koanf loader + DSN helpers
│   ├── database/
│   │   ├── postgres.go      # only with --postgres
│   │   └── redis.go         # only with --redis
│   └── handler/
│       └── server_impl.go   # Server struct, JSON(), Run()
├── pkg/
│   └── storage/
│       └── storage.go       # only with --postgres
├── migrations/              # only with --postgres
├── docker-compose.yml
├── Dockerfile
├── .env
└── Makefile

Enter fullscreen mode Exit fullscreen mode

The workflow after generation:

  1. Define your API in internal/api/api.swagger.yaml
  2. Run make generate — oapi-codegen produces typed models and the server interface
  3. Implement the interface methods on the Server struct
  4. Run docker compose up -d and go run ./cmd/

The generic storage layer

This is the part I use in every project. It's built on go-sqlbuilder and pgx, works with any struct via generics:

// SELECT with optional filter
users, err := storage.GetAll[User](ctx, "users", db,
    func(sb *sqlbuilder.SelectBuilder) {
        sb.Where(sb.Equal("active", true))
    },
)

// SELECT one
user, err := storage.GetOne[User](ctx, db, "users",
    func(sb *sqlbuilder.SelectBuilder) {
        sb.Where(sb.Equal("id", id))
    },
)
if errors.Is(err, storage.ErrNotFound) { ... }

// INSERT
err = storage.Create(ctx, "users", newUser, db)

// UPDATE — skips fields tagged `immutable` (like created_at)
err = storage.Update(ctx, "users", user, db,
    func(sb *sqlbuilder.UpdateBuilder) {
        sb.Where(sb.Equal("id", user.ID))
    },
)

Enter fullscreen mode Exit fullscreen mode

Fields tagged db:"-" are skipped on insert. Fields tagged immutable are skipped on update. No magic, just generics and struct tags.


Install

go install github.com/anxi0uz/gofro@latest

Enter fullscreen mode Exit fullscreen mode

Make sure $(go env GOPATH)/bin is in your $PATH. Then:

gofro new myproject --postgres --redis --github yourname --git
cd myproject

Enter fullscreen mode Exit fullscreen mode


Source: github.com/anxi0uz/gofro