Skip to content

SaiNageswarS/go-api-boot

Repository files navigation

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:

  • A fully wired gRPC server that also serves gRPC‑Web and REST gateways – no Envoy sidecars or extra proxies.
  • Temporal workflow support for long-running background jobs.
  • Generic ODM for MongoDB with multi‑tenant support.
  • Opinionated middlewares (JWT auth, logging, panic recovery) that you can opt out of per‑method.
  • A relocatable cloud toolkit (Azure / GCP) for signed URLs, blob storage, secret resolution, etc.
  • Zero-configuration HTTPS – serve valid TLS certificates on day 0.
  • Built-In Dependency injection wiring customized for gRpc services, temporal workers, config, mongo client, and cloud abstractions.

The result: you write business logic, not boilerplate.


Key Features

  • First‑class gRPC & gRPC‑Web – serve browsers natively without Envoy.
  • Generic ODM for MongoDB – type‑safe generic multi-tenant Object Model - (CollectionOf[T](client, tenant).FindOneById(id)) with async helpers.
  • Vector & Text Search – built‑in support for Atlas Vector Search and Atlas Search.
  • Index Management – auto‑create and ensure classic, search, and vector indexes via EnsureIndexes[T].
  • JWT Auth & Middleware Stack – observability, logging, panic recovery pre‑wired.
  • Cloud Providers – interchangeable Azure / GCP helpers for storage & secrets.
  • Zero‑Config SSL – automatic Let’s Encrypt certificates with exponential back‑off and optional cloud-backed cache (SslCloudCache) for stateless containers.
  • Temporal Workflow Support – run long-lived, fault-tolerant background jobs with native Temporal integration and DI-based worker registration.
  • Fluent Dependency Injection – chainable, lifecycle-aware registration for gRPC services, Temporal workflows/activities, SSL providers, cloud abstractions, and more, all via a single builder API.
  • Bootstrap CLI – scaffold full service, models, repos, services, Dockerfile, build scripts.

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
  • gRPC, gRPC‑Web, and optional REST gateway on the same port.
  • Middleware registry (unary + stream) to plug in OpenTelemetry, Prometheus, etc.

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))
  • Additionally use helpers like HashedKey to generate _id, NewModelFrom[T any](proto interface{}) to copy values from proto to the model.

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:


Vector Search

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)
}

Text Search

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

  • HS256 by default – override via env vars or secrets manager.
  • Skip auth per‑method:
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()
  • ACME challenge handled internally, exponential back‑off for cloud IP propagation.
  • Just expose port 80 and 443 in your container spec.
  • SslCloudCache streams certificates to the chosen object store (S3, Azure Blob, GCS).
  • Multiple replicas of your service instantly share the same certs – no race conditions, no volume mounts.
  • Exponential back-off is applied automatically while waiting for DNS / IP propagation.

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:

  • Register workflows and activities via a simple hook.
  • Automatically connect to Temporal server (local, Docker, or Temporal Cloud).
  • Share configuration and lifecycle across the whole service.
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 <modulePath> <protoDir> Scaffold a new project
repository <ModelName> Generate model + repository in db/
service <ServiceName> 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.

About

Production-ready Go framework for gRPC + HTTP APIs with MongoDB ODM, zero-config SSL, Temporal workflows, cloud utilities, and bootstrap CLI.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages