{"id":51471293,"url":"https://github.com/natuleadan/sdk-api","last_synced_at":"2026-07-06T18:00:45.561Z","repository":{"id":368034236,"uuid":"1282619324","full_name":"natuleadan/sdk-api","owner":"natuleadan","description":"Event-driven microservice SDK for Go. YAML-driven, auto-generates REST CRUD from struct tags. Fork of go-zero with Fiber (fasthttp), NATS JetStream, and pgx. Per-route middleware. Multi-DB (PostgreSQL, Turso, MySQL, MongoDB).","archived":false,"fork":false,"pushed_at":"2026-06-28T19:29:48.000Z","size":26922,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T20:17:04.263Z","etag":null,"topics":["backend","crud","go","microservice","middleware","sdk"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/natuleadan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.md","maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-28T02:25:45.000Z","updated_at":"2026-06-28T19:29:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/natuleadan/sdk-api","commit_stats":null,"previous_names":["natuleadan/sdk-api"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/natuleadan/sdk-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natuleadan%2Fsdk-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natuleadan%2Fsdk-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natuleadan%2Fsdk-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natuleadan%2Fsdk-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/natuleadan","download_url":"https://codeload.github.com/natuleadan/sdk-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natuleadan%2Fsdk-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35201088,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-06T02:00:07.184Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","crud","go","microservice","middleware","sdk"],"created_at":"2026-07-06T18:00:44.592Z","updated_at":"2026-07-06T18:00:45.501Z","avatar_url":"https://github.com/natuleadan.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Natuleadan SDK API\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://avatars.githubusercontent.com/u/210283438?s=400\u0026u=1afe4cf2a1a5347c739f4efc60b86e3c1564cb6\u0026v=4\" width=\"120\" height=\"120\" style=\"border-radius: 50%;\"\u003e\n  \u003cbr\u003e\n  \u003cb\u003eCLI:\u003c/b\u003e \u003ccode\u003esdk-api\u003c/code\u003e — \u003cb\u003eModule:\u003c/b\u003e \u003ccode\u003egithub.com/natuleadan/sdk-api\u003c/code\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/natuleadan/sdk-api/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/natuleadan/sdk-api/ci.yml?style=for-the-badge\u0026label=CI\u0026logo=github\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/natuleadan/sdk-api/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/natuleadan/sdk-api?style=for-the-badge\u0026label=Release\u0026logo=github\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/natuleadan/sdk-api\"\u003e\u003cimg src=\"https://img.shields.io/badge/Go-Reference-00ADD8?style=for-the-badge\u0026logo=go\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://golang.org\"\u003e\u003cimg src=\"https://img.shields.io/github/go-mod/go-version/natuleadan/sdk-api?style=for-the-badge\u0026logo=go\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://conventionalcommits.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=for-the-badge\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nA production-ready Go SDK for building event-driven microservices and monoliths. **Fork of [go-zero](https://github.com/zeromicro/go-zero)** with **Fiber** (fasthttp), **pgx** (PostgreSQL), **NATS JetStream** + **Kafka** (messaging), per-route middleware, security, and YAML-driven configuration.\n\n---\n\n## 1. Install\n\n```bash\ngo install github.com/natuleadan/sdk-api/cmd/sdk-api@latest\n```\n\nOr download a pre-built binary from the [releases page](https://github.com/natuleadan/sdk-api/releases).\n\n## 2. Quick Start\n\nCreate a new service with a single command:\n\n```bash\nsdk-api new products-svc --model Product --fields \"name:string,price:float64\"\ncd products-svc\n```\n\nThis generates `service.yaml`, `main.go`, `models/product.go`, and `models/hooks.go`:\n\n```yaml\nname: products-svc\nport: 8080\n\ndatabases:\n  - name: pg-main\n    driver: postgres\n    url: \"${DATABASE_URL}\"\n\nentry:\n  - type: crud\n    model: Product\n    db: pg-main\n    table: products\n\nserver:\n  openapi:\n    enabled: true\n```\n\nStart PostgreSQL and run:\n\n```bash\ndocker run -d --name pg -p 5432:5432 \\\n    -e POSTGRES_USER=dev -e POSTGRES_PASSWORD=devpass \\\n    postgres:18-alpine\n\nDATABASE_URL=\"postgres://dev:devpass@localhost:5432/postgres?sslmode=disable\" \\\n    go run .\n```\n\nYour service is live with auto-generated CRUD, OpenAPI docs, and Prometheus metrics:\n\n```bash\ncurl http://localhost:8080/api/v1/products\nopen http://localhost:8080/docs\ncurl http://localhost:8080/health\n```\n\n## 3. Features\n\n| Category | Feature | Description |\n|----------|---------|-------------|\n| **Entry types** | `crud` | Auto-generated List/Get/Create/Update/Delete with hooks |\n| | `rest` | Custom handler, any method (GET/POST/PUT/PATCH/DELETE) |\n| | `webhook` | Defaults to POST, no JWT by default |\n| | `websocket` | WebSocket upgrade handler |\n| | `sse` | Server-Sent Events streaming |\n| | `file` | Upload/download/delete, S3 or local storage |\n| | `async` | 202 Accepted + status polling for long-running jobs |\n| | `graphql` | Auto-generated schema + CRUD resolvers |\n| **Event streams** | NATS JetStream | Push/pull consumers, KV, request-reply |\n| | Kafka | Topic-based pub/sub, consumer groups |\n| | `EventBroker` | Unified interface for NATS/Kafka duality |\n| **Security** | Security headers | X-Frame-Options, CSP, HSTS, Permissions-Policy, etc. |\n| | CSRF | Double-submit cookie pattern |\n| | Rate limiting | Token bucket (memory or Redis), per IP/user/global |\n| | TLS | Manual certs or Let's Encrypt autocert |\n| | SSRF protection | Blocks private/loopback/metadata IPs |\n| | Input validation | Struct tag validation via `go-playground/validator/v10` |\n| | Error sanitization | Generic 500 messages, no internal leak |\n| **Auth** | JWT per-entry | Algorithm pinning, claim validation, AuthContext extraction |\n| | 4 auth modes | `none`, `manual`, `openfga-zitadel`, `ory` |\n| | OpenFGA + Zitadel | ReBAC authorization + OIDC authentication |\n| | Ory Kratos + Keto | Identity management + fine-grained authorization |\n| | API keys | Service-to-service with scoped permissions |\n| | Token refresh | Delegated to IDP (Zitadel/Kratos) or manual re-sign |\n| **Cron** | `nats` mode | Publish message to NATS on schedule |\n| | `handler` mode | Call a Go function on schedule |\n| | `internal` mode | System tick without handler |\n| **Databases** | PostgreSQL | `pgxpool` with auto-sizing pool |\n| | MySQL | via `go-sql-driver/mysql` |\n| | Turso | Embedded SQLite via libsql |\n| | Multi-DB | Each entry/exit can use a different database |\n| **Server** | 14 built-in middlewares | Logger, breaker, JWT, CORS, tracing, shedding, timeout, etc. |\n| | Per-route middleware | Configure middlewares per path in YAML |\n| | Security headers + CSRF + Rate limit | YAML-driven security layers |\n| | TLS (manual + autocert) | HTTPS + HTTP→HTTPS redirect |\n| | Error sanitization + CRLF protection | Built-in, always on |\n| | OpenAPI 3.0.3 + Scalar | Auto-generated spec + UI `/docs` |\n| | Health + Metrics | `/health`, `/metrics` |\n| **Storage** | S3-compatible | MinIO, R2, AWS S3 |\n| | Local filesystem | Path-constrained uploads |\n\n### Benchmarks\n\n| Scenario | Stack | RPS |\n|----------|-------|-----|\n| Minimal HTTP | raw Fiber | ~700k |\n| URL expand | SDK (PG + Redis) | ~31k |\n| URL expand | SDK (PG + NATS KV) | ~31k |\n| Product by ID | SDK (MySQL) | ~25k |\n| Product by ID | SDK (Turso) | ~20k |\n| Product by ID | SDK (MongoDB) | ~18k |\n\nFull benchmarks in [`docs/benchmarks.md`](docs/benchmarks.md).\n\n## 4. Use as Go SDK\n\n```go\nimport \"github.com/natuleadan/sdk-api\"\n\n// Option 1: YAML-driven\nsvc, _ := runtime.New(\"service.yaml\")\npool := svc.Pool(\"pg-main\").(*pgxpool.Pool)\ntable, _ := db.NewTable[Product](pool, \"products\")\nsvc.WithCRUD(\"Product\", runtime.NewCRUDProvider(table, \u0026ProductHooks{}))\nsvc.WithExit(\"onOrderConfirmed\", func(ctx, msg []byte) ([]byte, error) {\n    log.Printf(\"received: %s\", string(msg))\n    return nil, nil\n})\nsvc.RegisterModel(\"Product\", (*Product)(nil))\nsvc.Run()\n\n// Option 2: Client mode (connect to existing service)\nclient, _ := runtime.NewClient(\"service.yaml\")\nresp, _ := client.Request(\"orders\", \"orders.transform\", []byte(`{\"id\": 1}`))\n```\n\n## 5. Server Config\n\n### Server fields\n\n| Field | Default | Description |\n|-------|---------|-------------|\n| `host` | `0.0.0.0` | Bind address |\n| `prefork` | `false` | Fiber prefork (SO_REUSEPORT, Linux only) |\n| `body_limit` | `4194304` | Max body size |\n| `timeout` | `30s` | Read/write/idle timeout |\n| `api_prefix` | `/api/v1` | Prefix for all entry paths |\n| `health_path` | `/health` | Liveness probe |\n| `metrics_path` | `/metrics` | Prometheus endpoint |\n| `shutdown_timeout` | `10s` | Graceful shutdown wait |\n\n### Entry types\n\n| Type | HTTP Methods | What you write | DB required |\n|------|-------------|----------------|-------------|\n| `crud` | GET, POST, PATCH, DELETE | Nothing | Yes |\n| `rest` | Any | Single handler | Optional |\n| `webhook` | Any (default POST) | Single handler | Optional |\n| `websocket` | GET (upgrade) | WS handler | No |\n| `sse` | GET | SSE handler | No |\n| `file` | GET, POST, PUT, PATCH, DELETE | Upload handler | No |\n| `async` | POST, GET | Async handler | No |\n| `graphql` | POST | Nothing | No |\n\n### Exit worker fields\n\n| Field | Default | Description |\n|-------|---------|-------------|\n| `subscribe.stream` | required | NATS stream name |\n| `subscribe.subject` | stream name | Subject to subscribe to |\n| `handler` | required | Go function name |\n| `max_concurrent` | 1 | Max concurrent messages |\n| `reply` | false | Enable request-reply via `msg.Respond()` |\n| `reply_timeout` | `30s` | Reply timeout |\n| `consumer_mode` | `push` | `push` or `pull` |\n| `pull_batch` | 0 | Batch size for pull consumers |\n\n## 6. Event Flow\n\n```\nHTTP Entry → nats_publish → NATS Stream → Exit Worker → DB/NATS/Email\n      ↑                                      │\n      └────── Request-Reply (reply: true) ───┘\n\nCron → Publish NATS → Exit Worker (subscribed)\n```\n\nPackages involved:\n\n```\n┌──────────┬─────────────┬──────────────┬─────────────┬───────────┐\n│   db/    │   server/   │   events/    │  runtime/   │  auth/    │\n│  (pgx)   │  (Fiber)    │  (NATS JS)   │ (orchestr.) │ (ext.)    │\n│          │             │              │             │           │\n│ Table[T] │ 14+ middle- │  Producers   │ Service     │ OpenFGA   │\n│ CRUD     │ wares       │  Exit Workers│ YAML cfg    │ Zitadel   │\n│ AutoInit │ JWT/CORS    │  KV Cache    │ Entry routes│ Ory       │\n│ PG/Turso │ SSE/WS      │  Request-    │ Exit workers│ API Keys  │\n│ MySQL    │ OpenAPI      │  Reply       │ Cron        │ AuthCtx   │\n│          │ Auth (4 modes)│             │             │           │\n└──────────┴─────────────┴──────────────┴─────────────┴───────────┘\n```\n\n## 7. Documentation\n\n| File | Contents |\n|------|----------|\n| [docs/configuration.md](docs/configuration.md) | Full YAML schema reference (all entry types, event streams, security) |\n| [docs/security.md](docs/security.md) | Consolidated security guide (headers, CSRF, rate limit, TLS, SSRF, validation, auth, JWT, OpenFGA, Zitadel, Ory, API keys) |\n| [docs/http-server.md](docs/http-server.md) | Server config, middlewares, TLS, security headers, CSRF, rate limit |\n| [docs/runtime.md](docs/runtime.md) | Runtime API: `Service`, `CRUDProvider`, `RegisterValidation`, `SafeHTTPClient` |\n| [docs/messaging.md](docs/messaging.md) | NATS + Kafka, EventBroker, producers, exit workers, KV cache |\n| [docs/database.md](docs/database.md) | PG/Turso/MySQL, pool sizing, multi-DB, Table[T] CRUD |\n| [docs/entry-graphql.md](docs/entry-graphql.md) | Auto-generated GraphQL schema + resolvers |\n| [docs/entry-async.md](docs/entry-async.md) | Async jobs: 202 Accepted + status polling |\n| [docs/secrets.md](docs/secrets.md) | Secrets management: ${VAR}, SOPS/age, best practices |\n| [docs/api-patterns.md](docs/api-patterns.md) | Entry types, exit workers, cron, hooks with YAML + Go examples |\n| [docs/best-practices.md](docs/best-practices.md) | Gotchas, patterns, anti-patterns |\n| [docs/cli.md](docs/cli.md) | `sdk-api new/docker/kube/client` subcommands |\n| [docs/benchmarks.md](docs/benchmarks.md) | Full benchmark results and methodology |\n| [docs/architecture.md](docs/architecture.md) | Architecture, entry router, exit system, cron design |\n| [docs/getting-started.md](docs/getting-started.md) | Step-by-step tutorial for first service |\n\n## 8. Examples\n\n### 8.1 CRUD with hooks\n\n```yaml\nentry:\n  - type: crud\n    model: Product\n    db: pg-main\n    table: products\n    path: /products\n```\n\n```go\ntype ProductHooks struct{ runtime.DefaultHooks[Product] }\n\nfunc (h *ProductHooks) BeforeCreate(ctx context.Context, req Product) (Product, error) {\n    req.CreatedAt = time.Now()\n    return req, nil\n}\n\npool := svc.Pool(\"pg-main\").(*pgxpool.Pool)\ntable, _ := db.NewTable[Product](pool, \"products\")\nsvc.WithCRUD(\"Product\", runtime.NewCRUDProvider(table, \u0026ProductHooks{}))\n```\n\n### 8.2 REST endpoint with nats_publish\n\n```yaml\nentry:\n  - type: rest\n    method: POST\n    path: /orders/transform\n    handler: onTransform\n    nats_publish:\n      - stream: orders\n        subject: orders.transformed\n```\n\n```go\nsvc.WithRest(\"onTransform\", func(c *fiber.Ctx) error {\n    var req Order\n    jsonx.Unmarshal(c.Body(), \u0026req)\n    req.Status = \"transformed\"\n    return c.JSON(req)\n})\n```\n\n### 8.3 Exit worker with reply\n\n```yaml\nexit:\n  - name: email-sender\n    subscribe:\n      stream: orders\n      subject: orders.confirmed\n    handler: onEmail\n    reply: true\n    reply_timeout: 30s\n```\n\n```go\nsvc.WithExit(\"onEmail\", func(ctx, msg []byte) ([]byte, error) {\n    log.Printf(\"sending email for: %s\", string(msg))\n    return []byte(`{\"sent\": true}`), nil\n})\n```\n\n### 8.4 Cron job\n\n```yaml\ncron:\n  - name: daily-report\n    schedule: \"0 6 * * *\"\n    mode: handler\n    handler: onDailyReport\n```\n\n```go\nsvc.WithCron(\"onDailyReport\", func(ctx context.Context) error {\n    log.Println(\"generating daily report...\")\n    return nil\n})\n```\n\n## 9. Project Structure\n\n```\ncmd/sdk-api/     # CLI generator (new/docker/kube/client)\nruntime/         # Service orchestrator, entry router, exit workers, cron, hooks\nserver/          # Fiber HTTP + 14 middlewares + storage backends\ndb/              # Table[T] CRUD (PG, Turso, MySQL) + AutoInit\nevents/          # NATS JetStream producers, consumers, KV cache, request-reply\ninfra/           # 45+ go-zero packages (conf, logx, trace, breaker, redis, discover, ...)\ndocs/            # Documentation + API patterns\nexamples/        # 8 dockerized example services + benchmarks\n```\n\n## 10. License\n\nMIT — see [LICENSE](LICENSE). Forked from [go-zero](https://github.com/zeromicro/go-zero) (MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnatuleadan%2Fsdk-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnatuleadan%2Fsdk-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnatuleadan%2Fsdk-api/lists"}