GitHub - SaiNageswarS/go-api-boot: Production-ready Go framework for gRPC + HTTP APIs with MongoDB ODM, zero-config SSL, Temporal workflows, cloud utilities, and bootstrap CLI. (original) (raw)

go-api-boot - Production-Ready Go API Framework

codecov Go Report Card Go Reference GitHub release Go version License

Batteries‑included Go framework for building production‑grade gRPC + HTTP APIs – with generics, MongoDB ODM, cloud utilities, zero‑config HTTPS, Temporal workers, and a one‑line bootstrap CLI.

🚀 Featured in Awesome Go — the curated list of high-quality Go frameworks.

🎯 Keywords: Go API framework, gRPC Go, HTTP server Go, MongoDB ODM Go, Go microservices, Go web framework, production Go APIs, Go cloud native, Temporal Go workers, Go dependency injection


📑 Table of Contents

  1. Overview
  2. Key Features
  3. Quick Start
  4. Project Structure
  5. Core Modules
  6. CLI Reference
  7. Examples
  8. Contributing
  9. License

Overview

go‑api‑boot eliminates the repetitive plumbing required to ship modern API services in Go. With a single CLI command you get:

The result: you write business logic, not boilerplate.


Key Features


Quick Start

Bootstrap a New Service

Install the CLI once

$ go install github.com/SaiNageswarS/go-api-boot/cmd/go-api-boot@latest

Scaffold a new service in ./quizService

$ go-api-boot bootstrap github.com/yourname/quizService proto

Generated layout ⤵️

quizService/
├── cmd/...
├── db/              # repositories
├── generated/       # proto stubs (via build script)
├── services/        # business logic
├── Dockerfile       # multistage build
└── config.ini       # config

Running Locally

Generate proto code & build binary

$ ./build.sh

Export secrets (or use .env / Azure Key Vault)

$ export MONGO_URI=mongodb://localhost:27017 $ export ACCESS_SECRET=supersecret $ export DOMAIN=api.example.com # required for SSL

(optional) use cloud cache for certs

$ export SSL_BUCKET=my-cert-bucket # bucket / container name

Start the server – gRPC :50051, HTTP :8081 (HTTPS if --ssl)

$ ./build/quizService


Core Modules

Server

// main.go package main

func main() { // Load secrets and config dotenv.LoadEnv()

// load config file
var ccfg *config.AppConfig 
config.LoadConfig("config.ini", ccfg) // loads [dev] or [prod] section based on env var - `ENV=dev` or `ENV=prod`

mongo, _ := odm.GetClient()
// Pick a cloud provider – all implement cloud.Cloud
cloudFns := cloud.ProvideAzure(ccfg) // or cloud.ProvideGCP(cfg)
// load secrets from Keyvault/SecretManader
cloudFns.LoadSecretsIntoEnv(context.Background())

boot, _ := server.New().
    GRPCPort(":50051").        // or ":0" for dynamic
    HTTPPort(":8080").
    EnableSSL(server.CloudCacheProvider(cfg, cloudFns)).
    // Dependency injection
    Provide(cfg).
    Provide(mongo).
    ProvideAs(cloudFns, (*cloud.Cloud)(nil)).
    // Register gRPC service impls
    RegisterService(server.Adapt(pb.RegisterLoginServer), ProvideLoginService).
    Build()

ctx, cancel := context.WithCancel(context.Background())
// catch SIGINT ‑> cancel
_ = boot.Serve(ctx)

}

// AppConfig.go

package config

type AppConfig struct {
    BootConfig  `ini:",extends"`
    CustomField string `env:"CUSTOM-FIELD" ini:"custom_field"`
}

;; config.ini

[dev] custom_field=3 azure_storage_account=testaccount

[prod] custom_field=5 azure_storage_account=prodaccount

ODM (MongoDB)

Generic CRUD

// Model type Profile struct { ID string bson:"_id" Name string bson:"name" } func (p Profile) Id() string { return p.ID } func (p Profile) CollectionName() string { return "profile" }

// Query client, err := odm.GetClient(ccfg) profile, err := async.Await(odm.CollectionOf[Profile](client, tenant).FindOneById(context.Background(), id))


Creating & Ensuring Indexes

Use EnsureIndexes[T] at startup or in integration tests to:

  1. Create the collection if missing.
  2. Apply classic MongoDB indexes (B-tree, compound).
  3. Apply Atlas Search (text) and Atlas Vector Search indexes.

// In your setup code if err := odm.EnsureIndexes[Profile](ctx, mongoClient, tenant); err != nil { log.Fatalf("failed to ensure indexes: %v", err) }

This idempotent helper safely creates all indexes advertised by your models:


Built‑in support for Atlas Vector Search. Define vector index specs on your model:

type Article struct { ID string bson:"_id" Title string bson:"title" Content string bson:"content" Embedding bson.Vector bson:"embedding" // 768-dim vector }

func (a Article) Id() string { return a.ID } func (a Article) CollectionName() string { return "articles" }

// Specify vector index on field "embedding" // odm.EnsureIndexes would create this index automatically. func (m Article) VectorIndexSpecs() []odm.VectorIndexSpec { return []odm.VectorIndexSpec{{ Name: "contentVecIdx", Path: "embedding", Type: "vector", NumDimensions: 768, Similarity: "cosine", }} }

Perform vector search:

embedding := getEmbedding(...) // []float32 params := odm.VectorSearchParams{ IndexName: "contentVecIdx", Path: "embedding", K: 5, NumCandidates: 20, } results, _ := async.Await(repo.VectorSearch(ctx, embedding, params)) for _, hit := range results { fmt.Println(hit.Doc, hit.Score) }


Leverage Atlas Search for full‑text queries. Register term search specs:

type Article struct { ID string bson:"_id" Title string bson:"title" Content string bson:"content" Embedding bson.Vector bson:"embedding" // 768-dim vector }

func (a Article) Id() string { return a.ID } func (a Article) CollectionName() string { return "articles" }

// Specify term index on field "content" and "title". // This allows full‑text search across "content" and "title" fields. // odm.EnsureIndexes would create this index automatically. func (m Article) TermSearchIndexSpecs() []odm.TermSearchIndexSpec { return []odm.TermSearchIndexSpec{{ Name: "contentTextIdx", Paths: []string {"content", "title"}, }} }

Execute text search:

params := odm.TermSearchParams{ IndexName: "contentTextIdx", Path: []string {"content", "title"}, Limit: 10, } results, _ := async.Await(repo.TermSearch(ctx, "golang guides", params)) for _, hit := range results { fmt.Println(hit.Doc, hit.Score) }


Auth & JWT

func (s *LoginService) AuthFuncOverride(ctx context.Context, method string) (context.Context, error) { return ctx, nil // public endpoint }

Cloud Abstractions

var cloudFns cloud.Cloud = cloud.ProvideAzure(ccfg) filePath, err := cloudFns.DownloadFile(context, bucket, key)

Switch provider with one line – signatures stay identical. Cloud access Secrets such as ClientId, TenantId, ClientSecret for Azure or ServiceAccount.json for GCP are loaded from environment variables.

Other configs like azure stoage account name, keyvault name or GCP projectId are loaded from the config file (ini) lazily as and when the resources are used.

Zero‑Config SSL/TLS

There are two ways to persist the Let’s Encrypt certificates:

  1. Local autocert.DirCache("certs") – good for single-node dev / on-prem.
  2. Distributed cache with SslCloudCache – perfect for Docker / Kubernetes where the container filesystem is ephemeral.

boot, _ := server.New(). GRPCPort(":50051").HTTPPort(":8080"). EnableSSL(server.DirCache("certs")) // local cache Build()

Temporal Workers

go-api-boot provides first-class support for running Temporal workers alongside your gRPC/HTTP services using the same dependency injection system. You can:

import ( "github.com/SaiNageswarS/go-api-boot/server" "go.temporal.io/sdk/client" "go.temporal.io/sdk/worker" )

boot, _ := server.New(). GRPCPort(":50051"). HTTPPort(":8080"). WithTemporal("MY_TASK_QUEUE", &client.Options{ HostPort: "temporal:7233", // or "localhost:7233" if running locally }). // ProvideIndexerActivities is a function whose dependencies will be injected RegisterTemporalActivity(ProvideIndexerActivities).
RegisterTemporalWorkflow(IndexPdfFileWorkflow). Build()

boot.Serve(context.Background())


CLI Reference

Command Description
bootstrap Scaffold a new project
repository Generate model + repository in db/
service Generate skeleton gRPC service

Run with -h for full flags.


Examples


Contributing

PRs and issues are welcome!

  1. Fork ➡️ hack ➡️ PR.
  2. Run make test lint – zero lint errors.
  3. Add unit / integration tests for new features.

License

Apache‑2.0 – see LICENSE for details.


Built with ❤️ for developers by Sai Nageswar S.