Skip to content
/ api-svc Public

Go domain services for SaaS APIs: billing, identity, payments, credits/tokens, and contact—built with ports/adapters, Postgres migrations, and optional HTTP handlers.

License

Notifications You must be signed in to change notification settings

aatuh/api-svc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

api-svc

Overview

api-svc is a collection of reusable domain services for Go HTTP APIs: billing, credits/tokens, identity, payments, and contact. Each service is packaged as plain Go with clear ports (interfaces) for persistence and third‑party providers. Some services include optional HTTP handlers (chi-based via api-toolkit) and Postgres adapters + embedded migrations.

This repository is intentionally both human- and agent-friendly: predictable folder layout, small packages, explicit wiring, and minimal hidden magic.

Design goals

  • Domain logic in Service types; adapters stay thin.
  • Depend on stable interfaces at boundaries (github.com/aatuh/api-toolkit/ports).
  • Make persistence/provider swaps straightforward.
  • Keep wiring explicit and test-friendly (fakes over ports).

Services (package map)

  • billingsvc — billing profiles, invoices, “outstanding” invoicing, and webhook processing.
    • HTTP: billingsvc/http
    • Postgres: billingsvc/postgres
    • Migrations: billingsvc/migrations (embedded embed.FS)
  • creditsvc — token/credit accounts + transaction ledger.
    • Postgres: creditsvc/postgres
    • Migrations: creditsvc/migrations (embedded embed.FS)
  • identity — external identity → local user, role management.
    • HTTP: identity/http (ensure middleware + profile endpoints)
    • Postgres: identity/postgres (configurable table names)
    • Migrations: identity.MustMigrationsFS() (embedded fs.FS)
  • paymentsvc — token pack catalog + checkout + webhook handling.
    • HTTP: paymentsvc/http (Stripe webhook handler)
  • contact — contact form message delivery via an email Sender.
    • HTTP: contact/http (endpoint wrapper; you provide decode/validation)

Installation

go get github.com/aatuh/api-svc@latest

Quickstart (wiring example)

This repo is a library, not a runnable server. Your application wires services with adapters (for Postgres, Stripe, email, etc.) and mounts the HTTP handlers onto your router.

Identity + profile endpoints

package main

import (
  "log"
  "net/http"

  "github.com/aatuh/api-svc/identity"
  identityhttp "github.com/aatuh/api-svc/identity/http"
  identitypg "github.com/aatuh/api-svc/identity/postgres"
  "github.com/aatuh/api-toolkit/adapters/chi"
  "github.com/aatuh/api-toolkit/adapters/clock"
  "github.com/aatuh/api-toolkit/adapters/logzap"
  "github.com/aatuh/api-toolkit/adapters/pgxpool"
  "github.com/aatuh/api-toolkit/adapters/txpostgres"
  "github.com/aatuh/api-toolkit/adapters/uuid"
)

func main() {
  pool, err := pgxpool.New("postgres://user:pass@localhost:5432/app?sslmode=disable")
  if err != nil {
    log.Fatal(err)
  }
  defer pool.Close()

  tx := txpostgres.New(pool)
  logr := logzap.NewProduction()
  clk := clock.NewSystemClock()
  ids := uuid.NewUUIDGen()

  repo := identitypg.NewRepo(pool, identitypg.DefaultConfig())
  svc := identity.NewDefault(repo, tx, logr, clk, ids)

  r := chi.New()
  r.Mount("/me", identityhttp.NewProfileHandler(identityhttp.ProfileConfig{
    Service: svc,
  }).Routes())

  log.Fatal(http.ListenAndServe(":8080", r))
}

Configuration

Configuration is expressed as plain structs. Some services include helper loaders that read environment variables via api-toolkit/config.Loader.

Postgres adapters and migrations

Some services include Postgres adapters and embedded SQL migrations. Migrations are designed to be run via api-toolkit/migrator (or its adapters/migrate wrapper) without requiring a migrations directory on disk.

package main

import (
  "context"
  "io/fs"

  billingmigrations "github.com/aatuh/api-svc/billingsvc/migrations"
  creditsmigrations "github.com/aatuh/api-svc/creditsvc/migrations"
  "github.com/aatuh/api-svc/identity"
  "github.com/aatuh/api-toolkit/adapters/migrate"
  "github.com/aatuh/api-toolkit/adapters/logzap"
)

func migrateDB(ctx context.Context, dsn string) error {
  log := logzap.NewProduction()
  m, err := migrate.New(migrate.Options{
    DSN: dsn,
    Log: log,
    EmbeddedFSs: []fs.FS{
      identity.MustMigrationsFS(),
      billingmigrations.Migrations,
      creditsmigrations.Migrations,
    },
  })
  if err != nil {
    return err
  }
  defer m.Close()
  return m.Up(ctx, "")
}

HTTP handlers

Services that ship HTTP handlers expose reusable routers/handlers that follow a consistent flow: decode → validate → service call → encode. Defaults use RFC‑7807 Problem+JSON via api-toolkit/httpx, and most handlers allow overriding the encoding/problem writers.

Starting points:

  • Billing routes: billingsvc/http/handler.go
  • Contact endpoint wrapper: contact/http/handler.go
  • Identity middleware and profile endpoints: identity/http/middleware.go, identity/http/profile_handler.go
  • Stripe webhook fan-out: paymentsvc/http/stripe_webhook.go

Development

  • Run: go test ./... (if you’re inside a larger repo with a parent go.work that doesn’t include this module, use GOWORK=off go test ./...)
  • Format: gofmt -w .

License

Apache-2.0. See LICENSE.

About

Go domain services for SaaS APIs: billing, identity, payments, credits/tokens, and contact—built with ports/adapters, Postgres migrations, and optional HTTP handlers.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages