An open API service indexing awesome lists of open source software.

https://github.com/aatuh/api-svc

Go domain services for SaaS APIs: billing, identity, payments, credits/tokens, and contact—built with ports/adapters, Postgres migrations, and optional HTTP handlers.
https://github.com/aatuh/api-svc

api backend billing chi clean-architecture credits ddd email go golang hexagonal-architecture identity migrations payments ports-and-adapters postgresql saas stripe tokens webhooks

Last synced: 5 months ago
JSON representation

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

Awesome Lists containing this project

README

          

# 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

```bash
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

```go
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.

```go
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`.