blaze-api

module
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: Apache-2.0

README

blaze-api

Tests Go Report Card Coverage Status

Blaze-API is a foundational template for building and deploying APIs in Go. It provides a production-ready structure for creating GraphQL APIs with user management, account handling, role-based access control (RBAC), OAuth2, and JWT authentication.

Features

  • Users: Manage user data and interactions.
  • Accounts: Handle account operations and storage.
  • Roles: Role-Based Access Control (RBAC) for managing user permissions.
  • Permissions: Define and manage access rights for different roles.
  • JWT Authentication: Secure your API with JWT-based authentication.
  • GraphQL API: Integrated GraphQL support for building flexible APIs.
  • OAuth2: Server and client support with remote authorization.
  • Social auth: Facebook OAuth2 login out of the box (Google, LinkedIn, X.com ready to configure).
  • Object history log: Track all mutations with a per-request message.
  • Auth clients: OAuth2 client management (token issuance, revocation).
  • Direct access tokens: Long-lived tokens for service-to-service auth.
  • Generic repository/usecase layer: Type-safe CRUD with compile-time model constraints.
  • Tests: Comprehensive test suite for maintaining code quality.
  • Logging: Structured logging (Zap) with context propagation.
  • Profiler & metrics: pprof + Prometheus endpoints built in.
  • REST API: RESTful API interface for your application.
  • Swagger API documentation: Generate comprehensive API documentation with Swagger.

Quick Start

Installation
go get github.com/geniusrabbit/blaze-api
Run the example locally (Docker)
cd example/api

# Start Postgres + run migrations + start the API
make run-api

# API is available at http://localhost:8581
# GraphQL playground: http://localhost:8581/
# Prometheus metrics: http://localhost:8581/metrics
# pprof profiler:     http://localhost:8583/debug/pprof/

The run-api target builds the Docker image, runs migrations, and starts the full stack via docker-compose.

Configuration

All settings are read from environment variables (or a .env file). The key ones:

# Database (PostgreSQL)
SYSTEM_STORAGE_DATABASE_MASTER_CONNECT=postgres://dbuser:password@localhost:5432/project?sslmode=disable
SYSTEM_STORAGE_DATABASE_SLAVE_CONNECT=postgres://dbuser:password@localhost:5432/project?sslmode=disable

# OAuth2 / JWT
OAUTH2_SECRET=your-secret-min-32-chars
OAUTH2_ACCESS_TOKEN_LIFESPAN=1h
OAUTH2_REFRESH_TOKEN_LIFESPAN=720h

# Session
SESSION_COOKIE_NAME=sessid
SESSION_LIFETIME=1h

# Dev mode (skip auth with a static token)
DEBUG=true
LOG_LEVEL=debug
SESSION_DEV_TOKEN=develop
SESSION_DEV_USER_ID=1
SESSION_DEV_ACCOUNT_ID=1

# Social auth (optional)
FACEBOOK_CLIENT_ID=...
FACEBOOK_CLIENT_SECRET=...
FACEBOOK_REDIRECT_URL=http://localhost:8581/auth/facebook/callback

A full annotated example lives in example/api/.env and example/api/deploy/develop/.api.env.

Wiring it together (main.go)
// example/api/cmd/api/main.go
package main

import (
  "github.com/geniusrabbit/blaze-api/pkg/context/ctxlogger"
  "github.com/geniusrabbit/blaze-api/pkg/database"
  "github.com/geniusrabbit/blaze-api/pkg/permissions"
  "github.com/geniusrabbit/blaze-api/pkg/auth/jwt"
  "github.com/geniusrabbit/blaze-api/pkg/auth/oauth2"
  "github.com/geniusrabbit/blaze-api/repository/account/authorizer"
  "github.com/geniusrabbit/blaze-api/repository/historylog/middleware/gormlog"
)

func main() {
  // Connect master + slave databases
  masterDB, slaveDB, _ := database.ConnectMasterSlave(ctx,
    conf.System.Storage.MasterConnect,
    conf.System.Storage.SlaveConnect)

  // Register GORM callback — writes a HistoryAction row for every mutation
  gormlog.Register(masterDB)

  // Build permission manager (RBAC, cached)
  permissionManager := permissions.NewManager(masterDB, conf.Permissions.RoleCacheLifetime)
  appinit.InitModelPermissions(permissionManager)  // register all domain models

  // Build OAuth2 + JWT providers
  oauth2provider, jwtProvider := appinit.Auth(ctx, conf, masterDB)

  // Attach services to context (propagated to every request handler)
  ctx = ctxlogger.WithLogger(ctx, logger)
  ctx = database.WithDatabase(ctx, masterDB, slaveDB)
  ctx = permissions.WithManager(ctx, permissionManager)

  httpServer := server.HTTPServer{
    Logger:      logger,
    JWTProvider: jwtProvider,
    Authorizers: []auth.Authorizer[*user.User, *account.Account]{
      jwt.NewAuthorizer(jwtProvider),
      oauth2.NewAuthorizer(oauth2provider),
      authorizer.NewDevTokenAuthorizer(...), // dev-only static token
    },
    ContextWrap: func(ctx context.Context) context.Context {
      ctx = ctxlogger.WithLogger(ctx, logger)
      ctx = database.WithDatabase(ctx, masterDB, slaveDB)
      ctx = permissions.WithManager(ctx, permissionManager)
      return ctx
    },
  }
  httpServer.Run(ctx, conf.Server.HTTP.Listen)
}
Registering permissions for a domain model

Every model that should participate in ACL must be registered with the permission manager:

// example/api/cmd/api/appinit/acl.go
func InitModelPermissions(pm *permissions.Manager) {
  acl.InitModelPermissions(pm,
    &user.User{},
    &rbacModels.Role{},
    &authclient.AuthClient{},
    &account.Account{},
    &historylog.HistoryAction{},
    // ... add your own models here
  )

  // Standard CRUD permissions
  _ = pm.RegisterNewOwningPermissions(&user.User{},
    []string{acl.PermView, acl.PermList, acl.PermCreate, acl.PermUpdate, acl.PermDelete})

  // With approval workflow
  _ = pm.RegisterNewOwningPermissions(&account.Account{},
    append(crudPermissions, acl.PermApprove, acl.PermReject),
    rbac.WithCustomCheck(accountCustomCheck))
}

User / Account / Member templates

User, Account, and Member are composable embeddable bases + optional traits, not monolithic structs. User remains bundled in the library; Account and Member are wired by the consumer (see example/api/internal/domain/account.go).

Layer Bundled / reference type Compose from
User example/api/internal/domain.User UserBase + UserEmail + UserPassword
Account example/api/internal/domain.Account AccountBase + consumer AccountProfile (see domain/account_profile.go)
Member account.Member[TUser, TAccount] MemberBase + preload User/Account

account.Model covers core tenant fields only (GetID, permissions, GetApprove, GetCreatedAt, GetUpdatedAt). Profile fields (title, logo, …) live in the consumer GraphQL schema via extend type / extend input, not in the base library schema.

Base GraphQL types in repository/account/delivery/graphql/account_base.graphql and repository/user/delivery/graphql/user.graphql contain minimal core fields only. Consumer apps add profile/filter fields in separate extension files (see example/api/protocol/graphql/extensions/).

Account and User QueryResolver implementations are generics parameterized by consumer GraphQL types:

// repository/account/delivery/graphql/base_resolver.go
type QueryResolver[TUser, TDomain, TGQLAccount, TGQLAccountInput, ...] struct { ... }

// Base wiring (library default types):
accountgraphql.NewBaseQueryResolver(cfg)   // TGQLAccount = *gqlmodels.Account

// Example consumer (extended Account):
wiring.NewExampleAccountQueryResolver(cfg) // TGQLAccount = exmodels.Account

Wire extended resolvers in example/api/internal/server/graphql/wiring/ and map domain → GraphQL in example/api/internal/domain/graphql.go:

// example/api/internal/domain/graphql.go
func AccountToGraphQL(acc *Account) exmodels.Account { /* core + profile fields */ }
func FillAccountFromInput(dest *Account, input *exmodels.AccountInput, ...) *Account { /* ... */ }

// example/api/cmd/api/appinit/deps.go
ExampleResolverDeps = resolvers.Deps[*UserType, *AccountType, exmodels.Account, *exmodels.AccountInput]

RBACResourceName() / TableName() stay on concrete structs (ACL/GORM), not on account.Model.

Reference consumer wiring — see example/api/cmd/api/appinit/deps.go and example/api/internal/user/stack.go:

deps := appinit.NewDeps()
// deps.UserModule  — composite Repository + Core/Email/Password usecases (example-only helper)
// deps.Resolver    — passed to server/graphql/resolvers

The framework exposes separate interfaces only: user.Repository, user.EmailRepository, user.PasswordRepository, and matching usecases. Compose them in the consumer (example uses userstack.NewModule).

Deps[TUser, TAccount] is parameterized by your user/account types. GraphQL wiring uses UserModuleDeps (core + email + password + repos) and BaseDeps (account/member). Auth resolvers take EmailRepository + PasswordRepository separately — not a bundled repo type.

baseResolver.UserModuleDeps[*MyUser]{
    NewUser:      func() *MyUser { return new(MyUser) },
    Core:         userCoreUC,
    Email:        userEmailUC,
    Password:     userPasswordUC,
    EmailRepo:    userEmailRepo,
    PasswordRepo: userPasswordRepo,
}
Custom User type (consumer)
type User struct {
    userModels.UserBase
    userModels.UserEmail
    userModels.UserPassword
    Country string `gorm:"column:country"`
}

func (u *User) TableName() string       { return "adnet_user" }
func (u *User) RBACResourceName() string { return "adnet.user" }

Wire once at startup (example pattern):

newModel := func() *User { return new(User) }
userModule := userstack.NewModule(newModel) // example/api only
userRepo := userModule.Repo                 // satisfies Repository + Email + Password
userCoreUC := userModule.Core

Minimal UserBase-only deployments (no email/password) require a custom migration and must not use PasswordRepository / password GraphQL modules — compile-time generic constraints enforce this.

Adnetapi migration

When migrating an existing consumer (e.g. adnetapi):

  1. Replace type User = blzuser.User with a local struct embedding UserBase + traits + custom fields.
  2. Replace legacy user repository wiring with NewDefaultUserRepository() or NewBundledRepository(newModel).
  3. Pass server/graphql/resolvers.Deps (or legacy interfaces) into resolvers — do not construct repos inside resolver packages.
  4. Update struct literals: promoted embed fields cannot be set in composite literals — use stubs (UserStub(id)) or assign after &User{}.
  5. ACL registration stays the same — register your concrete &User{} / &Account{} types.

Architecture

Repository / Usecase layer (repository/generated)

All domain entities follow the same layered pattern:

repository/<domain>/
  models/        — domain structs (must implement generated.Model[TID])
  repository.go  — domain Repository/Usecase interface
  repository/    — GORM implementation (embeds generated.Repository[T, TID])
  usecase/       — business logic (embeds generated.Usecase[T, TID])
  mocks/         — generated mocks (go:generate mockgen, DO NOT EDIT)
  delivery/      — transport adapters (GraphQL resolvers, REST handlers)

The generic base types live in repository/generated:

Type Description
Repository[T, TID] GORM CRUD implementation for any model satisfying Model[TID]
Usecase[T, TID] ACL-checked business logic delegating to RepositoryIface[T, TID]
UsecaseApprover[T, TID] Approve/reject workflow with ACL checks
BaseModel[TID] Convenience embed — provides GetID/SetID for free
BaseTimestamps Convenience embed — provides SetCreatedAt/SetUpdatedAt for free
Defining a new domain model

A model type T must satisfy the generated.Model[TID] constraint — i.e., expose GetID() TID via a value receiver. The easiest way is to embed generated.BaseModel:

import "github.com/geniusrabbit/blaze-api/repository/generated"

type Widget struct {
    generated.BaseModel[uint64]  // GetID() + SetID() for free
    generated.BaseTimestamps     // SetCreatedAt() + SetUpdatedAt() for free
    gorm.DeletedAt

    Name string
}

func (w *Widget) TableName() string        { return "widget" }
func (w *Widget) RBACResourceName() string { return "widget" }

Then create the repository and usecase:

// repository/widget/repository/repository.go
type Repository struct {
    generated.Repository[widget.Widget, uint64]
}

func New() *Repository {
    return &Repository{Repository: *generated.NewRepository[widget.Widget, uint64]()}
}

// repository/widget/usecase/usecase.go
type Usecase struct {
    generated.Usecase[widget.Widget, uint64]
}

func New(repo widget.Repository) *Usecase {
    return &Usecase{Usecase: generated.Usecase[widget.Widget, uint64]{Repo: repo}}
}

If your model already has ID, CreatedAt, UpdatedAt fields but no embeds, add the methods explicitly (value receiver required for GetID):

func (m Widget) GetID() uint64             { return m.ID }
func (m *Widget) SetID(id uint64)          { m.ID = id }
func (m *Widget) SetCreatedAt(t time.Time) { m.CreatedAt = t }
func (m *Widget) SetUpdatedAt(t time.Time) { m.UpdatedAt = t }
Query options (repository.QOption)

All mutation and query methods accept ...QOption instead of positional parameters. Options compose freely:

type QOption interface {
    PrepareQuery(query *gorm.DB) *gorm.DB
}

Built-in options:

Option Package Effect
historylog.Message("reason") repository/historylog Attaches a human-readable message to the mutation recorded in the history log
&repository.PreloadOption{Fields: []string{"ChildRoles"}} repository Adds GORM .Preload(...) calls
filter (*Filter implementing QOption) domain package Adds WHERE conditions
order (*Order implementing QOption) domain package Adds ORDER BY

Example:

id, err := roleRepo.Create(ctx, role, historylog.Message("initial seed"))

err = roleRepo.Delete(ctx, id, historylog.Message("cleanup"))
History log

Every write that goes through a GORM master connection registered with gormlog.Register(db) records a HistoryAction row. The optional historylog.Message(msg) option attaches a human-readable reason:

gormlog.Register(masterDatabase)

// in a usecase or resolver:
repo.Delete(ctx, id, historylog.Message("user requested account deletion"))
Mock generation

Mocks are generated with mockgen and committed as source code. Never edit mock files by hand — regenerate them:

make generate-code   # runs: go generate ./...

Each mock package carries the directive:

//go:generate mockgen -source=../repository.go -destination=../mocks/repository.go

Extending the GraphQL API

Base types ship with core fields only. Extend them in your app without forking library schemas:

# example/api/protocol/graphql/extensions/account.graphql
extend type Account {
  title: String!
  description: String!
  logoURI: String!
  # ...
}

extend input AccountInput { title: String }
extend input AccountListFilter { title: [String!] }
extend input AccountListOrder { title: Ordering }

Point gqlgen at base schemas and your extensions:

# example/api/protocol/graphql/gqlgen.yml
schema:
  - ../../../../protocol/graphql/schemas/*.graphql
  - ../../../../repository/**/*.graphql
  - ./extensions/*.graphql

Model binding rules:

Type Bind to Why
Extended Account, AccountInput, filters Generate in example/.../models/ Merged type from base + extend
Shared User, SessionToken, RBAC, … blaze-api/server/graphql/models Unchanged across consumers
AccountConnection, UserConnection, MemberConnection example/.../models/connections.go Uses extended node types

Regenerate and wire generic resolvers:

cd example/api/protocol/graphql && go run github.com/99designs/gqlgen
cd example/api && make build-api

Resolver wiring lives in example/api/internal/server/graphql/wiring/ (NewExampleAccountQueryResolver, NewExampleUserQueryResolver, NewExampleMemberQueryResolver).

Adding new domain types
  1. Add a .graphql schema file to protocol/graphql/schemas/ (or your app's schemas/ folder).
  2. Point gqlgen.yml at the schemas — the example app uses:
# example/api/protocol/graphql/gqlgen.yml
schema:
  - ../../../../protocol/graphql/schemas/*.graphql
  - ../../../../repository/**/*.graphql
  1. Regenerate:
cd example/api && make build-gql   # runs: go run github.com/99designs/gqlgen
  1. Implement the generated resolver stubs in internal/server/graphql/resolvers/.
# example/api/protocol/graphql/gqlgen.yml (excerpt — see repo for full file)
schema:
  - ../../../../protocol/graphql/schemas/*.graphql
  - ../../../../repository/**/*.graphql
  - ./extensions/*.graphql

models:
  User:
    model: github.com/geniusrabbit/blaze-api/server/graphql/models.User
  AccountConnection:
    model: github.com/geniusrabbit/blaze-api/example/api/internal/server/graphql/models.AccountConnection
  UserConnection:
    model: github.com/geniusrabbit/blaze-api/example/api/internal/server/graphql/models.UserConnection
  MemberConnection:
    model: github.com/geniusrabbit/blaze-api/example/api/internal/server/graphql/models.MemberConnection
  # ... other shared types bind to blaze-api/server/graphql/models
  # Account / AccountInput / filters: NOT bound — generated with extensions in example/models

Development

# Run all tests
make test

# Run tests with race detector + coverage report
make cover

# Regenerate mocks (go generate ./...)
make generate-code

# Regenerate GraphQL server code (gqlgen)
cd example/api && make build-gql

# Build the example API binary
cd example/api && make build-api

# Run full stack via Docker Compose (Postgres + migrations + API)
cd example/api && make run-api

# Lint
make lint

TODO

  • OAuth2 social providers: Google, LinkedIn, X.com (endpoints are already wired; need full handler)
  • REST API interface
  • Swagger / OpenAPI documentation
  • OpenTelemetry tracing (opentelemetry-go)

Features

  • Users: Manage user data and interactions.
  • Accounts: Handle account operations and storage.
  • Roles: Role-Based Access Control (RBAC) for managing user permissions.
  • Permissions: Define and manage access rights for different roles.
  • JWT Authentication: Secure your API with JWT-based authentication.
  • GraphQL API: Integrated GraphQL support for building flexible APIs.
  • OAuth2: Server and client support with remote authorization.
  • Object history log: Track all mutations with a per-request message.
  • Auth clients: OAuth2 client management (token issuance, revocation).
  • Generic repository/usecase layer: Type-safe CRUD with compile-time model constraints.
  • Tests: Comprehensive test suite for maintaining code quality.
  • Logging: Structured logging with context propagation.
  • REST API: RESTful API interface for your application.
  • Swagger API documentation: Generate comprehensive API documentation with Swagger.

Quick Start

Installation
go get github.com/geniusrabbit/blaze-api
Example Usage
// @see example/api/cmd/api/main.go
package main

import (
  ...
  "github.com/geniusrabbit/blaze-api/pkg/context/ctxlogger"
  "github.com/geniusrabbit/blaze-api/pkg/permissions"
  "github.com/geniusrabbit/blaze-api/pkg/database"
  "github.com/geniusrabbit/blaze-api/pkg/middleware"
  "github.com/geniusrabbit/blaze-api/repository/historylog/middleware/gormlog"
)

func main() {
  // Register callback for history log (only for modifications)
  gormlog.Register(masterDatabase)

  // Init permission manager
  permissionManager := permissions.NewManager(masterDatabase, conf.Permissions.RoleCacheLifetime)
  appinit.InitModelPermissions(permissionManager)

  // Init OAuth2 + JWT providers
  oauth2provider, jwtProvider := appinit.Auth(ctx, conf, masterDatabase)

  // Init HTTP server
  httpServer := server.HTTPServer{
    OAuth2provider: oauth2provider,
    JWTProvider:    jwtProvider,
    SessionManager: appinit.SessionManager("session", 60*time.Minute),
    AuthOption: gocast.IfThen(conf.IsDebug(), &middleware.AuthOption{
      DevToken:     conf.Session.DevToken,
      DevUserID:    conf.Session.DevUserID,
      DevAccountID: conf.Session.DevAccountID,
    }, nil),
    ContextWrap: func(ctx context.Context) context.Context {
      ctx = ctxlogger.WithLogger(ctx, loggerObj)
      ctx = database.WithDatabase(ctx, masterDatabase, slaveDatabase)
      ctx = permissionmanager.WithManager(ctx, permissionManager)
      return ctx
    },
  }
  httpServer.Run(ctx, ":8080")
}

Architecture

Repository / Usecase layer (repository/generated)

All domain entities follow the same layered pattern:

repository/<domain>/
  models/        — domain structs (must implement generated.Model[TID])
  repository.go  — domain Repository/Usecase interface
  repository/    — GORM implementation (embeds generated.Repository[T, TID])
  usecase/       — business logic (embeds generated.Usecase[T, TID])
  mocks/         — generated mocks (go:generate mockgen, DO NOT EDIT)
  delivery/      — transport adapters (GraphQL resolvers, REST handlers)

The generic base types live in repository/generated:

Type Description
Repository[T, TID] GORM CRUD implementation for any model satisfying Model[TID]
Usecase[T, TID] ACL-checked business logic delegating to RepositoryIface[T, TID]
UsecaseApprover[T, TID] Approve/reject workflow with ACL checks
BaseModel[TID] Convenience embed — provides GetID/SetID for free
BaseTimestamps Convenience embed — provides SetCreatedAt/SetUpdatedAt for free
Defining a new domain model

A model type T must satisfy the generated.Model[TID] constraint — i.e., expose GetID() TID via a value receiver. The easiest way is to embed generated.BaseModel:

import "github.com/geniusrabbit/blaze-api/repository/generated"

type Widget struct {
    generated.BaseModel[uint64]  // GetID() + SetID() for free
    generated.BaseTimestamps     // SetCreatedAt() + SetUpdatedAt() for free
    gorm.DeletedAt

    Name string
}

Then create the repository:

type Repository struct {
    generated.Repository[Widget, uint64]
}

func New() *Repository {
    return &Repository{Repository: *generated.NewRepository[Widget, uint64]()}
}

If your model already has ID, CreatedAt, UpdatedAt fields but no embeds, add the methods explicitly (value receiver required for GetID):

func (m Widget) GetID() uint64          { return m.ID }
func (m *Widget) SetID(id uint64)       { m.ID = id }
func (m *Widget) SetCreatedAt(t time.Time) { m.CreatedAt = t }
func (m *Widget) SetUpdatedAt(t time.Time) { m.UpdatedAt = t }
Query options (repository.QOption)

All mutation and query methods accept ...QOption instead of positional parameters. Options compose freely:

type QOption interface {
    PrepareQuery(query *gorm.DB) *gorm.DB
}

Built-in options:

Option Package Effect
historylog.Message("reason") repository/historylog Attaches a human-readable message to the mutation recorded in the history log
&repository.PreloadOption{Fields: []string{"ChildRoles"}} repository Adds GORM .Preload(...) calls
filter (*Filter implementing QOption) domain package Adds WHERE conditions
order (*Order implementing QOption) domain package Adds ORDER BY

Example:

id, err := roleRepo.Create(ctx, role, historylog.Message("initial seed"))

err = roleRepo.Delete(ctx, id,
    historylog.Message("cleanup"),
)
History log

Every write that goes through a GORM master connection registered with gormlog.Register(db) records a HistoryAction row. The optional historylog.Message(msg) option attaches a human-readable reason:

gormlog.Register(masterDatabase)

// later, in a usecase or resolver:
repo.Delete(ctx, id, historylog.Message("user requested account deletion"))
Mock generation

Mocks are generated with mockgen and committed as source code. Never edit mock files by hand — regenerate them:

make generate-code   # runs: go generate ./...

Each mock package carries the directive:

Each mock package carries the directive:

//go:generate mockgen -source=../repository.go -destination=../mocks/repository.go

Extending the GraphQL API

  1. Add a schema file to protocol/graphql/schemas/ (or your app's schemas/ folder).
  2. Reference it in gqlgen.yml:
schema:
  - ./schemas/*.graphql
  - ../../vendor/github.com/geniusrabbit/blaze-api/protocol/graphql/schemas/*.graphql
  - ../../vendor/github.com/geniusrabbit/blaze-api/repository/**/*.graphql
  1. Regenerate the server code:
make build-gql   # runs: go run github.com/99designs/gqlgen
  1. Implement the generated resolver stubs in internal/server/graphql/resolvers/.

A minimal gqlgen.yml for an application that imports blaze-api:

schema:
  - ./schemas/*.graphql
  - ../../vendor/github.com/geniusrabbit/blaze-api/protocol/graphql/schemas/*.graphql
  - ../../vendor/github.com/geniusrabbit/blaze-api/repository/**/*.graphql

skip_mod_tidy: yes

exec:
  filename: ../../internal/server/graphql/generated/exec.go
  package: generated

model:
  filename: ../../internal/server/graphql/models/generated.go
  package: models

resolver:
  layout: follow-schema
  dir: ../../internal/server/graphql/resolvers
  package: resolvers

omit_slice_element_pointers: false
skip_validation: true

autobind:
  - github.com/geniusrabbit/blaze-api/server/graphql/models

models:
  ID:
    model:
      - github.com/99designs/gqlgen/graphql.ID
      - github.com/99designs/gqlgen/graphql.Int64
  Int64:
    model:
      - github.com/99designs/gqlgen/graphql.Int64
  Time:
    model: github.com/geniusrabbit/blaze-api/server/graphql/types.Time
  JSON:
    model: github.com/geniusrabbit/blaze-api/server/graphql/types.JSON
  NullableJSON:
    model: github.com/geniusrabbit/blaze-api/server/graphql/types.NullableJSON
  UUID:
    model: github.com/geniusrabbit/blaze-api/server/graphql/types.UUID
  ID64:
    model: github.com/geniusrabbit/blaze-api/server/graphql/types.ID64
  UserConnection:
    model: github.com/geniusrabbit/blaze-api/server/graphql/connectors.UserConnection
  AccountConnection:
    model: github.com/geniusrabbit/blaze-api/server/graphql/connectors.AccountConnection
  RBACRoleConnection:
    model: github.com/geniusrabbit/blaze-api/server/graphql/connectors.RBACRoleConnection
  AuthClientConnection:
    model: github.com/geniusrabbit/blaze-api/server/graphql/connectors.AuthClientConnection
  HistoryActionConnection:
    model: github.com/geniusrabbit/blaze-api/server/graphql/connectors.HistoryActionConnection
  OptionConnection:
    model: github.com/geniusrabbit/blaze-api/server/graphql/connectors.OptionConnection

Development

# Run all tests
make test

# Run tests with coverage report
make cover

# Regenerate mocks and gqlgen code
make generate-code

# Build the example API
cd example/api && make build-api

# Lint
make lint

TODO

  • OAuth2 social providers: Google, Facebook, LinkedIn, GitHub
  • REST API interface
  • Swagger / OpenAPI documentation
  • OpenTelemetry tracing (opentelemetry-go)

Directories

Path Synopsis
example
api/cmd/api command
api/cmd/api/appcontext
Package appcontext provides config options
Package appcontext provides config options
pkg
acl
auth/elogin
Package elogin provides auth middle procedures for remote authentication including oauth2 and other protocols, and specific providers like google, facebook, etc.
Package elogin provides auth middle procedures for remote authentication including oauth2 and other protocols, and specific providers like google, facebook, etc.
auth/oauth2/serverprovider/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
gopentracing
Package gopentracing inites some opentracing interface
Package gopentracing inites some opentracing interface
Package repository contains control entety repositories
Package repository contains control entety repositories
account/delivery/graphql/account_login
Package accountlogin provides the email+password login mutation as a schema extension.
Package accountlogin provides the email+password login mutation as a schema extension.
account/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
account/usecase
Package usecase account implementation
Package usecase account implementation
authclient
Package authclient provides repository access for authentication client management.
Package authclient provides repository access for authentication client management.
authclient/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
authclient/repository
Package repository implements methods of working with the repository objects
Package repository implements methods of working with the repository objects
authclient/usecase
Package usecase account implementation
Package usecase account implementation
directaccesstoken/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
historylog
Package account present full API functionality of the specific object
Package account present full API functionality of the specific object
historylog/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
historylog/repository
Package repository implements methods of working with the repository objects
Package repository implements methods of working with the repository objects
historylog/usecase
Package usecase account implementation
Package usecase account implementation
option
Package option presents full API functionality of the specific object.
Package option presents full API functionality of the specific object.
option/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
option/repository
Package repository implements methods of working with the repository objects
Package repository implements methods of working with the repository objects
option/usecase
Package usecase provides business logic for option management
Package usecase provides business logic for option management
rbac
Package account present full API functionality of the specific object
Package account present full API functionality of the specific object
rbac/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
rbac/repository
Package repository implements methods of working with the repository objects
Package repository implements methods of working with the repository objects
rbac/usecase
Package usecase provides business logic for RBAC role management
Package usecase provides business logic for RBAC role management
user
Package user present full API functionality of the specific object
Package user present full API functionality of the specific object
user/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
user/usecase
Package usecase user managing
Package usecase user managing
server

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL