Showing preview only (384K chars total). Download the full file or copy to clipboard to get everything.
Repository: Aristat/golang-example-app
Branch: master
Commit: f7be6c387f0e
Files: 106
Total size: 354.4 KB
Directory structure:
gitextract_na8wnxnj/
├── .circleci/
│ └── config.yml
├── .gitignore
├── Makefile
├── README.md
├── app/
│ ├── auth/
│ │ ├── middleware.go
│ │ └── provider.go
│ ├── casbin/
│ │ └── provider.go
│ ├── common/
│ │ ├── bcrypt.go
│ │ ├── constants.go
│ │ ├── graphql.go
│ │ └── jaeger.go
│ ├── config/
│ │ ├── injector.go
│ │ ├── provider.go
│ │ └── wire_gen.go
│ ├── context/
│ │ └── context.go
│ ├── dataloader/
│ │ ├── dataloader.go
│ │ └── productitemloader_gen.go
│ ├── db/
│ │ ├── db.go
│ │ ├── domain/
│ │ │ ├── product.go
│ │ │ ├── product_item.go
│ │ │ └── user.go
│ │ ├── injector.go
│ │ ├── provider.go
│ │ ├── repo/
│ │ │ ├── provider.go
│ │ │ ├── users.go
│ │ │ └── users_test.go
│ │ └── wire_gen.go
│ ├── entrypoint/
│ │ ├── entrypoint.go
│ │ ├── entrypoint_test.go
│ │ └── provider.go
│ ├── graphql/
│ │ ├── graphql.go
│ │ └── provider.go
│ ├── graphql_resolver/
│ │ ├── injector.go
│ │ ├── mock.go
│ │ ├── product.go
│ │ ├── product_test.go
│ │ ├── provider.go
│ │ ├── resolver.go
│ │ ├── resolver_gen.go
│ │ ├── user.go
│ │ ├── user_test.go
│ │ └── wire_gen.go
│ ├── grpc/
│ │ ├── connection.go
│ │ ├── manager.go
│ │ ├── pool.go
│ │ └── provider.go
│ ├── http/
│ │ ├── http.go
│ │ ├── injector.go
│ │ ├── logger.go
│ │ ├── provider.go
│ │ └── wire_gen.go
│ ├── http_routers/
│ │ └── products-router/
│ │ ├── injector.go
│ │ ├── manager.go
│ │ ├── provider.go
│ │ ├── router.go
│ │ ├── router_test.go
│ │ └── wire_gen.go
│ ├── logger/
│ │ ├── injector.go
│ │ ├── logger.go
│ │ ├── middleware.go
│ │ ├── mock.go
│ │ ├── provider.go
│ │ ├── wire_gen.go
│ │ └── zap.go
│ ├── provider/
│ │ └── provider.go
│ └── tracing/
│ ├── jaeger.go
│ └── provider.go
├── cmd/
│ ├── daemon/
│ │ └── daemon.go
│ ├── health-check-service/
│ │ └── health_check_service.go
│ ├── jwt/
│ │ ├── jwt.go
│ │ └── token.go
│ ├── migrate/
│ │ └── migrate.go
│ ├── product-service/
│ │ ├── nats_service.go
│ │ └── product_service.go
│ └── root.go
├── dbconfig.yml
├── docker/
│ └── app/
│ ├── Dockerfile
│ └── files/
│ └── docker/
│ └── bin/
│ └── entrypoint.sh
├── docker-compose.yml
├── generated/
│ ├── graphql/
│ │ ├── generated.go
│ │ └── models_gen.go
│ └── resources/
│ └── proto/
│ ├── health_checks/
│ │ ├── health_checks.pb.go
│ │ └── health_checks_grpc.pb.go
│ └── products/
│ ├── products.pb.go
│ └── products_grpc.pb.go
├── go.mod
├── go.sum
├── gqlgen.yml
├── main.go
├── prototool.yaml
├── resources/
│ ├── casbin/
│ │ ├── model.conf
│ │ └── policy.csv
│ ├── configs/
│ │ ├── development.yaml
│ │ └── docker_development.yaml
│ ├── graphql/
│ │ ├── products.graphql
│ │ ├── root.graphql
│ │ └── user.graphql
│ ├── keys/
│ │ └── local/
│ │ ├── private_key.pem
│ │ └── public_key.pem
│ ├── migrations/
│ │ ├── 20181215164636-create_users.sql
│ │ └── 20181216210607-records.sql
│ ├── proto/
│ │ ├── health_checks/
│ │ │ └── health_checks.proto
│ │ └── products/
│ │ └── products.proto
│ └── templates/
│ └── helpers/
│ └── errors.html
└── scripts/
├── docker-compose-start.sh
└── remove_docker_containers.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .circleci/config.yml
================================================
version: 2.1
jobs:
test:
docker:
- image: cimg/go:1.17
working_directory: ~/golang-example-app
steps:
- checkout
- run:
name: "Setup APP_WD"
command: echo 'export APP_WD="$(cd ${CIRCLE_WORKING_DIRECTORY}; pwd)/resources"' >> $BASH_ENV
- run:
name: Fetch dependencies
command: go mod download
- run:
name: Test
command: go test ./...
build:
docker:
- image: cimg/go:1.17
working_directory: ~/golang-example-app
steps:
- checkout
- run:
name: Fetch dependencies
command: go mod download
- run:
name: Building
command: |
VERSION=${CIRCLE_TAG}
GOOS=linux GOARCH=amd64 go build -ldflags "-X main.Version=${VERSION}" -o bin/app-${VERSION}-linux-amd64 main.go
GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.Version=${VERSION}" -o bin/app-${VERSION}-darwin-amd64 main.go
- persist_to_workspace:
root: .
paths:
- bin
publish-github-release:
docker:
- image: cibuilds/github:0.13
steps:
- attach_workspace:
at: ~/golang-example-app
- run:
name: "Publish Release on GitHub"
command: |
VERSION=${CIRCLE_TAG}
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${VERSION} ~/golang-example-app/bin
workflows:
version: 2
main:
jobs:
- test
release:
jobs:
- build:
filters:
branches:
ignore: /.*/
tags:
only: /^v\d+\.\d+\.\d+.*/
- publish-github-release:
requires:
- build
filters:
branches:
ignore: /.*/
tags:
only: /^v\d+\.\d+\.\d+.*/
================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
vendor/
.idea/
artifacts/
coverage.out
.DS_Store
================================================
FILE: Makefile
================================================
GO_DIR ?= $(shell pwd)
GO_PKG ?= $(shell go list -e -f "{{ .ImportPath }}")
GOOS ?= $(shell go env GOOS || echo linux)
GOARCH ?= $(shell go env GOARCH || echo amd64)
CGO_ENABLED ?= 0
DOCKER_IMAGE ?= unknown
TAG ?= unknown
CACHE_TAG ?= unknown_cache
DATABASE_URL ?= golang_example_development
REMOVE_CONTAINERS ?= OFF
define build_resources
find "$(GO_DIR)/resources" -maxdepth 1 -mindepth 1 -exec cp -R -f {} $(GO_DIR)/artifacts/${1} \;
endef
install: init ## install cli tools
go get -v github.com/rubenv/sql-migrate/... ;\
go get -u github.com/google/wire/cmd/wire ;\
go get -u github.com/vektah/dataloaden ;
init: ## init packages
mkdir -p artifacts ;\
rm -rf artifacts/*
start: ## start daemon on development mode
./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d
dependencies: ## generate dependencies
go mod download
gqlgen-generate: ## generate graphql resolver
go run github.com/99designs/gqlgen
prototool-generate: ## generate proto file
protoc --go_out=generated --go_opt=paths=source_relative --go-grpc_out=generated --go-grpc_opt=paths=source_relative resources/proto/products/products.proto
protoc --go_out=generated --go_opt=paths=source_relative --go-grpc_out=generated --go-grpc_opt=paths=source_relative resources/proto/health_checks/health_checks.proto
build: init ## build binary file
$(call build_resources) ;\
GOOS=${GOOS} CGO_ENABLED=${CGO_ENABLED} GOARCH=${GOARCH} \
go build -ldflags "-X $(GO_PKG)/cmd/version.appVersion=$(TAG)-$$(date -u +%Y%m%d%H%M)" -o "$(GO_DIR)/artifacts/bin" main.go
docker-image: ## build docker image
REMOVE_CONTAINERS=${REMOVE_CONTAINERS} DOCKER_IMAGE=${DOCKER_IMAGE} ./scripts/remove_docker_containers.sh
docker rmi ${DOCKER_IMAGE}:${TAG} -f || true ;\
docker build --cache-from ${DOCKER_IMAGE}:${CACHE_TAG} -f "${GO_DIR}/docker/app/Dockerfile" -t ${DOCKER_IMAGE}:${TAG} ${GO_DIR}
test: ## test application with race
go test -v ./...
coverage: ## test coverage
go test -coverprofile=coverage.out ./...
go tool cover -html coverage.out
createdb: ## create database
createdb $(DATABASE_URL)
dropdb: ## drop database
dropdb $(DATABASE_URL)
.PHONY: install init dependencies gqlgen-generate prototool-generate
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.DEFAULT_GOAL := help
================================================
FILE: README.md
================================================

# Golang Example Application
# Table of Contents
- [Overview](#overview)
- [Package list](#package-list)
- [Installing](#installing)
* [Local environment](#local-environment)
* [Docker environment](#docker-enviroment)
- [Run services](#run-services)
* [Start in local](#start-in-local-machine)
* [Start in docker](#start-in-docker)
- [Getting started](#getting-started)
* [Jaeger](#jaeger)
* [Http with gRPC](#http-example-with-grpc)
* [Graphql with gRPC](#graphql-example-with-grpc)
- [Deprecate version](#deprecated-version)
- [Testing](#testing)
# Overview
This is an example golang application.
Commands list:
1. Daemon - main service
2. Product service - service that returns Product, an example of gRPC client/server interaction
3. Health check service - this service is needed to show how convenient to understand on which of the services an error occurred in jaeger
4. Migrate - commands for migration
5. JWT - commands for generate JWT token
# Package list
Packages which use in this example project
1. [sql-migrate](https://github.com/rubenv/sql-migrate) - SQL migrations
2. [wire](https://github.com/google/wire) - dependency Injection
3. [viper](https://github.com/spf13/viper) - environment configuration
4. [cobra](https://github.com/spf13/cobra) - create commands
5. [cast](https://github.com/spf13/cast) - easy casting from one type to another
6. [gorm](https://github.com/jinzhu/gorm) - database ORM
7. [zap](https://github.com/uber-go/zap) - logger
8. [mux](https://github.com/gorilla/mux) - http router
9. [nats-streaming](https://github.com/nats-io/stan.go) - NATS Streaming System
10. [gqlgen](https://github.com/99designs/gqlgen) - graphql server library
11. [protobuf](https://pkg.go.dev/google.golang.org/protobuf) - Google's data interchange format
12. [grpc](google.golang.org/grpc) - RPC framework
13. [opentelemetry](https://github.com/open-telemetry/opentelemetry-go) - OpenTelemetry
14. [jaeger](https://github.com/uber/jaeger-client-go) - Jaeger Bindings for Go OpenTelemetry API
15. [casbin](https://github.com/casbin/casbin) - Supports access control
16. [dataloaden](https://github.com/vektah/dataloaden) - DataLoader for graphql
17. [nats](https://github.com/nats-io/nats.go) - Golang client for NATS, the cloud native messaging system
# Installing
Install the Golang and GO environment
```$xslt
https://golang.org/doc/install
```
Install [Postgresql](https://www.postgresql.org/download) (if you want to run locally)
Clone repository
```$xslt
git clone git@github.com:Aristat/golang-example-app.git (go get)
```
## Local environment
Install Golang packages without modules
```$xslt
make install
```
Install database
```$xslt
make createdb
```
Sql migrations
```$xslt
sql-migrate up
```
Install Golang dependencies
```$xslt
make dependencies
```
Generate artifacts(binary files and configs)
```$xslt
make build
```
Packages for proto generator
```$xslt
https://grpc.io/docs/languages/go/quickstart/#prerequisites
```
Set APP_WD if you start to use html templates or path to ssh keys or run `make test`
```$xslt
export APP_WD=go_path to project_path/resources or project_path/artifacts
```
## Docker environment
Generate docker image
```$xslt
DOCKER_IMAGE=golang-example-app TAG=development make docker-image
```
# Run services
## Start in local machine
Up jaeger in docker-compose or disable Jaeger(and rebuild binary file) in `resources/configs/*.yaml`
```$xslt
docker-compose up jaeger
```
Start daemon (main service)
```$xslt
make start
```
or
```$xslt
./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d
```
Start product service
```$xslt
./artifacts/bin product-service -c ./artifacts/configs/development.yaml -d
```
Start health-check service
```$xslt
./artifacts/bin health-check -c ./artifacts/configs/development.yaml -d
```
## Start in docker
#### Run this commands
```$xslt
docker-compose rm # Remove previous containers
REMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image # Generate new docker image
docker-compose up
```
#### or run script
```$xslt
./scripts/docker-compose-start.sh
```
# Getting Started
## Jaeger
```$xslt
http://localhost:16686
```
## Http example with gRPC
```$xslt
http://localhost:9096/products_grpc
```
## Http example with Nats Streaming
```$xslt
http://localhost:9096/products_nats
```
## Http example with graceful shutdown(long request, you can check the server shutdown)
```$xslt
http://localhost:9096/products_slowly
```
## Graphql example with gRPC
Graphql [client](https://github.com/prisma-labs/graphql-playground) for testing. End-point `http://localhost:9096/query`.
Generate JWT for Graphql authorization
```$xslt
./artifacts/bin jwt token --key='./artifacts/keys/local/private_key.pem' --fields='{"sub": "owner", "iss": "test-service"}'
```
Set JWT token in headers
```$xslt
{
"Authorization": "bearer token"
}
```
Example query
```
query oneUser {
users {
one(email: "test@gmail.com") {
email
id
}
}
}
```
Example query with data loader
```
query allProducts {
products {
list {
products {
id
productItems {
id
name
}
}
}
}
}
```
Example mutation
```
mutation createUser {
users {
createUser(email: "test1@gmail.com", password: "123456789") {
id
email
}
}
}
```
# Testing
```
➜ make test
```
================================================
FILE: app/auth/middleware.go
================================================
package auth
import (
"io/ioutil"
"net/http"
"strings"
"github.com/aristat/golang-example-app/app/common"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/golang-jwt/jwt"
appContext "github.com/aristat/golang-example-app/app/context"
"github.com/pkg/errors"
)
const prefix = "app.auth"
const defaultSubject = "anonymous"
const defaultServiceName = "unknown"
const defaultServiceId = 0
var errPublicNotFound = errors.New("public key not found for issuer")
var errAuthJWT = errors.New("Authentication failed, JWT invalid")
// CustomClaims
type CustomClaims struct {
jwt.StandardClaims
}
// Config
type Config struct {
Services map[string]uint64
RelativePath string
}
// Middleware
type Middleware struct {
keys keys
cfg Config
log logger.Logger
}
// keys
type keys struct {
publicPemKey []byte
privatePemKey []byte
}
// Handler for check Bearer token
func (m Middleware) JWTHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
var (
token string
bearerToken = strings.Split(r.Header.Get("Authorization"), " ")
subject = defaultSubject
claims *CustomClaims
ok bool
)
if len(bearerToken) > 1 {
token = bearerToken[1]
} else {
common.SendGraphqlErrorf(w, http.StatusUnauthorized, "Not found authorization token")
return
}
t, err := jwt.ParseWithClaims(token, &CustomClaims{}, func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Claims.(*CustomClaims); ok {
return jwt.ParseRSAPublicKeyFromPEM(m.keys.publicPemKey)
}
m.log.Error("Public key not found: %s", logger.Args(errPublicNotFound.Error()))
return nil, errPublicNotFound
})
if err != nil {
m.log.Error("Parse error: %s", logger.Args(err.Error()))
common.SendGraphqlErrorf(w, http.StatusUnauthorized, err.Error())
return
}
if t.Valid {
if claims, ok = t.Claims.(*CustomClaims); ok {
subject = claims.Subject
}
} else {
m.log.Error("Validation Error: %s", logger.Args(errAuthJWT.Error()))
common.SendGraphqlErrorf(w, http.StatusUnauthorized, errAuthJWT.Error())
return
}
serviceName, serviceID := m.Service(claims)
r = r.WithContext(appContext.NewContext(r.Context(), appContext.Mapping{
Subject: subject,
ServiceId: serviceID,
ServiceName: serviceName,
}))
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
// Service returns service data as pair of name and id
func (m Middleware) Service(claims *CustomClaims) (string, uint64) {
if claims == nil {
return defaultServiceName, defaultServiceId
}
issuer := claims.Issuer
if id, ok := m.cfg.Services[issuer]; ok {
return claims.Issuer, id
}
return defaultServiceName, defaultServiceId
}
func NewMiddleware(cfg Config, log logger.Logger) (*Middleware, func(), error) {
rPath := strings.Trim(cfg.RelativePath, "/")
log = log.WithFields(logger.Fields{"service": prefix})
m := &Middleware{cfg: cfg, log: log}
publicKey, err := ioutil.ReadFile(entrypoint.WorkDir() + "/" + rPath + "/public_key.pem")
if err != nil {
return nil, func() {}, err
}
m.keys.publicPemKey = publicKey
m.keys.privatePemKey, err = ioutil.ReadFile(entrypoint.WorkDir() + "/" + rPath + "/private_key.pem")
if err != nil {
return nil, func() {}, err
}
return m, func() {}, nil
}
func NewTestMiddleware(log logger.Logger) (*Middleware, func(), error) {
log = log.WithFields(logger.Fields{"service": prefix})
private := ``
public := ``
middleware := &Middleware{
cfg: Config{},
keys: keys{
publicPemKey: []byte(public),
privatePemKey: []byte(private),
},
log: log,
}
return middleware, func() {}, nil
}
================================================
FILE: app/auth/provider.go
================================================
package auth
import (
"github.com/aristat/golang-example-app/app/logger"
"github.com/google/wire"
"github.com/spf13/viper"
)
// ProviderCfg
func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
c := Config{}
e := cfg.UnmarshalKey("auth", &c)
return c, func() {}, e
}
// Provider
func Provider(cfg Config, logger logger.Logger) (*Middleware, func(), error) {
return NewMiddleware(cfg, logger)
}
// ProviderTest
func ProviderTest(logger logger.Logger) (*Middleware, func(), error) {
return NewTestMiddleware(logger)
}
var (
ProviderProductionSet = wire.NewSet(Provider, ProviderCfg)
ProviderTestSet = wire.NewSet(ProviderTest)
)
================================================
FILE: app/casbin/provider.go
================================================
package casbin
import (
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/casbin/casbin"
fileadapter "github.com/casbin/casbin/persist/file-adapter"
"github.com/google/wire"
)
func Provider() (*casbin.Enforcer, func(), error) {
wd := entrypoint.WorkDir()
enf := casbin.NewEnforcer(wd+"/casbin/model.conf", wd+"/casbin/policy.csv")
return enf, func() {}, nil
}
func ProviderTest() (*casbin.Enforcer, func(), error) {
model := `
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
`
policy := `
p, reader, users, read
p, owner, users, write
g, reader, anonymous
g, owner, reader
`
enf := casbin.NewEnforcer(casbin.NewModel(model), fileadapter.NewAdapter(policy))
return enf, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider)
ProviderTestSet = wire.NewSet(ProviderTest)
)
================================================
FILE: app/common/bcrypt.go
================================================
package common
import "golang.org/x/crypto/bcrypt"
func HashPassword(password string, cost int) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), cost)
return string(bytes), err
}
func CheckPasswordHash(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
================================================
FILE: app/common/constants.go
================================================
package common
const (
SrvProducts = "products"
)
================================================
FILE: app/common/graphql.go
================================================
package common
import (
"encoding/json"
"fmt"
"net/http"
"github.com/vektah/gqlparser/v2/gqlerror"
"github.com/99designs/gqlgen/graphql"
)
func SendGraphqlError(w http.ResponseWriter, code int, errors gqlerror.List) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
b, err := json.Marshal(&graphql.Response{Errors: errors})
if err != nil {
panic(err)
}
w.Write(b)
}
func SendGraphqlErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) {
SendGraphqlError(w, code, gqlerror.List{{Message: fmt.Sprintf(format, args...)}})
}
================================================
FILE: app/common/jaeger.go
================================================
package common
import (
"github.com/aristat/golang-example-app/app/tracing"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"github.com/spf13/viper"
)
func GenerateTracerForTestClient(serviceName string, cfg *viper.Viper) (*tracesdk.TracerProvider, error) {
configuration := tracing.Configuration{}
err := cfg.UnmarshalKey("tracing.jaeger", &configuration)
if err != nil {
return nil, err
}
exp, err := jaeger.New(
jaeger.WithAgentEndpoint(
jaeger.WithAgentHost(configuration.AgentHost),
jaeger.WithAgentPort(configuration.AgentPort),
),
)
if err != nil {
return nil, err
}
tp := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName),
)),
)
return tp, nil
}
================================================
FILE: app/config/injector.go
================================================
// +build wireinject
package config
import (
"github.com/google/wire"
"github.com/spf13/viper"
)
// Build returns spf13/viper instance with resolved dependencies
func Build() (*viper.Viper, func(), error) {
panic(wire.Build(Provider))
}
================================================
FILE: app/config/provider.go
================================================
package config
import (
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/google/wire"
"github.com/spf13/viper"
)
// Provider returns spf13/viper instance with resolved dependencies
func Provider() (*viper.Viper, func(), error) {
v := entrypoint.Viper()
for _, key := range v.AllKeys() {
val := v.Get(key)
v.Set(key, val)
}
return v, func() {}, nil
}
var ProviderSet = wire.NewSet(Provider)
================================================
FILE: app/config/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package config
import (
"github.com/spf13/viper"
)
// Injectors from injector.go:
// Build returns spf13/viper instance with resolved dependencies
func Build() (*viper.Viper, func(), error) {
viperViper, cleanup, err := Provider()
if err != nil {
return nil, nil, err
}
return viperViper, func() {
cleanup()
}, nil
}
================================================
FILE: app/context/context.go
================================================
package context
import (
"context"
"github.com/mitchellh/mapstructure"
)
const prefix = "app.context"
// Manager
type Manager struct {
mapping *Mapping
ctx context.Context
}
func (m *Manager) ToMapping() *Mapping {
return &Mapping{
Subject: m.mapping.Subject,
ServiceId: m.mapping.ServiceId,
ServiceName: m.mapping.ServiceName,
}
}
// NewManager
func NewManager(ctx context.Context) (*Manager, error) {
m := &Manager{ctx: ctx}
mapping := &Mapping{}
config := &mapstructure.DecoderConfig{TagName: "json", Result: &mapping}
decoder, _ := mapstructure.NewDecoder(config)
err := decoder.Decode(ctx.Value(prefix))
if err != nil {
return nil, err
}
m.mapping = mapping
return m, nil
}
// Mapping
type Mapping struct {
Subject string
ServiceId uint64 `json:"service_id"`
ServiceName string `json:"service_name"`
}
// NewContext
func NewContext(ctx context.Context, m Mapping) context.Context {
return context.WithValue(ctx, prefix, map[string]interface{}{
"subject": m.Subject,
"service_id": m.ServiceId,
"service_name": m.ServiceName,
})
}
================================================
FILE: app/dataloader/dataloader.go
================================================
//go:generate go run github.com/vektah/dataloaden ProductItemLoader int []*github.com/aristat/golang-example-app/generated/domain.ProductItem
package dataloader
import (
"context"
"fmt"
"math/rand"
"net/http"
"strconv"
"strings"
"time"
"github.com/aristat/golang-example-app/app/db/domain"
)
type ctxKeyType struct{ name string }
var ctxKey = ctxKeyType{"userDataLoader"}
type loaders struct {
ProductItemsByProduct *ProductItemLoader
}
func LoaderMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ldrs := loaders{}
// set this to zero what happens without data loading
wait := 250 * time.Microsecond
ldrs.ProductItemsByProduct = &ProductItemLoader{
wait: wait,
maxBatch: 100,
fetch: func(keys []int) ([][]*domain.ProductItem, []error) {
fmt.Println("ProductItems Start Fetch")
var keySQL []string
for _, key := range keys {
keySQL = append(keySQL, strconv.Itoa(key))
}
fmt.Printf("SELECT * FROM product_items WHERE product_id IN (%s)\n", strings.Join(keySQL, ","))
time.Sleep(5 * time.Millisecond)
productItems := make([][]*domain.ProductItem, len(keys))
errors := make([]error, len(keys))
for i := range keys {
productItems[i] = []*domain.ProductItem{
{ID: 1, Name: "item " + strconv.Itoa(rand.Int()%20+20)},
{ID: 2, Name: "item " + strconv.Itoa(rand.Int()%20+20)},
}
}
return productItems, errors
},
}
dlCtx := context.WithValue(r.Context(), ctxKey, ldrs)
next.ServeHTTP(w, r.WithContext(dlCtx))
})
}
func CtxLoaders(ctx context.Context) loaders {
return ctx.Value(ctxKey).(loaders)
}
================================================
FILE: app/dataloader/productitemloader_gen.go
================================================
// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.
package dataloader
import (
"sync"
"time"
"github.com/aristat/golang-example-app/app/db/domain"
)
// ProductItemLoaderConfig captures the config to create a new ProductItemLoader
type ProductItemLoaderConfig struct {
// Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([][]*domain.ProductItem, []error)
// Wait is how long wait before sending a batch
Wait time.Duration
// MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit
MaxBatch int
}
// NewProductItemLoader creates a new ProductItemLoader given a fetch, wait, and maxBatch
func NewProductItemLoader(config ProductItemLoaderConfig) *ProductItemLoader {
return &ProductItemLoader{
fetch: config.Fetch,
wait: config.Wait,
maxBatch: config.MaxBatch,
}
}
// ProductItemLoader batches and caches requests
type ProductItemLoader struct {
// this method provides the data for the loader
fetch func(keys []int) ([][]*domain.ProductItem, []error)
// how long to done before sending a batch
wait time.Duration
// this will limit the maximum number of keys to send in one batch, 0 = no limit
maxBatch int
// INTERNAL
// lazily created cache
cache map[int][]*domain.ProductItem
// the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners
batch *productItemLoaderBatch
// mutex to prevent races
mu sync.Mutex
}
type productItemLoaderBatch struct {
keys []int
data [][]*domain.ProductItem
error []error
closing bool
done chan struct{}
}
// Load a ProductItem by key, batching and caching will be applied automatically
func (l *ProductItemLoader) Load(key int) ([]*domain.ProductItem, error) {
return l.LoadThunk(key)()
}
// LoadThunk returns a function that when called will block waiting for a ProductItem.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *ProductItemLoader) LoadThunk(key int) func() ([]*domain.ProductItem, error) {
l.mu.Lock()
if it, ok := l.cache[key]; ok {
l.mu.Unlock()
return func() ([]*domain.ProductItem, error) {
return it, nil
}
}
if l.batch == nil {
l.batch = &productItemLoaderBatch{done: make(chan struct{})}
}
batch := l.batch
pos := batch.keyIndex(l, key)
l.mu.Unlock()
return func() ([]*domain.ProductItem, error) {
<-batch.done
var data []*domain.ProductItem
if pos < len(batch.data) {
data = batch.data[pos]
}
var err error
// its convenient to be able to return a single error for everything
if len(batch.error) == 1 {
err = batch.error[0]
} else if batch.error != nil {
err = batch.error[pos]
}
if err == nil {
l.mu.Lock()
l.unsafeSet(key, data)
l.mu.Unlock()
}
return data, err
}
}
// LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured
func (l *ProductItemLoader) LoadAll(keys []int) ([][]*domain.ProductItem, []error) {
results := make([]func() ([]*domain.ProductItem, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
productItems := make([][]*domain.ProductItem, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
productItems[i], errors[i] = thunk()
}
return productItems, errors
}
// LoadAllThunk returns a function that when called will block waiting for a ProductItems.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *ProductItemLoader) LoadAllThunk(keys []int) func() ([][]*domain.ProductItem, []error) {
results := make([]func() ([]*domain.ProductItem, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
return func() ([][]*domain.ProductItem, []error) {
productItems := make([][]*domain.ProductItem, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
productItems[i], errors[i] = thunk()
}
return productItems, errors
}
}
// Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *ProductItemLoader) Prime(key int, value []*domain.ProductItem) bool {
l.mu.Lock()
var found bool
if _, found = l.cache[key]; !found {
// make a copy when writing to the cache, its easy to pass a pointer in from a loop var
// and end up with the whole cache pointing to the same value.
cpy := make([]*domain.ProductItem, len(value))
copy(cpy, value)
l.unsafeSet(key, cpy)
}
l.mu.Unlock()
return !found
}
// Clear the value at key from the cache, if it exists
func (l *ProductItemLoader) Clear(key int) {
l.mu.Lock()
delete(l.cache, key)
l.mu.Unlock()
}
func (l *ProductItemLoader) unsafeSet(key int, value []*domain.ProductItem) {
if l.cache == nil {
l.cache = map[int][]*domain.ProductItem{}
}
l.cache[key] = value
}
// keyIndex will return the location of the key in the batch, if its not found
// it will add the key to the batch
func (b *productItemLoaderBatch) keyIndex(l *ProductItemLoader, key int) int {
for i, existingKey := range b.keys {
if key == existingKey {
return i
}
}
pos := len(b.keys)
b.keys = append(b.keys, key)
if pos == 0 {
go b.startTimer(l)
}
if l.maxBatch != 0 && pos >= l.maxBatch-1 {
if !b.closing {
b.closing = true
l.batch = nil
go b.end(l)
}
}
return pos
}
func (b *productItemLoaderBatch) startTimer(l *ProductItemLoader) {
time.Sleep(l.wait)
l.mu.Lock()
// we must have hit a batch limit and are already finalizing this batch
if b.closing {
l.mu.Unlock()
return
}
l.batch = nil
l.mu.Unlock()
b.end(l)
}
func (b *productItemLoaderBatch) end(l *ProductItemLoader) {
b.data, b.error = l.fetch(b.keys)
close(b.done)
}
================================================
FILE: app/db/db.go
================================================
package db
import (
"context"
"time"
"github.com/jinzhu/gorm"
"github.com/aristat/golang-example-app/app/logger"
_ "github.com/lib/pq"
)
const prefix = "app.db"
// Config
type Config struct {
URL string
MaxOpenConns int
MaxIdleConns int
ConnMaxLifetime time.Duration
LogLevel logger.Level
}
// Http
type Manager struct {
ctx context.Context
cfg Config
log logger.Logger
DB *gorm.DB
}
// New
func New(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB) *Manager {
return &Manager{
ctx: ctx,
cfg: cfg,
log: log.WithFields(logger.Fields{"service": prefix}),
DB: db,
}
}
================================================
FILE: app/db/domain/product.go
================================================
package domain
type Product struct {
ID int
Name string
productItems []ProductItem
}
================================================
FILE: app/db/domain/product_item.go
================================================
package domain
type ProductItem struct {
ID int
Name string
}
================================================
FILE: app/db/domain/user.go
================================================
package domain
type User struct {
ID int `gorm:"column:id"`
Email string `gorm:"column:email"`
EncryptedPassword string `gorm:"column:encrypted_password"`
}
// UsersRepo interface
type UsersRepo interface {
CreateUser(email string, encryptPassword string) (*User, error)
FindByEmail(email string) (*User, error)
}
================================================
FILE: app/db/injector.go
================================================
// +build wireinject
package db
import (
"github.com/aristat/golang-example-app/app/provider"
"github.com/google/wire"
)
func Build() (*Manager, func(), error) {
panic(wire.Build(ProviderProductionSet, provider.AwareProductionSet))
}
func BuildTest() (*Manager, func(), error) {
panic(wire.Build(ProviderTestSet, provider.AwareTestSet))
}
================================================
FILE: app/db/provider.go
================================================
package db
import (
"context"
"database/sql"
"github.com/jinzhu/gorm"
"github.com/aristat/golang-example-app/app/logger"
"github.com/google/wire"
mocket "github.com/selvatico/go-mocket"
"github.com/spf13/viper"
)
// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
c := Config{LogLevel: logger.LevelDebug}
e := cfg.UnmarshalKey("db", &c)
if e != nil {
return c, func() {}, e
}
return c, func() {}, nil
}
// CfgTest
func CfgTest() (Config, func(), error) {
return Config{}, func() {}, nil
}
// ProviderGORM
func ProviderGORM(ctx context.Context, log logger.Logger, cfg Config) (*gorm.DB, func(), error) {
log = log.WithFields(logger.Fields{"service": prefix})
db, err := gorm.Open("postgres", cfg.URL)
db.DB().SetMaxOpenConns(cfg.MaxOpenConns)
db.DB().SetMaxIdleConns(cfg.MaxIdleConns)
db.DB().SetConnMaxLifetime(cfg.ConnMaxLifetime)
if cfg.LogLevel == logger.LevelDebug {
db.LogMode(true)
}
cleanup := func() {
if db != nil {
_ = db.Close()
}
log.Info("Closed db connections")
}
return db, cleanup, err
}
// ProviderGORMTest for test, using go-mocket
func ProviderGORMTest() (*gorm.DB, func(), error) {
var db *gorm.DB
cleanup := func() {
if db != nil {
_ = db.Close()
}
}
mocket.Catcher.Register()
mocket.Catcher.Logging = true
sqlDB, err := sql.Open(mocket.DriverName, "gorm")
if err != nil {
return db, cleanup, err
}
db, err = gorm.Open("postgres", sqlDB)
return db, cleanup, err
}
// Provider
func Provider(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB) (*Manager, func(), error) {
g := New(ctx, log, cfg, db)
return g, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, ProviderGORM, Cfg)
ProviderTestSet = wire.NewSet(Provider, ProviderGORMTest, CfgTest)
)
================================================
FILE: app/db/repo/provider.go
================================================
package repo
import (
"github.com/aristat/golang-example-app/app/db/domain"
"github.com/google/wire"
)
// Repo for all records
type Repo struct {
Users domain.UsersRepo
}
// Provider
func Provider(userDomain domain.UsersRepo) (*Repo, func(), error) {
repo := &Repo{
Users: userDomain,
}
return repo, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, NewUsersRepo)
ProviderTestSet = wire.NewSet(Provider, NewUsersRepo)
)
================================================
FILE: app/db/repo/users.go
================================================
package repo
import (
"github.com/aristat/golang-example-app/app/db/domain"
"github.com/jinzhu/gorm"
)
type UsersRepo struct {
db *gorm.DB
}
func (u *UsersRepo) CreateUser(email string, encryptPassword string) (*domain.User, error) {
user := &domain.User{Email: email, EncryptedPassword: encryptPassword}
if err := u.db.Create(user).Error; err != nil {
return nil, err
}
return user, nil
}
func (u *UsersRepo) FindByEmail(email string) (*domain.User, error) {
user := &domain.User{}
err := u.db.
Table("users").
Select("id, email, encrypted_password").
Where("users.email = ?", email).
Limit(1).
Scan(&user).Error
return user, err
}
func NewUsersRepo(db *gorm.DB) (domain.UsersRepo, func(), error) {
a := &UsersRepo{db: db}
return a, func() {}, nil
}
================================================
FILE: app/db/repo/users_test.go
================================================
package repo_test
import (
"errors"
"testing"
"golang.org/x/crypto/bcrypt"
"github.com/aristat/golang-example-app/app/db"
"github.com/aristat/golang-example-app/app/db/domain"
mocket "github.com/selvatico/go-mocket"
"github.com/aristat/golang-example-app/app/db/repo"
"github.com/stretchr/testify/assert"
)
var customInsertError = errors.New("sql: custom insert error")
func TestCreateUser(t *testing.T) {
mocket.Catcher.Logging = true
dbManager, _, e := db.BuildTest()
assert.Nil(t, e, "DB manager error should be nil")
userRepo, _, e := repo.NewUsersRepo(dbManager.DB)
assert.Nil(t, e, "Repo error should be nil")
defaultEmail := "test@gmail.com"
defaultPassword := "123456789"
primaryKey := 333
mockCreateWithError := func() {
mocket.Catcher.
Reset().
NewMock().
WithQuery("INSERT INTO \"users\" (\"email\",\"encrypted_password\") VALUES ($1,$2)").
WithArgs(defaultEmail, defaultPassword).
WithError(customInsertError)
}
mockCreate := func() {
reply := []map[string]interface{}{{"id": primaryKey}}
mocket.Catcher.
Reset().
NewMock().
WithQuery("INSERT INTO \"users\" (\"email\",\"encrypted_password\") VALUES ($1,$2)").
WithArgs(defaultEmail, defaultPassword).
WithReply(reply)
}
tests := []struct {
name string
mock func()
asserts func(user *domain.User, err error)
}{
{
name: "USER NOT CREATED",
mock: mockCreateWithError,
asserts: func(user *domain.User, err error) {
assert.Nil(t, user, "user should be nil")
assert.NotNil(t, err, "err should not be nil")
assert.Equal(t, customInsertError.Error(), err.Error())
},
},
{
name: "USER CREATED",
mock: mockCreate,
asserts: func(user *domain.User, err error) {
assert.Equal(t, primaryKey, user.ID)
assert.Nil(t, err, "err should be nil")
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.mock()
user, err := userRepo.CreateUser(defaultEmail, defaultPassword)
test.asserts(user, err)
})
}
}
func TestFindByEmail(t *testing.T) {
mocket.Catcher.Logging = true
dbManager, _, e := db.BuildTest()
assert.Nil(t, e, "DB manager error should be nil")
userRepo, _, e := repo.NewUsersRepo(dbManager.DB)
assert.Nil(t, e, "Repo error should be nil")
ePassword, e := bcrypt.GenerateFromPassword([]byte("12345"), 8)
assert.Nil(t, e, "Password is correct")
defaultEmail := "test@gmail.com"
mockSelect := func() {
reply := []map[string]interface{}{{"id": 1, "email": defaultEmail, "encrypted_password": ePassword}}
mocket.Catcher.Reset().NewMock().WithQuery(`WHERE (users.email = $1) LIMIT 1`).WithArgs(defaultEmail).WithReply(reply)
}
tests := []struct {
name string
mock func()
asserts func(user *domain.User, err error)
}{
{
name: "USER IS EMPTY",
mock: func() {},
asserts: func(user *domain.User, err error) {
assert.Equal(t, "", user.Email, "email should be equals")
assert.NotNil(t, err, "err should not be nil")
assert.Equal(t, err.Error(), "record not found", "error should be corrects")
},
},
{
name: "USER EXIST",
mock: mockSelect,
asserts: func(user *domain.User, err error) {
assert.Equal(t, defaultEmail, user.Email, "email should be equals")
assert.Nil(t, e, "err should be nil")
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
mocket.Catcher.Reset()
test.mock()
user, err := userRepo.FindByEmail(defaultEmail)
test.asserts(user, err)
})
}
}
================================================
FILE: app/db/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package db
import (
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/logger"
)
import (
_ "github.com/lib/pq"
)
// Injectors from injector.go:
func Build() (*Manager, func(), error) {
context, cleanup, err := entrypoint.ContextProvider()
if err != nil {
return nil, nil, err
}
viper, cleanup2, err := config.Provider()
if err != nil {
cleanup()
return nil, nil, err
}
loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
zap, cleanup4, err := logger.Provider(context, loggerConfig)
if err != nil {
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
dbConfig, cleanup5, err := Cfg(viper)
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
db, cleanup6, err := ProviderGORM(context, zap, dbConfig)
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
manager, cleanup7, err := Provider(context, zap, dbConfig, db)
if err != nil {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
return manager, func() {
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
func BuildTest() (*Manager, func(), error) {
context, cleanup, err := entrypoint.ContextProviderTest()
if err != nil {
return nil, nil, err
}
loggerConfig, cleanup2, err := logger.ProviderCfgTest()
if err != nil {
cleanup()
return nil, nil, err
}
mock, cleanup3, err := logger.ProviderTest(context, loggerConfig)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
dbConfig, cleanup4, err := CfgTest()
if err != nil {
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
db, cleanup5, err := ProviderGORMTest()
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
manager, cleanup6, err := Provider(context, mock, dbConfig, db)
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
return manager, func() {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
================================================
FILE: app/entrypoint/entrypoint.go
================================================
package entrypoint
import (
"context"
"os"
"sync"
"github.com/spf13/viper"
)
var (
vi *viper.Viper
mu sync.Mutex
reloadCh = make(chan struct{})
shutdownCtx context.Context
cancelFn context.CancelFunc
ep *EntryPoint
wd string
)
const prefix = "app.entrypoint"
func init() {
shutdownCtx, cancelFn = context.WithCancel(context.Background())
}
// Viper returns instance of Viper
func Viper() *viper.Viper {
mu.Lock()
defer mu.Unlock()
if vi != nil {
return vi
}
vi = viper.GetViper()
return vi
}
// Initialize returns instance of entry point singleton manager, workDir uses to attach templates
func Initialize(workDir string, v *viper.Viper) (*EntryPoint, error) {
mu.Lock()
defer mu.Unlock()
if ep != nil {
return ep, nil
}
if len(workDir) > 0 {
wd = workDir
} else {
wd, _ = os.Getwd()
}
vi, ep = v, &EntryPoint{}
return ep, nil
}
// OnShutdown subscribe on shutdown event for gracefully exit via context.
func OnShutdown() context.Context {
return shutdownCtx
}
// OnReload subscribe on reload event.
func OnReload() <-chan struct{} {
return reloadCh
}
// EntryPoint manager of single point of application
type EntryPoint struct {
}
// Shutdown raise shutdown event.
func Shutdown(ctx context.Context, code int) {
mu.Lock()
defer mu.Unlock()
cancelFn()
if _, ok := ctx.Deadline(); ok {
<-ctx.Done()
}
}
// Reload raise reload event.
func (e *EntryPoint) Reload() {
mu.Lock()
defer mu.Unlock()
ch := reloadCh
reloadCh = make(chan struct{})
close(ch)
}
// WorkDir returns current work directory
func WorkDir() string {
return wd
}
================================================
FILE: app/entrypoint/entrypoint_test.go
================================================
package entrypoint_test
import (
"os"
"path/filepath"
"testing"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/stretchr/testify/assert"
)
func TestInitialize(t *testing.T) {
wd, _ := filepath.Abs(os.Getenv("APP_WD"))
entryPoint, err := entrypoint.Initialize(wd, nil)
assert.Nil(t, err, "err should be nil")
assert.NotNil(t, entryPoint, "entryPoint should not be nil")
}
================================================
FILE: app/entrypoint/provider.go
================================================
package entrypoint
import (
"context"
"os"
"path/filepath"
"github.com/google/wire"
)
// ContextProvider
func ContextProvider() (context.Context, func(), error) {
c := OnShutdown()
return c, func() {}, nil
}
// ContextProviderTest
func ContextProviderTest() (context.Context, func(), error) {
// initializing
wd, _ := filepath.Abs(os.Getenv("APP_WD"))
_, err := Initialize(wd, nil)
c := context.Background()
return c, func() {}, err
}
var (
ProviderProductionSet = wire.NewSet(ContextProvider)
ProviderTestSet = wire.NewSet(ContextProviderTest)
)
================================================
FILE: app/graphql/graphql.go
================================================
package graphql
import (
"context"
"errors"
"net/http"
"strings"
"time"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/handler/lru"
"github.com/99designs/gqlgen/graphql/handler/transport"
gqlgen "github.com/99designs/gqlgen/graphql"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/generated/graphql"
"github.com/go-chi/chi/v5"
"github.com/vektah/gqlparser/v2/gqlerror"
)
const (
prefix = "app.graphql"
)
var errInternalServer = errors.New("internal server error")
// GraphQL
type GraphQL struct {
ctx context.Context
resolver *graphql.Config
log logger.Logger
cfg Config
}
// Use
func (g *GraphQL) Use(router *chi.Mux) {
router.Use(g.cfg.Middleware...)
}
// Routers
func (g *GraphQL) Routers(router chi.Router) {
srv := handler.New(graphql.NewExecutableSchema(*g.resolver))
srv.AddTransport(transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
})
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.AddTransport(transport.MultipartForm{})
srv.SetQueryCache(lru.New(1000))
if g.cfg.Introspection {
srv.Use(extension.Introspection{})
}
srv.Use(extension.AutomaticPersistedQuery{
Cache: lru.New(100),
})
srv.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
g.log.Alert("unhandled panic, err: %v", logger.Args(err))
return nil
})
srv.SetErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error {
if e != nil {
g.log.Alert("recover on middleware, err: %v", logger.Args(e))
goto done
}
e = errInternalServer
done:
return gqlgen.DefaultErrorPresenter(ctx, e)
})
if g.cfg.Debug {
srv.AroundResponses(func(ctx context.Context, next gqlgen.ResponseHandler) *gqlgen.Response {
startTime := time.Now()
rc := gqlgen.GetOperationContext(ctx)
resp := next(ctx)
g.log.Debug("\nVARS:\n%+v\nQUERY:\n%v\nRESPONSE:\n%v\nERROR:\n%v\n",
logger.Args(rc.Variables, strings.TrimRight(rc.RawQuery, "\n"), string(resp.Data), resp.Errors),
logger.WithFields(logger.Fields{
"time": time.Since(startTime).String(),
}),
)
return resp
})
}
router.Handle("/query", srv)
}
// Config
type Config struct {
Debug bool
Introspection bool
Name string
Middleware []func(http.Handler) http.Handler
}
// New
func New(ctx context.Context, resolver graphql.Config, log logger.Logger, cfg Config) *GraphQL {
log = log.WithFields(logger.Fields{"service": prefix})
return &GraphQL{
ctx: ctx,
resolver: &resolver,
cfg: cfg,
log: log,
}
}
================================================
FILE: app/graphql/provider.go
================================================
package graphql
import (
"context"
"github.com/aristat/golang-example-app/app/graphql_resolver"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/generated/graphql"
"github.com/google/wire"
"github.com/spf13/viper"
)
// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
c := Config{}
e := cfg.UnmarshalKey("graphql", &c)
if e != nil {
return c, func() {}, e
}
if cfg.IsSet("debug") && !c.Debug {
c.Debug = cfg.GetBool("debug")
}
return c, func() {}, nil
}
// CfgTest
func CfgTest() (Config, func(), error) {
return Config{}, func() {}, nil
}
// Provider
func Provider(ctx context.Context, resolver graphql.Config, log logger.Logger, cfg Config) (*GraphQL, func(), error) {
g := New(ctx, resolver, log, cfg)
return g, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, Cfg, graphql_resolver.ProviderProductionSet)
ProviderTestSet = wire.NewSet(Provider, CfgTest, graphql_resolver.ProviderTestSet)
)
================================================
FILE: app/graphql_resolver/injector.go
================================================
// +build wireinject
package graphql_resolver
import (
"github.com/aristat/golang-example-app/app/db"
"github.com/aristat/golang-example-app/app/db/repo"
"github.com/aristat/golang-example-app/app/provider"
"github.com/aristat/golang-example-app/generated/graphql"
"github.com/google/wire"
)
// Build
func Build() (graphql.Config, func(), error) {
panic(wire.Build(ProviderProductionSet, repo.ProviderProductionSet, db.ProviderProductionSet, provider.AwareProductionSet))
}
func BuildTest() (graphql.Config, func(), error) {
panic(wire.Build(ProviderTestSet, repo.ProviderTestSet, db.ProviderTestSet, provider.AwareTestSet))
}
================================================
FILE: app/graphql_resolver/mock.go
================================================
package graphql_resolver
import (
"context"
"fmt"
"github.com/aristat/golang-example-app/generated/resources/proto/products"
)
type ProductServerMock struct {
products.UnimplementedProductsServer
}
func (s *ProductServerMock) ListProduct(ctx context.Context, in *products.ListProductIn) (*products.ListProductOut, error) {
productIds := []int64{1, 2, 3, 4, 5}
out := &products.ListProductOut{Status: products.ListProductOut_OK, Products: []*products.Product{}}
for _, id := range productIds {
out.Products = append(out.Products, &products.Product{Id: id, Name: fmt.Sprintf("product_%d", id)})
}
return out, nil
}
================================================
FILE: app/graphql_resolver/product.go
================================================
package graphql_resolver
import (
"context"
"time"
"github.com/aristat/golang-example-app/app/dataloader"
"github.com/aristat/golang-example-app/app/db/domain"
"github.com/aristat/golang-example-app/app/common"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/generated/graphql"
"github.com/aristat/golang-example-app/generated/resources/proto/products"
"github.com/spf13/cast"
)
type productsQueryResolver struct{ *Resolver }
type productResolver struct{ *Resolver }
func (r *Resolver) ProductsQuery() graphql.ProductsQueryResolver {
return &productsQueryResolver{r}
}
// QUERY
func (r *queryResolver) Products(ctx context.Context) (*graphql.ProductsQuery, error) {
return &graphql.ProductsQuery{}, nil
}
func (r *productsQueryResolver) List(ctx context.Context, obj *graphql.ProductsQuery) (*graphql.ProductsListOut, error) {
conn, d, err := grpc.GetConnGRPC(r.pollManager, common.SrvProducts)
defer d()
if err != nil {
return nil, err
}
c := products.NewProductsClient(conn)
ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(r.cfg.ProductTimeout))
defer cancel()
productOut, err := c.ListProduct(ctx, &products.ListProductIn{Id: 1})
if err != nil {
return nil, err
}
list := make([]*domain.Product, len(productOut.Products))
for i, product := range productOut.Products {
list[i] = &domain.Product{
ID: cast.ToInt(&product.Id),
Name: product.Name,
}
}
return &graphql.ProductsListOut{Products: list}, nil
}
func (r *queryResolver) ProductsRoot(ctx context.Context) ([]*domain.Product, error) {
return []*domain.Product{{ID: 1, Name: "test1"}, {ID: 2, Name: "test2"}}, nil
}
func (r *Resolver) Product() graphql.ProductResolver {
return &productResolver{r}
}
func (r *productResolver) ProductItems(ctx context.Context, obj *domain.Product) ([]*domain.ProductItem, error) {
r.log.Info("ProductItems Start Request")
return dataloader.CtxLoaders(ctx).ProductItemsByProduct.Load(obj.ID)
}
================================================
FILE: app/graphql_resolver/product_test.go
================================================
package graphql_resolver_test
import (
"context"
"encoding/json"
"log"
"net"
"os"
"strconv"
"testing"
"github.com/aristat/golang-example-app/app/common"
"github.com/aristat/golang-example-app/generated/resources/proto/products"
"google.golang.org/grpc"
"github.com/stretchr/testify/assert"
"github.com/aristat/golang-example-app/app/graphql_resolver"
grpc1 "github.com/aristat/golang-example-app/app/grpc"
graphql1 "github.com/aristat/golang-example-app/generated/graphql"
)
var (
productServerHost = "localhost"
grpcPort string
)
func TestMain(m *testing.M) {
lis, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatalf(err.Error())
}
defer lis.Close()
grpcPort = ":" + strconv.Itoa(lis.Addr().(*net.TCPAddr).Port)
s := grpc.NewServer()
products.RegisterProductsServer(s, &graphql_resolver.ProductServerMock{})
go func() {
if err := s.Serve(lis); err != nil {
log.Fatalf("Server exited with error: %v", err)
}
}()
code := m.Run()
os.Exit(code)
}
func TestList(t *testing.T) {
var opts []grpc.DialOption
ctx := context.Background()
opts = append(opts, grpc.WithInsecure())
pool, _ := grpc1.NewPool(ctx, common.SrvProducts, productServerHost+grpcPort, grpc1.ConnOptions(opts...))
grpc1.SetPool(pool, common.SrvProducts)
cfg, _, err := graphql_resolver.BuildTest()
if err != nil {
assert.Failf(t, "graphql_resolver instance failed, err: %v", err.Error())
return
}
obj := graphql1.ProductsQuery{}
out, err := cfg.Resolvers.ProductsQuery().List(ctx, &obj)
if err != nil {
assert.Failf(t, "request failed, err: %v", err.Error())
return
}
jsonProducts, _ := json.Marshal(out.Products)
t.Log(string(jsonProducts))
assert.Equal(t, len(out.Products), 5)
}
================================================
FILE: app/graphql_resolver/provider.go
================================================
package graphql_resolver
import (
"context"
"github.com/casbin/casbin"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/generated/graphql"
"github.com/google/wire"
"github.com/spf13/viper"
)
// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
c := Config{}
e := cfg.UnmarshalKey("graphql_resolver", &c)
return c, func() {}, e
}
// CfgTest
func CfgTest() (Config, func(), error) {
return Config{ProductTimeout: 5}, func() {}, nil
}
var ProviderManagers = wire.NewSet(
wire.Struct(new(Managers), "*"),
)
// Provider
func Provider(ctx context.Context, log logger.Logger, cfg Config, enforcer *casbin.Enforcer, managers Managers) (graphql.Config, func(), error) {
c := New(ctx, log, cfg, enforcer, managers)
return c, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, Cfg, ProviderManagers)
ProviderTestSet = wire.NewSet(Provider, CfgTest, ProviderManagers)
)
================================================
FILE: app/graphql_resolver/resolver.go
================================================
package graphql_resolver
import (
"context"
"strings"
"github.com/pkg/errors"
"github.com/99designs/gqlgen/graphql"
"github.com/casbin/casbin"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/db/repo"
appContext "github.com/aristat/golang-example-app/app/context"
"github.com/aristat/golang-example-app/app/logger"
graphql1 "github.com/aristat/golang-example-app/generated/graphql"
)
var prefix = "app.graphql_resolver"
var errPermission = errors.WithMessage(errors.New("No have permission"), prefix)
// Config
type Config struct {
ProductTimeout int
}
// Managers
type Managers struct {
Repo *repo.Repo
PollManager *grpc.PoolManager
}
type queryResolver struct{ *Resolver }
type mutationResolver struct{ *Resolver }
// Resolver config graphql resolvers
type Resolver struct {
ctx context.Context
log logger.Logger
cfg Config
repo *repo.Repo
pollManager *grpc.PoolManager
}
// Mutation returns root graphql mutation graphql_resolver
func (r *Resolver) Mutation() graphql1.MutationResolver {
return &mutationResolver{r}
}
// Query returns root graphql query graphql_resolver
func (r *Resolver) Query() graphql1.QueryResolver {
return &queryResolver{r}
}
// New
func New(ctx context.Context, log logger.Logger, cfg Config, enforcer *casbin.Enforcer, managers Managers) graphql1.Config {
log = log.WithFields(logger.Fields{"service": prefix})
c := graphql1.Config{
Resolvers: &Resolver{
ctx: ctx,
log: log,
cfg: cfg,
repo: managers.Repo,
pollManager: managers.PollManager,
},
}
c.Directives.HasUsersPermission = func(ctx context.Context, obj interface{}, next graphql.Resolver, role graphql1.UsersPermissionEnum) (res interface{}, err error) {
m, err := appContext.NewManager(ctx)
if err != nil {
return nil, err
}
mapping := m.ToMapping()
if !enforcer.Enforce(mapping.Subject, "users", strings.ToLower(string(role))) {
return nil, errPermission
}
return next(ctx)
}
return c
}
================================================
FILE: app/graphql_resolver/resolver_gen.go
================================================
package graphql_resolver
================================================
FILE: app/graphql_resolver/user.go
================================================
package graphql_resolver
import (
"context"
"github.com/aristat/golang-example-app/app/common"
graphql1 "github.com/aristat/golang-example-app/generated/graphql"
"github.com/spf13/cast"
)
type usersQueryResolver struct{ *Resolver }
type usersMutationResolver struct{ *Resolver }
func (r *Resolver) UsersMutation() graphql1.UsersMutationResolver {
return &usersMutationResolver{r}
}
func (r *Resolver) UsersQuery() graphql1.UsersQueryResolver {
return &usersQueryResolver{r}
}
// QUERY
func (r *queryResolver) Users(ctx context.Context) (*graphql1.UsersQuery, error) {
return &graphql1.UsersQuery{}, nil
}
func (r *usersQueryResolver) One(ctx context.Context, obj *graphql1.UsersQuery, email string) (*graphql1.UsersOneOut, error) {
user, err := r.repo.Users.FindByEmail(email)
if err != nil {
return nil, err
}
userData := &graphql1.UsersOneOut{
ID: cast.ToString(&user.ID),
Email: user.Email,
}
return userData, nil
}
// MUTATIONS
func (r *mutationResolver) Users(ctx context.Context) (*graphql1.UsersMutation, error) {
return &graphql1.UsersMutation{}, nil
}
func (r *usersMutationResolver) CreateUser(ctx context.Context, obj *graphql1.UsersMutation, email string, password string) (*graphql1.UsersCreateOut, error) {
encryptPassword, err := common.HashPassword(password, 8)
if err != nil {
return nil, err
}
user, err := r.repo.Users.CreateUser(email, encryptPassword)
if err != nil {
return nil, err
}
userData := &graphql1.UsersCreateOut{
ID: cast.ToString(user.ID),
Email: user.Email,
Status: graphql1.UsersCreateOutStatusOk,
}
return userData, nil
}
================================================
FILE: app/graphql_resolver/user_test.go
================================================
package graphql_resolver_test
import (
"context"
"testing"
"github.com/spf13/cast"
"golang.org/x/crypto/bcrypt"
"github.com/stretchr/testify/assert"
"github.com/aristat/golang-example-app/app/graphql_resolver"
graphql1 "github.com/aristat/golang-example-app/generated/graphql"
mocket "github.com/selvatico/go-mocket"
)
type UserParams struct {
testName string
id int
email string
}
func TestOne(t *testing.T) {
ctx := context.Background()
cfg, _, err := graphql_resolver.BuildTest()
if err != nil {
assert.Failf(t, "graphql_resolver instance failed, err: %v", err.Error())
return
}
ePassword, e := bcrypt.GenerateFromPassword([]byte("12345"), 8)
assert.Nil(t, e, "Password is correct")
obj := graphql1.UsersQuery{}
defaultEmail := "test@gmail.com"
id := 1
mockDefaultResult := func() {
reply := []map[string]interface{}{{"id": id, "email": defaultEmail, "encrypted_password": ePassword}}
mocket.Catcher.Reset().NewMock().WithQuery(`WHERE (users.email = $1) LIMIT 1`).WithArgs(defaultEmail).WithReply(reply)
}
tests := []struct {
userParams UserParams
mock func()
asserts func(userParams UserParams, out *graphql1.UsersOneOut, err error)
}{
{
userParams: UserParams{id: 2, email: "test1@gmail.com", testName: "USER NOT EXIST"},
mock: mockDefaultResult,
asserts: func(userParams UserParams, out *graphql1.UsersOneOut, err error) {
assert.NotNil(t, err, "err should not be nil")
assert.Nil(t, out, "out should be nil")
},
},
{
userParams: UserParams{id: id, email: defaultEmail, testName: "USER EXIST"},
mock: mockDefaultResult,
asserts: func(userParams UserParams, out *graphql1.UsersOneOut, err error) {
assert.Nil(t, err, "err should be nil")
assert.Equal(t, cast.ToString(userParams.id), out.ID, "id should be equals")
assert.Equal(t, userParams.email, out.Email, "email should be equals")
},
},
}
for _, test := range tests {
t.Run(test.userParams.testName, func(t *testing.T) {
mocket.Catcher.Reset()
test.mock()
out, err := cfg.Resolvers.UsersQuery().One(ctx, &obj, test.userParams.email)
test.asserts(test.userParams, out, err)
})
}
}
================================================
FILE: app/graphql_resolver/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package graphql_resolver
import (
"github.com/aristat/golang-example-app/app/casbin"
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/db"
"github.com/aristat/golang-example-app/app/db/repo"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/app/tracing"
"github.com/aristat/golang-example-app/generated/graphql"
)
// Injectors from injector.go:
// Build
func Build() (graphql.Config, func(), error) {
context, cleanup, err := entrypoint.ContextProvider()
if err != nil {
return graphql.Config{}, nil, err
}
viper, cleanup2, err := config.Provider()
if err != nil {
cleanup()
return graphql.Config{}, nil, err
}
loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
if err != nil {
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
zap, cleanup4, err := logger.Provider(context, loggerConfig)
if err != nil {
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
graphql_resolverConfig, cleanup5, err := Cfg(viper)
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
enforcer, cleanup6, err := casbin.Provider()
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
dbConfig, cleanup7, err := db.Cfg(viper)
if err != nil {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
gormDB, cleanup8, err := db.ProviderGORM(context, zap, dbConfig)
if err != nil {
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
usersRepo, cleanup9, err := repo.NewUsersRepo(gormDB)
if err != nil {
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
repoRepo, cleanup10, err := repo.Provider(usersRepo)
if err != nil {
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
configuration, cleanup11, err := tracing.Cfg(viper)
if err != nil {
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
tracerProvider, cleanup12, err := tracing.Provider(context, configuration, zap)
if err != nil {
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
grpcConfig, cleanup13, err := grpc.Cfg(viper)
if err != nil {
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
poolManager, cleanup14, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)
if err != nil {
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
managers := Managers{
Repo: repoRepo,
PollManager: poolManager,
}
graphqlConfig, cleanup15, err := Provider(context, zap, graphql_resolverConfig, enforcer, managers)
if err != nil {
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
return graphqlConfig, func() {
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
func BuildTest() (graphql.Config, func(), error) {
context, cleanup, err := entrypoint.ContextProviderTest()
if err != nil {
return graphql.Config{}, nil, err
}
loggerConfig, cleanup2, err := logger.ProviderCfgTest()
if err != nil {
cleanup()
return graphql.Config{}, nil, err
}
mock, cleanup3, err := logger.ProviderTest(context, loggerConfig)
if err != nil {
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
graphql_resolverConfig, cleanup4, err := CfgTest()
if err != nil {
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
enforcer, cleanup5, err := casbin.ProviderTest()
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
gormDB, cleanup6, err := db.ProviderGORMTest()
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
usersRepo, cleanup7, err := repo.NewUsersRepo(gormDB)
if err != nil {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
repoRepo, cleanup8, err := repo.Provider(usersRepo)
if err != nil {
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
tracerProvider, cleanup9, err := tracing.ProviderTest()
if err != nil {
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
grpcConfig, cleanup10, err := grpc.CfgTest()
if err != nil {
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
poolManager, cleanup11, err := grpc.Provider(context, tracerProvider, mock, grpcConfig)
if err != nil {
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
managers := Managers{
Repo: repoRepo,
PollManager: poolManager,
}
graphqlConfig, cleanup12, err := Provider(context, mock, graphql_resolverConfig, enforcer, managers)
if err != nil {
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return graphql.Config{}, nil, err
}
return graphqlConfig, func() {
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
================================================
FILE: app/grpc/connection.go
================================================
package grpc
import (
"sync"
"google.golang.org/grpc"
)
var (
srvMu sync.Mutex
poolSrv = map[string]*Pool{}
)
// Set pool connections
func SetPool(p *Pool, srv string) {
if _, ok := poolSrv[srv]; !ok {
srvMu.Lock()
defer srvMu.Unlock()
poolSrv[srv] = p
}
}
// Get client connection
func GetConnGRPC(poolManager *PoolManager, srv string) (*grpc.ClientConn, Done, error) {
if _, ok := poolSrv[srv]; !ok {
srvMu.Lock()
defer srvMu.Unlock()
if _, ok := poolSrv[srv]; !ok {
p, _, e := poolManager.NewPool(srv)
if e != nil {
return nil, func() {}, e
}
poolSrv[srv] = p
}
}
return poolSrv[srv].Get()
}
================================================
FILE: app/grpc/manager.go
================================================
package grpc
import (
"context"
"errors"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
"google.golang.org/grpc/credentials/insecure"
"github.com/aristat/golang-example-app/app/logger"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
)
const prefix = "app.grpc"
var errCfgInvalid = errors.New("cfg is not present or invalid")
// PoolManager
type PoolManager struct {
ctx context.Context
tracing *tracesdk.TracerProvider
cfg *Config
logger logger.Logger
}
// New
func (p *PoolManager) NewPool(service string) (_ *Pool, loaded bool, _ error) {
s, ok := p.cfg.Services[service]
if !ok {
return nil, false, errCfgInvalid
}
var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
cl := s.ClientParameters
if cl == nil {
if p.cfg.ClientParameters != nil {
cl = p.cfg.ClientParameters
} else {
cl = &keepalive.ClientParameters{}
}
}
opts = append(opts, grpc.WithKeepaliveParams(*cl))
opts = append(opts,
grpc.WithChainUnaryInterceptor(
logger.UnaryClientInterceptor(p.logger, true),
otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(p.tracing), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
)
opts = append(opts,
grpc.WithChainStreamInterceptor(
logger.StreamClientInterceptor(p.logger, true),
otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(p.tracing), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
)
pool, l := NewPool(p.ctx, service, s.Target,
MaxConn(s.MaxConn),
InitConn(s.InitConn),
MaxLifeDuration(s.MaxLifeDuration),
IdleTimeout(s.IdleTimeout),
ConnOptions(opts...),
)
return pool, l, nil
}
// NewPoolManager
func NewPoolManager(ctx context.Context, tracing *tracesdk.TracerProvider, logger logger.Logger, cfg *Config) *PoolManager {
return &PoolManager{ctx: ctx, tracing: tracing, cfg: cfg, logger: logger}
}
================================================
FILE: app/grpc/pool.go
================================================
package grpc
import (
"context"
"sync"
"time"
"github.com/pkg/errors"
grpcpool "github.com/processout/grpc-go-pool"
"google.golang.org/grpc"
)
var (
poolList map[string]*Pool
mu sync.Mutex
)
// Done
type Done func()
type conn struct {
conn *grpc.ClientConn
pool *Pool
err error
}
func (c *conn) init() {
c.conn, c.err = grpc.Dial(c.pool.target, c.pool.opts.dialOptions...)
}
// Pool
type Pool struct {
id string
ctx context.Context
service string
pool *grpcpool.Pool
target string
opts *opts
}
// Get
func (p *Pool) Get() (*grpc.ClientConn, Done, error) {
c, e := p.pool.Get(p.ctx)
return c.ClientConn, func() {
_ = c.Close()
}, errors.WithMessage(e, prefix)
}
type opts struct {
dialOptions []grpc.DialOption
initConn int
maxConn int
idleTimeout time.Duration
maxLifeDuration time.Duration
}
// Option
type Option func(*opts) error
// ConnOptions
func ConnOptions(o ...grpc.DialOption) Option {
return func(f *opts) error {
f.dialOptions = o
return nil
}
}
// MaxConn
func MaxConn(value int) Option {
return func(f *opts) error {
f.maxConn = value
return nil
}
}
// InitConn
func InitConn(value int) Option {
return func(f *opts) error {
f.initConn = value
return nil
}
}
// MaxLifeDuration
func MaxLifeDuration(value time.Duration) Option {
return func(f *opts) error {
f.maxLifeDuration = value
return nil
}
}
// IdleTimeout
func IdleTimeout(value time.Duration) Option {
return func(f *opts) error {
f.idleTimeout = value
return nil
}
}
// NewPool
func NewPool(ctx context.Context, service, target string, o ...Option) (_ *Pool, loaded bool) {
mu.Lock()
defer mu.Unlock()
if p := poolList[service]; p != nil {
return p, true
}
p := &Pool{
id: time.Now().String(),
ctx: ctx,
service: service,
opts: &opts{},
target: target,
}
for _, option := range o {
_ = option(p.opts)
}
factory := func() (*grpc.ClientConn, error) {
c := &conn{pool: p}
c.init()
return c.conn, c.err
}
p.pool, _ = grpcpool.New(factory, p.opts.initConn, p.opts.maxConn, p.opts.idleTimeout, p.opts.maxLifeDuration)
return p, false
}
================================================
FILE: app/grpc/provider.go
================================================
package grpc
import (
"context"
"sync"
"time"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
"github.com/aristat/golang-example-app/app/logger"
"github.com/google/wire"
"github.com/spf13/viper"
"google.golang.org/grpc/keepalive"
)
var (
pm *PoolManager
mutexPM sync.Mutex
)
// Cfg
func Cfg(cfg *viper.Viper) (*Config, func(), error) {
c := &Config{}
e := cfg.UnmarshalKey("grpc", c)
if e != nil {
return c, func() {}, e
}
return c, func() {}, e
}
// CfgTest
func CfgTest() (*Config, func(), error) {
return &Config{}, func() {}, nil
}
// Service
type Service struct {
Target string
MaxConn int
InitConn int
MaxLifeDuration time.Duration
IdleTimeout time.Duration
ClientParameters *keepalive.ClientParameters
}
// Config
type Config struct {
Services map[string]*Service
ClientParameters *keepalive.ClientParameters
}
// Provider
func Provider(ctx context.Context, tracing *tracesdk.TracerProvider, logger logger.Logger, cfg *Config) (*PoolManager, func(), error) {
mutexPM.Lock()
defer mutexPM.Unlock()
if pm != nil {
return pm, func() {}, nil
}
pm = NewPoolManager(ctx, tracing, logger, cfg)
return pm, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, Cfg)
ProviderTestSet = wire.NewSet(Provider, CfgTest)
)
================================================
FILE: app/http/http.go
================================================
package http
import (
"context"
"net/http"
"sync"
"github.com/go-chi/chi/v5"
"github.com/go-session/session"
"github.com/aristat/golang-example-app/app/logger"
)
const prefix = "app.http"
// Config
type Config struct {
Debug bool
Bind string
}
// Http
type Http struct {
ctx context.Context
cfg Config
session *session.Manager
log logger.Logger
mux *chi.Mux
}
// ListenAndServe
func (m *Http) ListenAndServe(wg *sync.WaitGroup, bind ...string) (server *http.Server) {
bindAddress := m.cfg.Bind
if len(bind) > 0 && len(bind[0]) > 0 {
bindAddress = bind[0]
}
server = &http.Server{
Addr: bindAddress,
Handler: m.mux,
}
go func() {
defer wg.Done()
if err := server.ListenAndServe(); err != nil {
if err != http.ErrServerClosed {
m.log.Emergency("Server is shutdown with error, %v", logger.Args(err))
} else {
err = nil
}
}
m.log.Info("HTTP Server stopped successfully")
}()
return server
}
// New
func New(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Config) *Http {
return &Http{
ctx: ctx,
cfg: cfg,
mux: mux,
log: log.WithFields(logger.Fields{"service": prefix}),
}
}
================================================
FILE: app/http/injector.go
================================================
// +build wireinject
package http
import (
"github.com/aristat/golang-example-app/app/auth"
"github.com/aristat/golang-example-app/app/db"
"github.com/aristat/golang-example-app/app/db/repo"
"github.com/aristat/golang-example-app/app/graphql"
products_router "github.com/aristat/golang-example-app/app/http_routers/products-router"
"github.com/aristat/golang-example-app/app/provider"
"github.com/google/wire"
)
// Build
func Build() (*Http, func(), error) {
panic(wire.Build(
ProviderProductionSet,
auth.ProviderProductionSet,
graphql.ProviderProductionSet,
products_router.ProviderProductionSet,
repo.ProviderProductionSet,
db.ProviderProductionSet,
provider.AwareProductionSet,
))
}
================================================
FILE: app/http/logger.go
================================================
package http
import (
"net/http"
"time"
"github.com/aristat/golang-example-app/app/logger"
"github.com/go-chi/chi/v5/middleware"
)
func Logger(l logger.Logger) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
t1 := time.Now()
defer func() {
l.Info("proto %s, path %s, lat %d, status %d, size %d, reqId %s", logger.Args(
r.Proto,
r.URL.Path,
time.Since(t1),
ww.Status(),
ww.BytesWritten(),
middleware.GetReqID(r.Context()),
))
}()
next.ServeHTTP(ww, r)
}
return http.HandlerFunc(fn)
}
}
================================================
FILE: app/http/provider.go
================================================
package http
import (
"context"
"github.com/riandyrn/otelchi"
"github.com/aristat/golang-example-app/app/dataloader"
products_router "github.com/aristat/golang-example-app/app/http_routers/products-router"
"github.com/aristat/golang-example-app/app/auth"
"github.com/aristat/golang-example-app/app/graphql"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/aristat/golang-example-app/app/logger"
"github.com/google/wire"
"github.com/spf13/viper"
)
var muxRouter *chi.Mux
// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
c := Config{}
e := cfg.UnmarshalKey("http", &c)
if e != nil {
return c, func() {}, e
}
c.Debug = cfg.GetBool("debug")
return c, func() {}, nil
}
// CfgTest
func CfgTest() (Config, func(), error) {
return Config{}, func() {}, nil
}
// Mux
func Mux(managers Managers, log logger.Logger) (*chi.Mux, func(), error) {
if muxRouter != nil {
return muxRouter, func() {}, nil
}
muxRouter = chi.NewRouter()
muxRouter.Use(middleware.RequestID)
muxRouter.Use(Logger(log))
muxRouter.Use(otelchi.Middleware("http-server", otelchi.WithChiRoutes(muxRouter)))
muxRouter.Use(dataloader.LoaderMiddleware)
managers.products.Router.Run(muxRouter)
managers.graphql.Routers(muxRouter.With(managers.authMiddleware.JWTHandler))
return muxRouter, func() {}, nil
}
// ServiceManagers
type Managers struct {
products *products_router.Manager
authMiddleware *auth.Middleware
graphql *graphql.GraphQL
}
var ProviderManagers = wire.NewSet(
wire.Struct(new(Managers), "*"),
)
// Provider
func Provider(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Config) (*Http, func(), error) {
g := New(ctx, mux, log, cfg)
return g, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, Cfg, Mux, ProviderManagers)
ProviderTestSet = wire.NewSet(Provider, CfgTest)
)
================================================
FILE: app/http/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package http
import (
"github.com/aristat/golang-example-app/app/auth"
"github.com/aristat/golang-example-app/app/casbin"
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/db"
"github.com/aristat/golang-example-app/app/db/repo"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/graphql"
"github.com/aristat/golang-example-app/app/graphql_resolver"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/http_routers/products-router"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/app/tracing"
)
// Injectors from injector.go:
// Build
func Build() (*Http, func(), error) {
context, cleanup, err := entrypoint.ContextProvider()
if err != nil {
return nil, nil, err
}
viper, cleanup2, err := config.Provider()
if err != nil {
cleanup()
return nil, nil, err
}
loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
zap, cleanup4, err := logger.Provider(context, loggerConfig)
if err != nil {
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
configuration, cleanup5, err := tracing.Cfg(viper)
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
tracerProvider, cleanup6, err := tracing.Provider(context, configuration, zap)
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
grpcConfig, cleanup7, err := grpc.Cfg(viper)
if err != nil {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
poolManager, cleanup8, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)
if err != nil {
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
serviceManagers := products_router.ServiceManagers{
PoolManager: poolManager,
}
products_routerConfig, cleanup9, err := products_router.Cfg(viper)
if err != nil {
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
manager, cleanup10, err := products_router.Provider(context, zap, serviceManagers, products_routerConfig)
if err != nil {
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
authConfig, cleanup11, err := auth.ProviderCfg(viper)
if err != nil {
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
middleware, cleanup12, err := auth.Provider(authConfig, zap)
if err != nil {
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
graphql_resolverConfig, cleanup13, err := graphql_resolver.Cfg(viper)
if err != nil {
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
enforcer, cleanup14, err := casbin.Provider()
if err != nil {
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
dbConfig, cleanup15, err := db.Cfg(viper)
if err != nil {
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
gormDB, cleanup16, err := db.ProviderGORM(context, zap, dbConfig)
if err != nil {
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
usersRepo, cleanup17, err := repo.NewUsersRepo(gormDB)
if err != nil {
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
repoRepo, cleanup18, err := repo.Provider(usersRepo)
if err != nil {
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
managers := graphql_resolver.Managers{
Repo: repoRepo,
PollManager: poolManager,
}
graphqlConfig, cleanup19, err := graphql_resolver.Provider(context, zap, graphql_resolverConfig, enforcer, managers)
if err != nil {
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
config2, cleanup20, err := graphql.Cfg(viper)
if err != nil {
cleanup19()
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
graphQL, cleanup21, err := graphql.Provider(context, graphqlConfig, zap, config2)
if err != nil {
cleanup20()
cleanup19()
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
httpManagers := Managers{
products: manager,
authMiddleware: middleware,
graphql: graphQL,
}
mux, cleanup22, err := Mux(httpManagers, zap)
if err != nil {
cleanup21()
cleanup20()
cleanup19()
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
httpConfig, cleanup23, err := Cfg(viper)
if err != nil {
cleanup22()
cleanup21()
cleanup20()
cleanup19()
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
http, cleanup24, err := Provider(context, mux, zap, httpConfig)
if err != nil {
cleanup23()
cleanup22()
cleanup21()
cleanup20()
cleanup19()
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
return http, func() {
cleanup24()
cleanup23()
cleanup22()
cleanup21()
cleanup20()
cleanup19()
cleanup18()
cleanup17()
cleanup16()
cleanup15()
cleanup14()
cleanup13()
cleanup12()
cleanup11()
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
================================================
FILE: app/http_routers/products-router/injector.go
================================================
// +build wireinject
package products_router
import (
"github.com/aristat/golang-example-app/app/provider"
"github.com/google/wire"
)
// Build
func Build() (*Manager, func(), error) {
panic(wire.Build(ProviderProductionSet, provider.AwareProductionSet))
}
func BuildTest() (*Manager, func(), error) {
panic(wire.Build(ProviderTestSet, provider.AwareTestSet))
}
================================================
FILE: app/http_routers/products-router/manager.go
================================================
package products_router
import (
"context"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/logger"
)
const prefix = "app.products-router"
// Product Manager
type Manager struct {
ctx context.Context
logger logger.Logger
Router *Router
}
// ServiceManagers
type ServiceManagers struct {
PoolManager *grpc.PoolManager
}
func New(ctx context.Context, log logger.Logger, managers ServiceManagers, cfg *Config) *Manager {
log = log.WithFields(logger.Fields{"service": prefix})
router := &Router{
ctx: ctx,
cfg: cfg,
logger: log,
poolManager: managers.PoolManager,
}
return &Manager{
ctx: ctx,
logger: log,
Router: router,
}
}
================================================
FILE: app/http_routers/products-router/provider.go
================================================
package products_router
import (
"context"
"github.com/aristat/golang-example-app/app/logger"
"github.com/google/wire"
"github.com/spf13/viper"
)
// Cfg
func Cfg(cfg *viper.Viper) (*Config, func(), error) {
c := &Config{}
e := cfg.UnmarshalKey("products", c)
if e != nil {
return c, func() {}, e
}
return c, func() {}, e
}
// CfgTest
func CfgTest() (*Config, func(), error) {
return &Config{}, func() {}, nil
}
// Config
type Config struct {
NatsURL string
Subject string
}
var ProviderManagers = wire.NewSet(
wire.Struct(new(ServiceManagers), "*"),
)
// Provider
func Provider(ctx context.Context, log logger.Logger, managers ServiceManagers, cfg *Config) (*Manager, func(), error) {
g := New(ctx, log, managers, cfg)
return g, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, ProviderManagers, Cfg)
ProviderTestSet = wire.NewSet(Provider, ProviderManagers, CfgTest)
)
================================================
FILE: app/http_routers/products-router/router.go
================================================
package products_router
import (
"context"
"encoding/json"
"net/http"
"time"
"github.com/nats-io/stan.go"
"github.com/aristat/golang-example-app/app/common"
"github.com/go-chi/chi/v5"
"github.com/nats-io/nats.go"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/generated/resources/proto/products"
)
type Router struct {
ctx context.Context
cfg *Config
logger logger.Logger
poolManager *grpc.PoolManager
}
func (router *Router) Run(chiRouter chi.Router) {
chiRouter.Get("/products_grpc", router.GetProductsGrpc)
chiRouter.Get("/products_nats", router.GetProductsNats)
chiRouter.Get("/products_slowly", router.GetProductsSlowly)
}
func (router *Router) GetProductsGrpc(w http.ResponseWriter, r *http.Request) {
conn, d, err := grpc.GetConnGRPC(router.poolManager, common.SrvProducts)
defer d()
defer r.Body.Close()
if err != nil {
router.logger.Printf("[ERROR] %s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c := products.NewProductsClient(conn)
ctx, cancel := context.WithTimeout(r.Context(), time.Second)
defer cancel()
e := json.NewEncoder(w)
productOut, err := c.ListProduct(ctx, &products.ListProductIn{Id: 1})
if err != nil {
w.WriteHeader(http.StatusBadGateway)
e.Encode("{}")
return
}
e.Encode(productOut)
}
func (router *Router) GetProductsNats(w http.ResponseWriter, r *http.Request) {
// Connect to NATS
nc, err := nats.Connect(router.cfg.NatsURL)
if err != nil {
router.logger.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer nc.Close()
sc, err := stan.Connect("test-cluster", "stan-pub", stan.NatsConn(nc))
if err != nil {
router.logger.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Close connection
defer sc.Close()
message := "Hello"
router.logger.Printf("[NATS] send %s", message)
err = sc.Publish(router.cfg.Subject, []byte(message))
if err != nil {
router.logger.Printf("[ERROR] %s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
e := json.NewEncoder(w)
e.Encode("done")
}
func (router *Router) GetProductsSlowly(w http.ResponseWriter, r *http.Request) {
router.logger.Info("Start sleep")
time.Sleep(time.Second * 10)
router.logger.Info("Stop sleep")
e := json.NewEncoder(w)
e.Encode("")
}
================================================
FILE: app/http_routers/products-router/router_test.go
================================================
package products_router_test
import (
"context"
"log"
"net"
"net/http"
"net/http/httptest"
"os"
"strconv"
"strings"
"testing"
products_router "github.com/aristat/golang-example-app/app/http_routers/products-router"
"github.com/stretchr/testify/assert"
"github.com/aristat/golang-example-app/app/common"
grpc1 "github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/graphql_resolver"
"github.com/aristat/golang-example-app/generated/resources/proto/products"
"google.golang.org/grpc"
)
var (
productServerHost = "localhost"
grpcPort string
)
func TestMain(m *testing.M) {
lis, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatalf(err.Error())
}
defer lis.Close()
grpcPort = ":" + strconv.Itoa(lis.Addr().(*net.TCPAddr).Port)
s := grpc.NewServer()
products.RegisterProductsServer(s, &graphql_resolver.ProductServerMock{})
go func() {
if err := s.Serve(lis); err != nil {
log.Fatalf("Server exited with error: %v", err)
}
}()
code := m.Run()
os.Exit(code)
}
func TestGetProductsGrpc(t *testing.T) {
var opts []grpc.DialOption
ctx := context.Background()
opts = append(opts, grpc.WithInsecure())
pool, _ := grpc1.NewPool(ctx, common.SrvProducts, productServerHost+grpcPort, grpc1.ConnOptions(opts...))
grpc1.SetPool(pool, common.SrvProducts)
tests := []struct {
name string
expectedCode int
}{
{
name: "successful",
expectedCode: http.StatusOK,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
provider, _, e := products_router.BuildTest()
assert.Nil(t, e, "err should be nil")
rec := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/products_grpc", strings.NewReader(""))
provider.Router.GetProductsGrpc(rec, req)
assert.Equal(t, test.expectedCode, rec.Code)
assert.NotNil(t, rec.Body)
})
}
}
================================================
FILE: app/http_routers/products-router/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package products_router
import (
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/app/tracing"
)
// Injectors from injector.go:
// Build
func Build() (*Manager, func(), error) {
context, cleanup, err := entrypoint.ContextProvider()
if err != nil {
return nil, nil, err
}
viper, cleanup2, err := config.Provider()
if err != nil {
cleanup()
return nil, nil, err
}
loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
zap, cleanup4, err := logger.Provider(context, loggerConfig)
if err != nil {
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
configuration, cleanup5, err := tracing.Cfg(viper)
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
tracerProvider, cleanup6, err := tracing.Provider(context, configuration, zap)
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
grpcConfig, cleanup7, err := grpc.Cfg(viper)
if err != nil {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
poolManager, cleanup8, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)
if err != nil {
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
serviceManagers := ServiceManagers{
PoolManager: poolManager,
}
products_routerConfig, cleanup9, err := Cfg(viper)
if err != nil {
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
manager, cleanup10, err := Provider(context, zap, serviceManagers, products_routerConfig)
if err != nil {
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
return manager, func() {
cleanup10()
cleanup9()
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
func BuildTest() (*Manager, func(), error) {
context, cleanup, err := entrypoint.ContextProviderTest()
if err != nil {
return nil, nil, err
}
loggerConfig, cleanup2, err := logger.ProviderCfgTest()
if err != nil {
cleanup()
return nil, nil, err
}
mock, cleanup3, err := logger.ProviderTest(context, loggerConfig)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
tracerProvider, cleanup4, err := tracing.ProviderTest()
if err != nil {
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
grpcConfig, cleanup5, err := grpc.CfgTest()
if err != nil {
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
poolManager, cleanup6, err := grpc.Provider(context, tracerProvider, mock, grpcConfig)
if err != nil {
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
serviceManagers := ServiceManagers{
PoolManager: poolManager,
}
products_routerConfig, cleanup7, err := CfgTest()
if err != nil {
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
manager, cleanup8, err := Provider(context, mock, serviceManagers, products_routerConfig)
if err != nil {
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
return manager, func() {
cleanup8()
cleanup7()
cleanup6()
cleanup5()
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
================================================
FILE: app/logger/injector.go
================================================
// +build wireinject
package logger
import (
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/google/wire"
)
// Build returns logger instance implemented of Logger interface with resolved dependencies
func Build() (Logger, func(), error) {
panic(wire.Build(ProviderProductionSet, entrypoint.ProviderProductionSet, config.ProviderSet))
}
func BuildTest() (Logger, func(), error) {
panic(wire.Build(ProviderTestSet, entrypoint.ProviderTestSet))
}
================================================
FILE: app/logger/logger.go
================================================
package logger
type (
Fields map[string]interface{}
)
// Level represent RFC5424 logger severity
type Level int8
// String implements interface Stringer
func (l Level) String() string {
switch l {
case LevelDebug:
return "debug"
case LevelInfo:
return "info"
case LevelNotice:
return "notice"
case LevelWarning:
return "warning"
case LevelError:
return "error"
case LevelCritical:
return "critical"
case LevelAlert:
return "alert"
case LevelEmergency:
return "emergency"
}
return "unknown"
}
// FromString set logger level from string representation
func (l *Level) FromString(level string) Level {
switch level {
case "debug":
*l = LevelDebug
case "info":
*l = LevelInfo
case "notice":
*l = LevelNotice
case "warning":
*l = LevelWarning
case "error":
*l = LevelError
case "critical":
*l = LevelCritical
case "alert":
*l = LevelAlert
case "emergency":
*l = LevelEmergency
}
return *l
}
const (
// Debug: debug-level messages
LevelDebug Level = 7
// Informational: informational messages
LevelInfo Level = 6
// Notice: normal but significant condition
LevelNotice Level = 5
// Warning: warning conditions
LevelWarning Level = 4
// Error: error conditions
LevelError Level = 3
// Critical: critical conditions
LevelCritical Level = 2
// Alert: action must be taken immediately
LevelAlert Level = 1
// Emergency: system is unusable
LevelEmergency Level = 0
)
type opts struct {
args []interface{}
fields Fields
}
// Option is func hook for underling logic call
type Option func(*opts) error
// Args returns func hook a logger for replace fmt placeholders on represent values
func Args(a ...interface{}) Option {
return func(f *opts) error {
f.args = a
return nil
}
}
// WithFields returns func hook a logger for adding fields for call
func WithFields(fields Fields) Option {
return func(f *opts) error {
f.fields = fields
return nil
}
}
// Config is a general logger config settings
type Config struct {
Debug bool
}
// Logger is the interface for logger client
type Logger interface {
// Printf is like fmt.Printf, push to log entry with debug level
Printf(format string, a ...interface{})
// Emergency push to log entry with emergency level & throw panic
Emergency(format string, opts ...Option)
// Alert push to log entry with alert level
Alert(format string, opts ...Option)
// Critical push to log entry with critical level
Critical(format string, opts ...Option)
// Error push to log entry with error level
Error(format string, opts ...Option)
// Warning push to log entry with warning level
Warning(format string, opts ...Option)
// Notice push to log entry with notice level
Notice(format string, opts ...Option)
// Info push to log entry with info level
Info(format string, opts ...Option)
// Debug push to log entry with debug level
Debug(format string, opts ...Option)
// Write push to log entry with debug level
Write(p []byte) (n int, err error)
// Log push to log with specified level
Log(level Level, format string, opts ...Option)
// WithFields create new instance with fields
WithFields(fields Fields) Logger
}
================================================
FILE: app/logger/middleware.go
================================================
package logger
import (
"context"
"strings"
"time"
"google.golang.org/grpc"
)
// UnaryClientInterceptor wrapper to logging query
func UnaryClientInterceptor(log Logger, enable bool) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
if !enable {
return invoker(ctx, method, req, reply, cc, opts...)
}
startTime := time.Now()
err := invoker(ctx, method, req, reply, cc, opts...)
var e string
if err != nil {
e = strings.ReplaceAll(err.Error(), "\n", "")
}
log.Debug("\nQUERY UnaryClient:\n\nData: %v\n\nERROR:\n%v\n\n", Args(req, e), WithFields(Fields{
"time": time.Since(startTime).String(),
}))
return err
}
}
// StreamClientInterceptor returns a new streaming client interceptor
func StreamClientInterceptor(log Logger, enable bool) grpc.StreamClientInterceptor {
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
if !enable {
return streamer(ctx, desc, cc, method, opts...)
}
startTime := time.Now()
clientStream, err := streamer(ctx, desc, cc, method, opts...)
var e string
if err != nil {
e = strings.ReplaceAll(err.Error(), "\n", "")
}
log.Debug("\nQUERY StreamClient:\n\nMethod: %v\n\nERROR:\n%v\n\n", Args(method, e), WithFields(Fields{
"time": time.Since(startTime).String(),
}))
return clientStream, err
}
}
// UnaryServerInterceptor wrapper to logging query
func UnaryServerInterceptor(log Logger, enable bool) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
if !enable {
return handler(ctx, req)
}
startTime := time.Now()
res, err := handler(ctx, req)
var e string
if err != nil {
e = strings.ReplaceAll(err.Error(), "\n", "")
}
log.Debug("\nQUERY UnaryServer:\n\nFullMethod: %v\nData: %v\nRESPONSE:\n\nData: %v\nERROR:\n%v\n", Args(info.FullMethod, req, res, e), WithFields(Fields{
"time": time.Since(startTime).String(),
}))
return res, err
}
}
// StreamServerInterceptor returns a new streaming server interceptor
func StreamServerInterceptor(log Logger, enable bool) grpc.StreamServerInterceptor {
return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
if !enable {
return handler(srv, stream)
}
startTime := time.Now()
err := handler(srv, stream)
var e string
if err != nil {
e = strings.ReplaceAll(err.Error(), "\n", "")
}
log.Debug("\nQUERY StreamServer:\n\nFullMethod: %v\n\nERROR:\n%v\n", Args(info.FullMethod, e), WithFields(Fields{
"time": time.Since(startTime).String(),
}))
return err
}
}
================================================
FILE: app/logger/mock.go
================================================
package logger
import (
"context"
)
// Entity represent log struct with all assets
type Entity struct {
Level Level
Fields Fields
Args []interface{}
Format string
}
// Mock is the logger with stubbed methods
type Mock struct {
ctx context.Context
ch chan Entity
discard bool
cfg Config
fields map[string]interface{}
}
// Printf is like fmt.Printf, push to log entry with debug level
func (m *Mock) Printf(format string, a ...interface{}) {
m.Debug(format, Args(a...))
}
// Emergency push to log entry with emergency level & throw panic
func (m *Mock) Emergency(format string, opts ...Option) {
m.Log(LevelEmergency, format, opts...)
}
// Alert push to log entry with alert level
func (m *Mock) Alert(format string, opts ...Option) {
m.Log(LevelAlert, format, opts...)
}
// Critical push to log entry with critical level
func (m *Mock) Critical(format string, opts ...Option) {
m.Log(LevelCritical, format, opts...)
}
// Error push to log entry with error level
func (m *Mock) Error(format string, opts ...Option) {
m.Log(LevelError, format, opts...)
}
// Warning push to log entry with warning level
func (m *Mock) Warning(format string, opts ...Option) {
m.Log(LevelWarning, format, opts...)
}
// Notice push to log entry with notice level
func (m *Mock) Notice(format string, opts ...Option) {
m.Log(LevelNotice, format, opts...)
}
// Info push to log entry with info level
func (m *Mock) Info(format string, opts ...Option) {
m.Log(LevelInfo, format, opts...)
}
// Debug push to log entry with debug level
func (m *Mock) Debug(format string, opts ...Option) {
m.Log(LevelDebug, format, opts...)
}
// Write push to log entry with debug level
func (m *Mock) Write(p []byte) (n int, err error) {
m.Debug(string(p))
return len(p), nil
}
// Log push to log with specified level
func (m *Mock) Log(level Level, format string, o ...Option) {
if !m.discard {
return
}
opts := &opts{}
for _, option := range o {
_ = option(opts)
}
var (
fields = map[string]interface{}{}
)
// fields
for k, v := range m.fields {
fields[k] = v
}
for k, v := range opts.fields {
fields[k] = v
}
go func() {
m.ch <- Entity{
Level: level,
Format: format,
Args: opts.args,
Fields: fields,
}
}()
}
// WithFields create new instance with fields
func (m *Mock) WithFields(fields Fields) Logger {
nm := &Mock{}
copyMock(nm, m, fields)
return nm
}
func copyMock(dst, src *Mock, fields map[string]interface{}) {
var cFields = map[string]interface{}{}
// fields
for k, v := range src.fields {
cFields[k] = v
}
dst.fields = cFields
if fields != nil {
for k, v := range fields {
dst.fields[k] = v
}
}
dst.discard = src.discard
dst.ch = src.ch
}
// Catch returns channel of entity structure for testing event content
func (m *Mock) Catch() <-chan Entity {
return m.ch
}
// NewMock returns mock instance implemented of Logger interface
func newMock(ctx context.Context, cfg Config, discard bool) *Mock {
return &Mock{
ctx: ctx,
cfg: cfg,
ch: make(chan Entity),
discard: discard,
}
}
================================================
FILE: app/logger/provider.go
================================================
package logger
import (
"context"
"github.com/google/wire"
"github.com/spf13/viper"
)
// ProviderCfg returns configuration for production logger
func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
c := Config{}
e := cfg.UnmarshalKey("logger", &c)
if e != nil {
return c, func() {}, e
}
if cfg.IsSet("debug") && !c.Debug {
c.Debug = cfg.GetBool("debug")
}
return c, func() {}, nil
}
// ProviderCfgTest returns configuration for stub/mock logger
func ProviderCfgTest() (Config, func(), error) {
return Config{}, func() {}, nil
}
// Provider returns logger instance implemented of Logger interface with resolved dependencies
func Provider(ctx context.Context, cfg Config) (*Zap, func(), error) {
return newZap(ctx, cfg), func() {}, nil
}
// ProviderTest returns stub/mock logger instance implemented of Logger interface with resolved dependencies
func ProviderTest(ctx context.Context, cfg Config) (*Mock, func(), error) {
mock := newMock(ctx, cfg, true)
cleanup := func() {
if mock.ch != nil {
close(mock.ch)
}
}
return mock, cleanup, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, ProviderCfg, wire.Bind(new(Logger), new(*Zap)))
ProviderTestSet = wire.NewSet(ProviderTest, ProviderCfgTest, wire.Bind(new(Logger), new(*Mock)))
)
================================================
FILE: app/logger/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package logger
import (
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/entrypoint"
)
// Injectors from injector.go:
// Build returns logger instance implemented of Logger interface with resolved dependencies
func Build() (Logger, func(), error) {
context, cleanup, err := entrypoint.ContextProvider()
if err != nil {
return nil, nil, err
}
viper, cleanup2, err := config.Provider()
if err != nil {
cleanup()
return nil, nil, err
}
loggerConfig, cleanup3, err := ProviderCfg(viper)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
zap, cleanup4, err := Provider(context, loggerConfig)
if err != nil {
cleanup3()
cleanup2()
cleanup()
return nil, nil, err
}
return zap, func() {
cleanup4()
cleanup3()
cleanup2()
cleanup()
}, nil
}
func BuildTest() (Logger, func(), error) {
context, cleanup, err := entrypoint.ContextProviderTest()
if err != nil {
return nil, nil, err
}
loggerConfig, cleanup2, err := ProviderCfgTest()
if err != nil {
cleanup()
return nil, nil, err
}
mock, cleanup3, err := ProviderTest(context, loggerConfig)
if err != nil {
cleanup2()
cleanup()
return nil, nil, err
}
return mock, func() {
cleanup3()
cleanup2()
cleanup()
}, nil
}
================================================
FILE: app/logger/zap.go
================================================
package logger
import (
"context"
"go.uber.org/zap/zapcore"
"go.uber.org/zap"
)
// Zap is uber/zap logger implemented of Logger interface
type Zap struct {
ctx context.Context
cfg Config
logger *zap.SugaredLogger
fields map[string]interface{}
}
// Printf is like fmt.Printf, push to log entry with debug level
func (z *Zap) Printf(format string, a ...interface{}) {
z.Debug(format, Args(a...))
}
// Emergency push to log entry with emergency level & throw panic
func (z *Zap) Emergency(format string, opts ...Option) {
z.Log(LevelEmergency, format, opts...)
}
// Alert push to log entry with alert level
func (z *Zap) Alert(format string, opts ...Option) {
z.Log(LevelAlert, format, opts...)
}
// Critical push to log entry with critical level
func (z *Zap) Critical(format string, opts ...Option) {
z.Log(LevelCritical, format, opts...)
}
// Error push to log entry with error level
func (z *Zap) Error(format string, opts ...Option) {
z.Log(LevelError, format, opts...)
}
// Warning push to log entry with warning level
func (z *Zap) Warning(format string, opts ...Option) {
z.Log(LevelWarning, format, opts...)
}
// Notice push to log entry with notice level
func (z *Zap) Notice(format string, opts ...Option) {
z.Log(LevelNotice, format, opts...)
}
// Info push to log entry with info level
func (z *Zap) Info(format string, opts ...Option) {
z.Log(LevelInfo, format, opts...)
}
// Debug push to log entry with debug level
func (z *Zap) Debug(format string, opts ...Option) {
z.Log(LevelDebug, format, opts...)
}
// Write push to log entry with debug level
func (z *Zap) Write(p []byte) (n int, err error) {
z.Debug(string(p))
return len(p), nil
}
// Log push to log with specified level
func (z *Zap) Log(level Level, format string, o ...Option) {
opts := &opts{}
for _, option := range o {
_ = option(opts)
}
var (
wargs = []interface{}{"level", level.String()}
)
// fields
for k, v := range z.fields {
wargs = append(wargs, k, v)
}
for k, v := range opts.fields {
wargs = append(wargs, k, v)
}
var logger = z.logger
if len(wargs) > 0 {
logger = logger.With(wargs...)
}
if len(opts.args) == 0 {
var fn func(args ...interface{})
switch level {
default:
fn = logger.Debug
case LevelInfo, LevelNotice:
fn = logger.Info
case LevelWarning:
fn = logger.Warn
case LevelError, LevelCritical, LevelAlert:
fn = logger.Error
case LevelEmergency:
fn = logger.Panic
}
fn(format)
} else {
var fn func(format string, args ...interface{})
switch level {
default:
fn = logger.Debugf
case LevelInfo, LevelNotice:
fn = logger.Infof
case LevelWarning:
fn = logger.Warnf
case LevelError, LevelCritical, LevelAlert:
fn = logger.Errorf
case LevelEmergency:
fn = logger.Panicf
}
fn(format, opts.args...)
}
}
// WithFields create new instance with fields
func (z *Zap) WithFields(fields Fields) Logger {
nz := &Zap{}
copyZap(nz, z, fields)
return nz
}
func copyZap(dst, src *Zap, fields map[string]interface{}) {
var cFields = map[string]interface{}{}
// fields
for k, v := range src.fields {
cFields[k] = v
}
dst.fields = cFields
if fields != nil {
for k, v := range fields {
dst.fields[k] = v
}
}
dst.logger = src.logger
}
// NewZap returns zap logger
func newZap(ctx context.Context, cfg Config) *Zap {
var logger *zap.Logger
if !cfg.Debug {
cfg := zap.NewProductionConfig()
logger, _ = cfg.Build(zap.AddCallerSkip(3), zap.AddStacktrace(zap.WarnLevel))
} else {
cfg := zap.NewDevelopmentConfig()
cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
logger, _ = cfg.Build(zap.AddCallerSkip(3), zap.AddStacktrace(zap.WarnLevel))
}
go func(logger *zap.Logger) {
<-ctx.Done()
_ = logger.Sync()
}(logger)
return &Zap{ctx: ctx, cfg: cfg, logger: logger.Sugar()}
}
================================================
FILE: app/provider/provider.go
================================================
package provider
import (
"github.com/aristat/golang-example-app/app/casbin"
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/grpc"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/app/tracing"
"github.com/google/wire"
)
var AwareProductionSet = wire.NewSet(
entrypoint.ProviderProductionSet,
logger.ProviderProductionSet,
config.ProviderSet,
tracing.ProviderProductionSet,
grpc.ProviderProductionSet,
casbin.ProviderProductionSet,
)
var AwareTestSet = wire.NewSet(
entrypoint.ProviderTestSet,
logger.ProviderTestSet,
tracing.ProviderTestSet,
grpc.ProviderTestSet,
casbin.ProviderTestSet,
)
================================================
FILE: app/tracing/jaeger.go
================================================
package tracing
import (
"context"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"github.com/aristat/golang-example-app/app/logger"
"github.com/pkg/errors"
)
type Configuration struct {
AgentHost string
AgentPort string
ServiceName string
}
const prefix = "app.tracer"
func newJaegerTracer(ctx context.Context, configuration *Configuration, log logger.Logger) (*tracesdk.TracerProvider, error) {
log = log.WithFields(logger.Fields{"service": prefix})
exp, err := jaeger.New(
jaeger.WithAgentEndpoint(
jaeger.WithAgentHost(configuration.AgentHost),
jaeger.WithAgentPort(configuration.AgentPort),
),
)
if err != nil {
return nil, errors.WithMessage(err, prefix)
}
tracer := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(configuration.ServiceName),
)),
)
go func() {
<-ctx.Done()
if err := tracer.Shutdown(ctx); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
}
}()
return tracer, errors.WithMessage(err, prefix)
}
================================================
FILE: app/tracing/provider.go
================================================
package tracing
import (
"context"
"go.opentelemetry.io/otel/propagation"
"github.com/google/wire"
"github.com/spf13/viper"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel"
"github.com/aristat/golang-example-app/app/logger"
)
// Cfg
func Cfg(cfg *viper.Viper) (*Configuration, func(), error) {
c := Configuration{}
e := cfg.UnmarshalKey("tracing.jaeger", &c)
if e != nil {
return nil, func() {}, e
}
return &c, func() {}, nil
}
// Provider
func Provider(ctx context.Context, configuration *Configuration, log logger.Logger) (*tracesdk.TracerProvider, func(), error) {
t, e := newJaegerTracer(ctx, configuration, log)
otel.SetTracerProvider(t)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
return t, func() {}, e
}
// ProviderTest
func ProviderTest() (*tracesdk.TracerProvider, func(), error) {
m := tracesdk.NewTracerProvider()
return m, func() {}, nil
}
var (
ProviderProductionSet = wire.NewSet(Provider, Cfg)
ProviderTestSet = wire.NewSet(ProviderTest)
)
================================================
FILE: cmd/daemon/daemon.go
================================================
package daemon
import (
"context"
"os"
"os/signal"
"sync"
"syscall"
"time"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/http"
"github.com/aristat/golang-example-app/app/logger"
"github.com/spf13/cobra"
)
var (
bind string
gracefulDelay time.Duration
Cmd = &cobra.Command{
Use: "daemon",
Short: "Gateway API daemon",
SilenceUsage: true,
SilenceErrors: true,
Run: func(_ *cobra.Command, _ []string) {
var (
e error
s *http.Http
c func()
)
log, c, e := logger.Build()
if e != nil {
panic(e)
}
defer c()
defer func() {
if r := recover(); r != nil {
if re, _ := r.(error); re != nil {
log.Error(re.Error())
} else {
log.Alert("unhandled panic, err: %v", logger.Args(r))
}
}
}()
s, c, e = http.Build()
if e != nil {
log.Error(e.Error())
return
}
defer c()
wg := &sync.WaitGroup{}
wg.Add(1)
server := s.ListenAndServe(wg, bind)
shutdownSignal := make(chan os.Signal)
signal.Notify(shutdownSignal, syscall.SIGTERM, syscall.SIGINT)
sig := <-shutdownSignal
log.Printf("OS signaled `%v`\n", sig.String())
log.Info("Server shutdown is raised")
if e := server.Shutdown(context.Background()); e != nil {
log.Emergency("Graceful shutdown error, %v", logger.Args(e))
}
wg.Wait()
log.Printf("Graceful shutdown in %s\n", gracefulDelay)
ctx, _ := context.WithTimeout(context.Background(), gracefulDelay)
entrypoint.Shutdown(ctx, 0)
},
}
)
func init() {
Cmd.PersistentFlags().StringVarP(&bind, "bind", "b", ":9096", "bind address")
Cmd.PersistentFlags().DurationVar(&gracefulDelay, "graceful.delay", 50*time.Millisecond, "graceful delay")
}
================================================
FILE: cmd/health-check-service/health_check_service.go
================================================
package health_check_service
import (
"context"
"log"
"math/rand"
"net"
"time"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel"
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/app/common"
"github.com/aristat/golang-example-app/generated/resources/proto/health_checks"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
emptypb "google.golang.org/protobuf/types/known/emptypb"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)
// Config
type Config struct {
Port string
RandomDisable bool
}
type server struct {
cfg Config
health_checks.UnimplementedHealthChecksServer
}
func (s *server) IsAlive(ctx context.Context, empty *emptypb.Empty) (*health_checks.IsAliveOut, error) {
if s.cfg.RandomDisable {
return &health_checks.IsAliveOut{Status: health_checks.IsAliveOut_OK}, nil
}
var status health_checks.IsAliveOut_Status
rand.Seed(time.Now().UTC().UnixNano())
number := rand.Intn(2-0) + 0
if number == 1 {
status = health_checks.IsAliveOut_OK
} else {
status = health_checks.IsAliveOut_NOT_OK
}
return &health_checks.IsAliveOut{Status: status}, nil
}
// Example service, which need for testing jaeger and grpc pool
var (
//bind string
Cmd = &cobra.Command{
Use: "health-check",
Short: "Health check",
SilenceUsage: true,
SilenceErrors: true,
Run: func(_ *cobra.Command, _ []string) {
conf, c, e := config.Build()
if e != nil {
panic(e)
}
defer c()
clientConfig := Config{}
e = conf.UnmarshalKey("services.healthCheckService", &clientConfig)
if e != nil {
log.Fatal("Config initialize error")
}
log, c, e := logger.Build()
if e != nil {
panic(e)
}
defer c()
defer func() {
if r := recover(); r != nil {
if re, _ := r.(error); re != nil {
log.Error(re.Error())
} else {
log.Alert("unhandled panic, err: %v", logger.Args(r))
}
}
}()
tracer, e := common.GenerateTracerForTestClient("golang-example-app-health-check-service", conf)
otel.SetTracerProvider(tracer)
if e != nil {
panic(e)
}
defer func() {
if err := tracer.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
}
}()
lis, err := net.Listen("tcp", ":"+clientConfig.Port)
if err != nil {
panic(err)
}
s := grpc.NewServer(
grpc.ChainUnaryInterceptor(
logger.UnaryServerInterceptor(log, true),
otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
grpc.ChainStreamInterceptor(
logger.StreamServerInterceptor(log, true),
otelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
)
health_checks.RegisterHealthChecksServer(s, &server{cfg: clientConfig})
if err := s.Serve(lis); err != nil {
panic(err)
}
},
}
)
func init() {
}
================================================
FILE: cmd/jwt/jwt.go
================================================
package jwt
import "github.com/spf13/cobra"
var Cmd = &cobra.Command{
Use: "jwt",
Short: "Tools for generate JWT",
SilenceUsage: true,
SilenceErrors: true,
}
func init() {
Cmd.AddCommand(tokenCmd)
}
================================================
FILE: cmd/jwt/token.go
================================================
package jwt
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"time"
"github.com/spf13/cast"
"github.com/golang-jwt/jwt"
"github.com/spf13/cobra"
)
var (
jwtFlagPrivateKey string
jwtFlagFields string
)
func init() {
tokenCmd.PersistentFlags().StringVar(&jwtFlagPrivateKey, "key", "", "private key")
tokenCmd.PersistentFlags().StringVar(&jwtFlagFields, "fields", "", "JWT fields in JSON format")
}
var tokenCmd = &cobra.Command{
Use: "token",
Short: "Generate JWT token with sign",
Example: `jwt --key='{path to private key}' --fields='{in json format {"key":"value"} }'`,
SilenceUsage: true,
SilenceErrors: true,
Run: func(cmd *cobra.Command, args []string) {
if jwtFlagPrivateKey == "" {
fmt.Printf("Flag `key` is required\n")
os.Exit(1)
}
privatePemKey, err := ioutil.ReadFile(jwtFlagPrivateKey)
if err != nil {
fmt.Printf("Error occurred: %v\n", err.Error())
os.Exit(1)
}
fields := make(map[string]interface{})
if jwtFlagFields != "" {
if err = json.Unmarshal([]byte(jwtFlagFields), &fields); err != nil {
fmt.Printf("Parse fields error %v\n", err.Error())
os.Exit(1)
}
}
jwtEncoded, err := GenerateJWT(privatePemKey, fields)
if err != nil {
fmt.Printf("Error occurred: %v\n", err.Error())
os.Exit(1)
}
fmt.Println(jwtEncoded)
},
}
// GenerateJWT returns token signed by private key with filled fields
func GenerateJWT(privateKey []byte, fields map[string]interface{}) (string, error) {
type CustomClaims struct {
UserId int64 `json:"user_id,omitempty"`
jwt.StandardClaims
}
claims := &CustomClaims{}
for k, v := range fields {
switch k {
case "aud":
claims.Audience = cast.ToString(v)
case "sub":
claims.Subject = cast.ToString(v)
case "iss":
claims.Issuer = cast.ToString(v)
case "id":
claims.Id = cast.ToString(v)
case "exp":
claims.ExpiresAt = cast.ToInt64(v)
case "user_id":
claims.UserId = cast.ToInt64(v)
case "nbf":
claims.NotBefore = cast.ToInt64(v)
case "iat":
claims.IssuedAt = time.Now().Unix()
}
}
var (
sPrivateKey interface{}
err error
)
sPrivateKey, err = jwt.ParseRSAPrivateKeyFromPEM(privateKey)
if err != nil {
return "", err
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
ss, err := token.SignedString(sPrivateKey)
if err != nil {
return "", err
}
return ss, nil
}
================================================
FILE: cmd/migrate/migrate.go
================================================
package migrate
import (
"database/sql"
"fmt"
"os"
"github.com/aristat/golang-example-app/app/entrypoint"
_ "github.com/lib/pq"
migrate "github.com/rubenv/sql-migrate"
"github.com/spf13/cobra"
)
var (
argDsn, argTable string
argLimit int
db *sql.DB
ms *migrate.FileMigrationSource
initCmdFn = func(cmd *cobra.Command, _ []string) (re error) {
var e error
defer func() {
recover()
re = e
}()
ms = &migrate.FileMigrationSource{
Dir: entrypoint.WorkDir() + "/migrations",
}
migrate.SetTable(argTable)
db, e = sql.Open("postgres", argDsn)
if e != nil {
return e
}
return nil
}
cmdUp = &cobra.Command{
Use: "up",
Short: "Migrates the database to the most recent version available",
SilenceUsage: true,
SilenceErrors: true,
Run: func(_ *cobra.Command, _ []string) {
if e := initCmdFn(nil, nil); e != nil {
fmt.Printf("Failed: %v\n", e.Error())
os.Exit(1)
}
n, err := migrate.ExecMax(db, "postgres", ms, migrate.Up, argLimit)
if err != nil {
fmt.Printf("Failed: %v\n", err.Error())
os.Exit(1)
}
fmt.Printf("Applied %d migrations!\n", n)
},
}
cmdDown = &cobra.Command{
Use: "down",
Short: "Rollback a database migration",
SilenceUsage: true,
SilenceErrors: true,
Run: func(_ *cobra.Command, _ []string) {
if e := initCmdFn(nil, nil); e != nil {
fmt.Printf("Failed: %v\n", e.Error())
os.Exit(1)
}
n, err := migrate.ExecMax(db, "postgres", ms, migrate.Down, argLimit)
if err != nil {
fmt.Printf("Failed: %v\n", err.Error())
os.Exit(1)
}
fmt.Printf("Applied %d migrations!\n", n)
},
}
Cmd = &cobra.Command{
Use: "migrate",
Short: "SQL migration tool",
SilenceUsage: true,
SilenceErrors: true,
}
)
func init() {
Cmd.PersistentFlags().StringVar(&argTable, "table", "migrations", "Table for migration history")
Cmd.PersistentFlags().IntVar(&argLimit, "limit", 1, "Limit the number of migrations (0 = unlimited)")
Cmd.PersistentFlags().StringVar(&argDsn, "dsn", "postgres://localhost:5432/golang_example_development?sslmode=disable", "DSN connection string")
Cmd.AddCommand(cmdUp, cmdDown)
}
================================================
FILE: cmd/product-service/nats_service.go
================================================
package product_service
import (
"github.com/aristat/golang-example-app/app/logger"
"github.com/nats-io/stan.go"
)
type natsService struct {
logger logger.Logger
}
func (s *natsService) workerHanlder(m *stan.Msg) {
s.logger.Info("[NATS] Received a message: %s\n", logger.Args(string(m.Data)))
m.Ack()
}
================================================
FILE: cmd/product-service/product_service.go
================================================
package product_service
import (
"context"
"errors"
"log"
"net"
"time"
"go.opentelemetry.io/otel/propagation"
"google.golang.org/grpc/credentials/insecure"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"github.com/nats-io/nats.go"
"github.com/nats-io/stan.go"
"github.com/aristat/golang-example-app/app/config"
"github.com/aristat/golang-example-app/app/common"
"github.com/aristat/golang-example-app/app/logger"
"github.com/aristat/golang-example-app/generated/resources/proto/health_checks"
"github.com/aristat/golang-example-app/generated/resources/proto/products"
emptypb "google.golang.org/protobuf/types/known/emptypb"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)
// Config
type Config struct {
Port string
HealthCheckUrl string
NatsURL string
Subject string
}
type server struct {
logger logger.Logger
cfg Config
products.UnimplementedProductsServer
}
func (s *server) ListProduct(ctx context.Context, in *products.ListProductIn) (*products.ListProductOut, error) {
tracer := otel.GetTracerProvider()
conn, err := grpc.Dial(s.cfg.HealthCheckUrl,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithChainUnaryInterceptor(
logger.UnaryClientInterceptor(s.logger, true),
otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
grpc.WithChainStreamInterceptor(
logger.StreamClientInterceptor(s.logger, true),
otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
)
if err != nil {
return nil, err
}
defer conn.Close()
c := health_checks.NewHealthChecksClient(conn)
ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
isAliveOut, err := c.IsAlive(ctx, &emptypb.Empty{})
if err != nil {
return nil, err
}
if isAliveOut.Status != health_checks.IsAliveOut_OK {
return nil, errors.New("Heal checks not working")
}
// test result
out := &products.ListProductOut{Status: products.ListProductOut_OK, Products: []*products.Product{}}
out.Products = append(out.Products, &products.Product{Id: 1, Name: "first_product"})
out.Products = append(out.Products, &products.Product{Id: 2, Name: "second_product"})
return out, nil
}
// Example service, which gives some data
var (
//bind string
Cmd = &cobra.Command{
Use: "product-service",
Short: "Product service",
SilenceUsage: true,
SilenceErrors: true,
Run: func(_ *cobra.Command, _ []string) {
conf, c, e := config.Build()
if e != nil {
panic(e)
}
defer c()
clientConfig := Config{}
e = conf.UnmarshalKey("services.productService", &clientConfig)
if e != nil {
log.Fatal("Config initialize error")
}
log, c, e := logger.Build()
if e != nil {
panic(e)
}
defer c()
defer func() {
if r := recover(); r != nil {
if re, _ := r.(error); re != nil {
log.Error(re.Error())
} else {
log.Alert("unhandled panic, err: %v", logger.Args(r))
}
}
}()
tracer, e := common.GenerateTracerForTestClient("golang-example-app-product-service", conf)
otel.SetTracerProvider(tracer)
if e != nil {
panic(e)
}
defer func() {
if err := tracer.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
}
}()
log.Info("Start product service %s", logger.Args(clientConfig.Port))
lis, err := net.Listen("tcp", ":"+clientConfig.Port)
if err != nil {
panic(err)
}
nc, err := nats.Connect(clientConfig.NatsURL)
if err != nil {
log.Error(err.Error())
panic(err)
}
defer nc.Close()
sc, _ := stan.Connect("test-cluster", "example-subscriber", stan.NatsConn(nc))
natsService := natsService{logger: log}
_, err = sc.QueueSubscribe(clientConfig.Subject, "worker", natsService.workerHanlder, stan.DurableName("i-will-remember"), stan.MaxInflight(1), stan.SetManualAckMode())
if err != nil {
sc.Close()
log.Error(err.Error())
panic(err)
}
s := grpc.NewServer(
grpc.ChainUnaryInterceptor(
logger.UnaryServerInterceptor(log, true),
otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
grpc.ChainStreamInterceptor(
logger.StreamServerInterceptor(log, true),
otelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
),
)
products.RegisterProductsServer(s, &server{logger: log, cfg: clientConfig})
if err := s.Serve(lis); err != nil {
panic(err)
}
},
}
)
func init() {
}
================================================
FILE: cmd/root.go
================================================
package cmd
import (
"bytes"
"encoding/json"
"fmt"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"github.com/aristat/golang-example-app/cmd/jwt"
"github.com/aristat/golang-example-app/cmd/migrate"
health_check_service "github.com/aristat/golang-example-app/cmd/health-check-service"
product_service "github.com/aristat/golang-example-app/cmd/product-service"
"github.com/aristat/golang-example-app/app/entrypoint"
"github.com/aristat/golang-example-app/app/logger"
"go.uber.org/automaxprocs/maxprocs"
"github.com/aristat/golang-example-app/cmd/daemon"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
configPath string
debug bool
v *viper.Viper
log logger.Logger
)
const prefix = "cmd.root"
// Root command
var rootCmd = &cobra.Command{
Use: "bin [command]",
Long: "",
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
l, c, e := logger.Build()
defer c()
if e != nil {
panic(e)
}
log = l.WithFields(logger.Fields{"service": prefix})
v.SetConfigFile(configPath)
if configPath != "" {
e := v.ReadInConfig()
if e != nil {
log.Error("can't read config, %v", logger.Args(errors.WithMessage(e, prefix)))
os.Exit(1)
}
}
if debug {
b, _ := json.Marshal(v.AllSettings())
var out bytes.Buffer
e := json.Indent(&out, b, "", " ")
if e != nil {
log.Error("can't prettify config")
os.Exit(1)
}
fmt.Println(string(out.Bytes()))
}
_, _ = maxprocs.Set(maxprocs.Logger(log.Printf))
},
}
func init() {
v = viper.New()
v.SetConfigType("yaml")
v.SetEnvPrefix("APP")
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
v.AutomaticEnv()
// pflags
rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "config file")
rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "debug mode")
// initializing
wd := os.Getenv("APP_WD")
if len(wd) == 0 {
wd, _ = filepath.Abs(filepath.Dir(os.Args[0]))
}
wd, _ = filepath.Abs(wd)
ep, _ := entrypoint.Initialize(wd, v)
// bin pflags to viper
_ = v.BindPFlags(rootCmd.PersistentFlags())
go func() {
reloadSignal := make(chan os.Signal)
signal.Notify(reloadSignal, syscall.SIGHUP)
for {
sig := <-reloadSignal
ep.Reload()
fmt.Printf("OS signaled `%v`, reload", sig.String())
}
}()
}
func Execute() {
rootCmd.AddCommand(daemon.Cmd, product_service.Cmd, health_check_service.Cmd, migrate.Cmd, jwt.Cmd)
if e := rootCmd.Execute(); e != nil {
_, _ = fmt.Fprintf(os.Stderr, "%v\n", e.Error())
os.Exit(1)
}
}
================================================
FILE: dbconfig.yml
================================================
development:
dialect: postgres
datasource: dbname=golang_example_development sslmode=disable
dir: resources/migrations
table: migrations
================================================
FILE: docker/app/Dockerfile
================================================
FROM golang:1.17.9-alpine3.15 as builder
RUN apk add --update make \
&& rm -rf /tmp/* \
&& rm -rf /var/cache/apk/*
RUN mkdir /build
WORKDIR /build
COPY . .
RUN GOOS=linux GOARCH=amd64 make build
FROM alpine:3.9
COPY --from=builder /build/docker/app/files /
COPY --from=builder /build/artifacts /app/
WORKDIR /app
RUN apk --no-cache add tzdata bash \
&& chmod +x /docker/bin/* \
&& chmod +x bin \
&& rm -rf /tmp/* \
&& rm -rf /var/cache/apk/*
ENTRYPOINT ["/docker/bin/entrypoint.sh"]
================================================
FILE: docker/app/files/docker/bin/entrypoint.sh
================================================
#!/usr/bin/env sh
exec ./bin "$@"
================================================
FILE: docker-compose.yml
================================================
version: '3.7'
services:
jaeger:
image: jaegertracing/all-in-one:latest
networks:
- intranet
ports:
- "5775:5775/udp"
- "6831:6831/udp"
- "6832:6832/udp"
- "5778:5778"
- "16686:16686"
- "14268:14268"
- "9411:9411"
#=============================#
# check migration before start
daemon-migrate:
image: golang-example-app:development
depends_on:
- postgres
networks:
- intranet
command:
migrate up --dsn=postgres://postgres@postgres:5432/golang_example_development?sslmode=disable --limit=0
daemon:
image: golang-example-app:development
command: daemon -c ./configs/docker_development.yaml -d
depends_on:
- product_service
- health_check_service
- daemon-migrate
- postgres
- redis
- nats-streaming
networks:
- intranet
ports:
- "9096:9096"
#=============================#
product_service:
image: golang-example-app:development
command: product-service -c ./configs/docker_development.yaml -d
depends_on:
- postgres
networks:
- intranet
ports:
- "50051:50051"
#=============================#
health_check_service:
image: golang-example-app:development
command: health-check -c ./configs/docker_development.yaml -d
networks:
- intranet
ports:
- "50052:50052"
#=============================#
postgres:
image: postgres:9.6
environment:
- POSTGRES_USER=postgres
- POSTGRES_DB=golang_example_development
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5532:5432"
networks:
- intranet
redis:
image: redis:latest
volumes:
- redis_data:/data
networks:
- intranet
nats-streaming:
image: nats-streaming
ports:
- "8222:8222"
- "4222:4222"
networks:
- intranet
networks:
intranet:
driver: bridge
volumes:
postgres_data:
redis_data:
================================================
FILE: generated/graphql/generated.go
================================================
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package graphql
import (
"bytes"
"context"
"errors"
"fmt"
"strconv"
"sync"
"sync/atomic"
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection"
"github.com/aristat/golang-example-app/app/db/domain"
gqlparser "github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
)
// region ************************** generated!.gotpl **************************
// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
return &executableSchema{
resolvers: cfg.Resolvers,
directives: cfg.Directives,
complexity: cfg.Complexity,
}
}
type Config struct {
Resolvers ResolverRoot
Directives DirectiveRoot
Complexity ComplexityRoot
}
type ResolverRoot interface {
Mutation() MutationResolver
Product() ProductResolver
ProductsQuery() ProductsQueryResolver
Query() QueryResolver
UsersMutation() UsersMutationResolver
UsersQuery() UsersQueryResolver
}
type DirectiveRoot struct {
HasUsersPermission func(ctx context.Context, obj interface{}, next graphql.Resolver, permission UsersPermissionEnum) (res interface{}, err error)
}
type ComplexityRoot struct {
Mutation struct {
Users func(childComplexity int) int
}
Product struct {
ID func(childComplexity int) int
Name func(childComplexity int) int
ProductItems func(childComplexity int) int
}
ProductItem struct {
ID func(childComplexity int) int
Name func(childComplexity int) int
}
ProductsListOut struct {
Products func(childComplexity int) int
}
ProductsQuery struct {
List func(childComplexity int) int
}
Query struct {
Products func(childComplexity int) int
Users func(childComplexity int) int
}
UsersCreateOut struct {
Email func(childComplexity int) int
ID func(childComplexity int) int
Status func(childComplexity int) int
}
UsersMutation struct {
CreateUser func(childComplexity int, email string, password string) int
}
UsersOneOut struct {
Email func(childComplexity int) int
ID func(childComplexity int) int
}
UsersQuery struct {
One func(childComplexity int, email string) int
}
}
type MutationResolver interface {
Users(ctx context.Context) (*UsersMutation, error)
}
type ProductResolver interface {
ProductItems(ctx context.Context, obj *domain.Product) ([]*domain.ProductItem, error)
}
type ProductsQueryResolver interface {
List(ctx context.Context, obj *ProductsQuery) (*ProductsListOut, error)
}
type QueryResolver interface {
Users(ctx context.Context) (*UsersQuery, error)
Products(ctx context.Context) (*ProductsQuery, error)
}
type UsersMutationResolver interface {
CreateUser(ctx context.Context, obj *UsersMutation, email string, password string) (*UsersCreateOut, error)
}
type UsersQueryResolver interface {
One(ctx context.Context, obj *UsersQuery, email string) (*UsersOneOut, error)
}
type executableSchema struct {
resolvers ResolverRoot
directives DirectiveRoot
complexity ComplexityRoot
}
func (e *executableSchema) Schema() *ast.Schema {
return parsedSchema
}
func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
ec := executionContext{nil, e}
_ = ec
switch typeName + "." + field {
case "Mutation.users":
if e.complexity.Mutation.Users == nil {
break
}
return e.complexity.Mutation.Users(childComplexity), true
case "Product.id":
if e.complexity.Product.ID == nil {
break
}
return e.complexity.Product.ID(childComplexity), true
case "Product.name":
if e.complexity.Product.Name == nil {
break
}
return e.complexity.Product.Name(childComplexity), true
case "Product.productItems":
if e.complexity.Product.ProductItems == nil {
break
}
return e.complexity.Product.ProductItems(childComplexity), true
case "ProductItem.id":
if e.complexity.ProductItem.ID == nil {
break
}
return e.complexity.ProductItem.ID(childComplexity), true
case "ProductItem.name":
if e.complexity.ProductItem.Name == nil {
break
}
return e.complexity.ProductItem.Name(childComplexity), true
case "ProductsListOut.products":
if e.complexity.ProductsListOut.Products == nil {
break
}
return e.complexity.ProductsListOut.Products(childComplexity), true
case "ProductsQuery.list":
if e.complexity.ProductsQuery.List == nil {
break
}
return e.complexity.ProductsQuery.List(childComplexity), true
case "Query.products":
if e.complexity.Query.Products == nil {
break
}
return e.complexity.Query.Products(childComplexity), true
case "Query.users":
if e.complexity.Query.Users == nil {
break
}
return e.complexity.Query.Users(childComplexity), true
case "UsersCreateOut.email":
if e.complexity.UsersCreateOut.Email == nil {
break
}
return e.complexity.UsersCreateOut.Email(childComplexity), true
case "UsersCreateOut.id":
if e.complexity.UsersCreateOut.ID == nil {
break
}
return e.complexity.UsersCreateOut.ID(childComplexity), true
case "UsersCreateOut.status":
if e.complexity.UsersCreateOut.Status == nil {
break
}
return e.complexity.UsersCreateOut.Status(childComplexity), true
case "UsersMutation.createUser":
if e.complexity.UsersMutation.CreateUser == nil {
break
}
args, err := ec.field_UsersMutation_createUser_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.UsersMutation.CreateUser(childComplexity, args["email"].(string), args["password"].(string)), true
case "UsersOneOut.email":
if e.complexity.UsersOneOut.Email == nil {
break
}
return e.complexity.UsersOneOut.Email(childComplexity), true
case "UsersOneOut.id":
if e.complexity.UsersOneOut.ID == nil {
break
}
return e.complexity.UsersOneOut.ID(childComplexity), true
case "UsersQuery.one":
if e.complexity.UsersQuery.One == nil {
break
}
args, err := ec.field_UsersQuery_one_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.UsersQuery.One(childComplexity, args["email"].(string)), true
}
return 0, false
}
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
rc := graphql.GetOperationContext(ctx)
ec := executionContext{rc, e}
first := true
switch rc.Operation.Operation {
case ast.Query:
return func(ctx context.Context) *graphql.Response {
if !first {
return nil
}
first = false
data := ec._Query(ctx, rc.Operation.SelectionSet)
var buf bytes.Buffer
data.MarshalGQL(&buf)
return &graphql.Response{
Data: buf.Bytes(),
}
}
case ast.Mutation:
return func(ctx context.Context) *graphql.Response {
if !first {
return nil
}
first = false
data := ec._Mutation(ctx, rc.Operation.SelectionSet)
var buf bytes.Buffer
data.MarshalGQL(&buf)
return &graphql.Response{
Data: buf.Bytes(),
}
}
default:
return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation"))
}
}
type executionContext struct {
*graphql.OperationContext
*executableSchema
}
func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
if ec.DisableIntrospection {
return nil, errors.New("introspection disabled")
}
return introspection.WrapSchema(parsedSchema), nil
}
func (ec *executionContext) introspectType(name string) (*introspection.Type, error) {
if ec.DisableIntrospection {
return nil, errors.New("introspection disabled")
}
return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil
}
var sources = []*ast.Source{
{Name: "resources/graphql/products.graphql", Input: `type ProductsQuery {
list: ProductsListOut!
}
type Product {
id: ID!
name: String!
productItems: [ProductItem!]!
}
type ProductItem {
id: ID!
name: String!
}
type ProductsListOut {
products: [Product!]!
}
`, BuiltIn: false},
{Name: "resources/graphql/root.graphql", Input: `type Query {
users: UsersQuery
products: ProductsQuery
}
type Mutation {
users: UsersMutation
}
`, BuiltIn: false},
{Name: "resources/graphql/user.graphql", Input: `type UsersOneOut {
id: ID!
email: String!
}
type UsersQuery {
one(email: String!): UsersOneOut! @hasUsersPermission(permission: READ)
}
type UsersMutation {
createUser(email: String!, password: String!): UsersCreateOut! @hasUsersPermission(permission: WRITE)
}
type UsersCreateOut {
status: UsersCreateOutStatus!
id: ID!
email: String!
}
enum UsersCreateOutStatus {
OK
BAD_REQUEST
SERVER_INTERNAL_ERROR
}
directive @hasUsersPermission(permission: UsersPermissionEnum!) on FIELD_DEFINITION
enum UsersPermissionEnum {
READ
WRITE
}
`, BuiltIn: false},
}
var parsedSchema = gqlparser.MustLoadSchema(sources...)
// endregion ************************** generated!.gotpl **************************
// region ***************************** args.gotpl *****************************
func (ec *executionContext) dir_hasUsersPermission_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 UsersPermissionEnum
if tmp, ok := rawArgs["permission"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("permission"))
arg0, err = ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, tmp)
if err != nil {
return nil, err
}
}
args["permission"] = arg0
return args, nil
}
func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["name"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("name"))
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["name"] = arg0
return args, nil
}
func (ec *executionContext) field_UsersMutation_createUser_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["email"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("email"))
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["email"] = arg0
var arg1 string
if tmp, ok := rawArgs["password"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("password"))
arg1, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["password"] = arg1
return args, nil
}
func (ec *executionContext) field_UsersQuery_one_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["email"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("email"))
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["email"] = arg0
return args, nil
}
func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 bool
if tmp, ok := rawArgs["includeDeprecated"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("includeDeprecated"))
arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp)
if err != nil {
return nil, err
}
}
args["includeDeprecated"] = arg0
return args, nil
}
func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 bool
if tmp, ok := rawArgs["includeDeprecated"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("includeDeprecated"))
arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp)
if err != nil {
return nil, err
}
}
args["includeDeprecated"] = arg0
return args, nil
}
// endregion ***************************** args.gotpl *****************************
// region ************************** directives.gotpl **************************
// endregion ************************** directives.gotpl **************************
// region **************************** field.gotpl *****************************
func (ec *executionContext) _Mutation_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Mutation",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().Users(rctx)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*UsersMutation)
fc.Result = res
return ec.marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersMutation(ctx, field.Selections, res)
}
func (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Product",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(int)
fc.Result = res
return ec.marshalNID2int(ctx, field.Selections, res)
}
func (ec *executionContext) _Product_name(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Product",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _Product_productItems(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Product",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Product().ProductItems(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]*domain.ProductItem)
fc.Result = res
return ec.marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItemᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _ProductItem_id(ctx context.Context, field graphql.CollectedField, obj *domain.ProductItem) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "ProductItem",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(int)
fc.Result = res
return ec.marshalNID2int(ctx, field.Selections, res)
}
func (ec *executionContext) _ProductItem_name(ctx context.Context, field graphql.CollectedField, obj *domain.ProductItem) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "ProductItem",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _ProductsListOut_products(ctx context.Context, field graphql.CollectedField, obj *ProductsListOut) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "ProductsListOut",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Products, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]*domain.Product)
fc.Result = res
return ec.marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _ProductsQuery_list(ctx context.Context, field graphql.CollectedField, obj *ProductsQuery) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "ProductsQuery",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.ProductsQuery().List(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*ProductsListOut)
fc.Result = res
return ec.marshalNProductsListOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Users(rctx)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*UsersQuery)
fc.Result = res
return ec.marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersQuery(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_products(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Products(rctx)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*ProductsQuery)
fc.Result = res
return ec.marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsQuery(ctx, field.Selections, res)
}
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query___type_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.introspectType(args["name"].(string))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*introspection.Type)
fc.Result = res
return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.introspectSchema()
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*introspection.Schema)
fc.Result = res
return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersCreateOut_status(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersCreateOut",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Status, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(UsersCreateOutStatus)
fc.Result = res
return ec.marshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersCreateOut_id(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersCreateOut",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersCreateOut_email(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersCreateOut",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Email, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersMutation_createUser(ctx context.Context, field graphql.CollectedField, obj *UsersMutation) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersMutation",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_UsersMutation_createUser_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.UsersMutation().CreateUser(rctx, obj, args["email"].(string), args["password"].(string))
}
directive1 := func(ctx context.Context) (interface{}, error) {
permission, err := ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, "WRITE")
if err != nil {
return nil, err
}
if ec.directives.HasUsersPermission == nil {
return nil, errors.New("directive hasUsersPermission is not implemented")
}
return ec.directives.HasUsersPermission(ctx, obj, directive0, permission)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, err
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*UsersCreateOut); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/aristat/golang-example-app/generated/graphql.UsersCreateOut`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*UsersCreateOut)
fc.Result = res
return ec.marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersOneOut_id(ctx context.Context, field graphql.CollectedField, obj *UsersOneOut) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersOneOut",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersOneOut_email(ctx context.Context, field graphql.CollectedField, obj *UsersOneOut) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersOneOut",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Email, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _UsersQuery_one(ctx context.Context, field graphql.CollectedField, obj *UsersQuery) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UsersQuery",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_UsersQuery_one_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.UsersQuery().One(rctx, obj, args["email"].(string))
}
directive1 := func(ctx context.Context) (interface{}, error) {
permission, err := ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, "READ")
if err != nil {
return nil, err
}
if ec.directives.HasUsersPermission == nil {
return nil, errors.New("directive hasUsersPermission is not implemented")
}
return ec.directives.HasUsersPermission(ctx, obj, directive0, permission)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, err
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*UsersOneOut); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/aristat/golang-example-app/generated/graphql.UsersOneOut`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*UsersOneOut)
fc.Result = res
return ec.marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut(ctx, field.Selections, res)
}
func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Directive",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Directive",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalOString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Directive",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Locations, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]string)
fc.Result = res
return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Directive",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Args, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]introspection.InputValue)
fc.Result = res
return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalOString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsDeprecated(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DeprecationReason(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Field",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Field",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalOString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Field",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Args, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]introspection.InputValue)
fc.Result = res
return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Field",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Type, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*introspection.Type)
fc.Result = res
return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Field",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsDeprecated(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Field",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DeprecationReason(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__InputValue",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__InputValue",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalOString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__InputValue",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Type, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*introspection.Type)
fc.Result = res
return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__InputValue",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DefaultValue, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Schema",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Types(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]introspection.Type)
fc.Result = res
return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Schema",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.QueryType(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*introspection.Type)
fc.Result = res
return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Schema",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.MutationType(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*introspection.Type)
fc.Result = res
return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Schema",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.SubscriptionType(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*introspection.Type)
fc.Result = res
return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Schema",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Directives(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]introspection.Directive)
fc.Result = res
return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Type",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Kind(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalN__TypeKind2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Type",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Type",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalOString2string(ctx, field.Selections, res)
}
func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Type",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field___Type_fields_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Fields(args["includeDeprecated"].(bool)), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.([]introspection.Field)
fc.Result = res
return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Type",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Interfaces(), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.([]introspection.Type)
fc.Result = res
return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "__Type",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pos
gitextract_na8wnxnj/
├── .circleci/
│ └── config.yml
├── .gitignore
├── Makefile
├── README.md
├── app/
│ ├── auth/
│ │ ├── middleware.go
│ │ └── provider.go
│ ├── casbin/
│ │ └── provider.go
│ ├── common/
│ │ ├── bcrypt.go
│ │ ├── constants.go
│ │ ├── graphql.go
│ │ └── jaeger.go
│ ├── config/
│ │ ├── injector.go
│ │ ├── provider.go
│ │ └── wire_gen.go
│ ├── context/
│ │ └── context.go
│ ├── dataloader/
│ │ ├── dataloader.go
│ │ └── productitemloader_gen.go
│ ├── db/
│ │ ├── db.go
│ │ ├── domain/
│ │ │ ├── product.go
│ │ │ ├── product_item.go
│ │ │ └── user.go
│ │ ├── injector.go
│ │ ├── provider.go
│ │ ├── repo/
│ │ │ ├── provider.go
│ │ │ ├── users.go
│ │ │ └── users_test.go
│ │ └── wire_gen.go
│ ├── entrypoint/
│ │ ├── entrypoint.go
│ │ ├── entrypoint_test.go
│ │ └── provider.go
│ ├── graphql/
│ │ ├── graphql.go
│ │ └── provider.go
│ ├── graphql_resolver/
│ │ ├── injector.go
│ │ ├── mock.go
│ │ ├── product.go
│ │ ├── product_test.go
│ │ ├── provider.go
│ │ ├── resolver.go
│ │ ├── resolver_gen.go
│ │ ├── user.go
│ │ ├── user_test.go
│ │ └── wire_gen.go
│ ├── grpc/
│ │ ├── connection.go
│ │ ├── manager.go
│ │ ├── pool.go
│ │ └── provider.go
│ ├── http/
│ │ ├── http.go
│ │ ├── injector.go
│ │ ├── logger.go
│ │ ├── provider.go
│ │ └── wire_gen.go
│ ├── http_routers/
│ │ └── products-router/
│ │ ├── injector.go
│ │ ├── manager.go
│ │ ├── provider.go
│ │ ├── router.go
│ │ ├── router_test.go
│ │ └── wire_gen.go
│ ├── logger/
│ │ ├── injector.go
│ │ ├── logger.go
│ │ ├── middleware.go
│ │ ├── mock.go
│ │ ├── provider.go
│ │ ├── wire_gen.go
│ │ └── zap.go
│ ├── provider/
│ │ └── provider.go
│ └── tracing/
│ ├── jaeger.go
│ └── provider.go
├── cmd/
│ ├── daemon/
│ │ └── daemon.go
│ ├── health-check-service/
│ │ └── health_check_service.go
│ ├── jwt/
│ │ ├── jwt.go
│ │ └── token.go
│ ├── migrate/
│ │ └── migrate.go
│ ├── product-service/
│ │ ├── nats_service.go
│ │ └── product_service.go
│ └── root.go
├── dbconfig.yml
├── docker/
│ └── app/
│ ├── Dockerfile
│ └── files/
│ └── docker/
│ └── bin/
│ └── entrypoint.sh
├── docker-compose.yml
├── generated/
│ ├── graphql/
│ │ ├── generated.go
│ │ └── models_gen.go
│ └── resources/
│ └── proto/
│ ├── health_checks/
│ │ ├── health_checks.pb.go
│ │ └── health_checks_grpc.pb.go
│ └── products/
│ ├── products.pb.go
│ └── products_grpc.pb.go
├── go.mod
├── go.sum
├── gqlgen.yml
├── main.go
├── prototool.yaml
├── resources/
│ ├── casbin/
│ │ ├── model.conf
│ │ └── policy.csv
│ ├── configs/
│ │ ├── development.yaml
│ │ └── docker_development.yaml
│ ├── graphql/
│ │ ├── products.graphql
│ │ ├── root.graphql
│ │ └── user.graphql
│ ├── keys/
│ │ └── local/
│ │ ├── private_key.pem
│ │ └── public_key.pem
│ ├── migrations/
│ │ ├── 20181215164636-create_users.sql
│ │ └── 20181216210607-records.sql
│ ├── proto/
│ │ ├── health_checks/
│ │ │ └── health_checks.proto
│ │ └── products/
│ │ └── products.proto
│ └── templates/
│ └── helpers/
│ └── errors.html
└── scripts/
├── docker-compose-start.sh
└── remove_docker_containers.sh
SYMBOL INDEX (527 symbols across 77 files)
FILE: app/auth/middleware.go
constant prefix (line 20) | prefix = "app.auth"
constant defaultSubject (line 21) | defaultSubject = "anonymous"
constant defaultServiceName (line 22) | defaultServiceName = "unknown"
constant defaultServiceId (line 23) | defaultServiceId = 0
type CustomClaims (line 29) | type CustomClaims struct
type Config (line 34) | type Config struct
type Middleware (line 40) | type Middleware struct
method JWTHandler (line 53) | func (m Middleware) JWTHandler(next http.Handler) http.Handler {
method Service (line 108) | func (m Middleware) Service(claims *CustomClaims) (string, uint64) {
type keys (line 47) | type keys struct
function NewMiddleware (line 121) | func NewMiddleware(cfg Config, log logger.Logger) (*Middleware, func(), ...
function NewTestMiddleware (line 140) | func NewTestMiddleware(log logger.Logger) (*Middleware, func(), error) {
FILE: app/auth/provider.go
function ProviderCfg (line 10) | func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
function Provider (line 17) | func Provider(cfg Config, logger logger.Logger) (*Middleware, func(), er...
function ProviderTest (line 22) | func ProviderTest(logger logger.Logger) (*Middleware, func(), error) {
FILE: app/casbin/provider.go
function Provider (line 10) | func Provider() (*casbin.Enforcer, func(), error) {
function ProviderTest (line 16) | func ProviderTest() (*casbin.Enforcer, func(), error) {
FILE: app/common/bcrypt.go
function HashPassword (line 5) | func HashPassword(password string, cost int) (string, error) {
function CheckPasswordHash (line 10) | func CheckPasswordHash(password, hash string) bool {
FILE: app/common/constants.go
constant SrvProducts (line 4) | SrvProducts = "products"
FILE: app/common/graphql.go
function SendGraphqlError (line 13) | func SendGraphqlError(w http.ResponseWriter, code int, errors gqlerror.L...
function SendGraphqlErrorf (line 23) | func SendGraphqlErrorf(w http.ResponseWriter, code int, format string, a...
FILE: app/common/jaeger.go
function GenerateTracerForTestClient (line 13) | func GenerateTracerForTestClient(serviceName string, cfg *viper.Viper) (...
FILE: app/config/injector.go
function Build (line 11) | func Build() (*viper.Viper, func(), error) {
FILE: app/config/provider.go
function Provider (line 10) | func Provider() (*viper.Viper, func(), error) {
FILE: app/config/wire_gen.go
function Build (line 16) | func Build() (*viper.Viper, func(), error) {
FILE: app/context/context.go
constant prefix (line 9) | prefix = "app.context"
type Manager (line 12) | type Manager struct
method ToMapping (line 17) | func (m *Manager) ToMapping() *Mapping {
function NewManager (line 26) | func NewManager(ctx context.Context) (*Manager, error) {
type Mapping (line 42) | type Mapping struct
function NewContext (line 49) | func NewContext(ctx context.Context, m Mapping) context.Context {
FILE: app/dataloader/dataloader.go
type ctxKeyType (line 17) | type ctxKeyType struct
type loaders (line 21) | type loaders struct
function LoaderMiddleware (line 25) | func LoaderMiddleware(next http.Handler) http.Handler {
function CtxLoaders (line 63) | func CtxLoaders(ctx context.Context) loaders {
FILE: app/dataloader/productitemloader_gen.go
type ProductItemLoaderConfig (line 13) | type ProductItemLoaderConfig struct
function NewProductItemLoader (line 25) | func NewProductItemLoader(config ProductItemLoaderConfig) *ProductItemLo...
type ProductItemLoader (line 34) | type ProductItemLoader struct
method Load (line 66) | func (l *ProductItemLoader) Load(key int) ([]*domain.ProductItem, erro...
method LoadThunk (line 73) | func (l *ProductItemLoader) LoadThunk(key int) func() ([]*domain.Produ...
method LoadAll (line 116) | func (l *ProductItemLoader) LoadAll(keys []int) ([][]*domain.ProductIt...
method LoadAllThunk (line 134) | func (l *ProductItemLoader) LoadAllThunk(keys []int) func() ([][]*doma...
method Prime (line 152) | func (l *ProductItemLoader) Prime(key int, value []*domain.ProductItem...
method Clear (line 167) | func (l *ProductItemLoader) Clear(key int) {
method unsafeSet (line 173) | func (l *ProductItemLoader) unsafeSet(key int, value []*domain.Product...
type productItemLoaderBatch (line 57) | type productItemLoaderBatch struct
method keyIndex (line 182) | func (b *productItemLoaderBatch) keyIndex(l *ProductItemLoader, key in...
method startTimer (line 206) | func (b *productItemLoaderBatch) startTimer(l *ProductItemLoader) {
method end (line 222) | func (b *productItemLoaderBatch) end(l *ProductItemLoader) {
FILE: app/db/db.go
constant prefix (line 13) | prefix = "app.db"
type Config (line 16) | type Config struct
type Manager (line 25) | type Manager struct
function New (line 33) | func New(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB...
FILE: app/db/domain/product.go
type Product (line 3) | type Product struct
FILE: app/db/domain/product_item.go
type ProductItem (line 3) | type ProductItem struct
FILE: app/db/domain/user.go
type User (line 3) | type User struct
type UsersRepo (line 10) | type UsersRepo interface
FILE: app/db/injector.go
function Build (line 10) | func Build() (*Manager, func(), error) {
function BuildTest (line 14) | func BuildTest() (*Manager, func(), error) {
FILE: app/db/provider.go
function Cfg (line 17) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
function CfgTest (line 27) | func CfgTest() (Config, func(), error) {
function ProviderGORM (line 32) | func ProviderGORM(ctx context.Context, log logger.Logger, cfg Config) (*...
function ProviderGORMTest (line 55) | func ProviderGORMTest() (*gorm.DB, func(), error) {
function Provider (line 78) | func Provider(ctx context.Context, log logger.Logger, cfg Config, db *go...
FILE: app/db/repo/provider.go
type Repo (line 9) | type Repo struct
function Provider (line 14) | func Provider(userDomain domain.UsersRepo) (*Repo, func(), error) {
FILE: app/db/repo/users.go
type UsersRepo (line 8) | type UsersRepo struct
method CreateUser (line 12) | func (u *UsersRepo) CreateUser(email string, encryptPassword string) (...
method FindByEmail (line 22) | func (u *UsersRepo) FindByEmail(email string) (*domain.User, error) {
function NewUsersRepo (line 35) | func NewUsersRepo(db *gorm.DB) (domain.UsersRepo, func(), error) {
FILE: app/db/repo/users_test.go
function TestCreateUser (line 20) | func TestCreateUser(t *testing.T) {
function TestFindByEmail (line 85) | func TestFindByEmail(t *testing.T) {
FILE: app/db/wire_gen.go
function Build (line 21) | func Build() (*Manager, func(), error) {
function BuildTest (line 82) | func BuildTest() (*Manager, func(), error) {
FILE: app/entrypoint/entrypoint.go
constant prefix (line 21) | prefix = "app.entrypoint"
function init (line 23) | func init() {
function Viper (line 28) | func Viper() *viper.Viper {
function Initialize (line 39) | func Initialize(workDir string, v *viper.Viper) (*EntryPoint, error) {
function OnShutdown (line 55) | func OnShutdown() context.Context {
function OnReload (line 60) | func OnReload() <-chan struct{} {
type EntryPoint (line 65) | type EntryPoint struct
method Reload (line 79) | func (e *EntryPoint) Reload() {
function Shutdown (line 69) | func Shutdown(ctx context.Context, code int) {
function WorkDir (line 88) | func WorkDir() string {
FILE: app/entrypoint/entrypoint_test.go
function TestInitialize (line 13) | func TestInitialize(t *testing.T) {
FILE: app/entrypoint/provider.go
function ContextProvider (line 12) | func ContextProvider() (context.Context, func(), error) {
function ContextProviderTest (line 18) | func ContextProviderTest() (context.Context, func(), error) {
FILE: app/graphql/graphql.go
constant prefix (line 24) | prefix = "app.graphql"
type GraphQL (line 30) | type GraphQL struct
method Use (line 38) | func (g *GraphQL) Use(router *chi.Mux) {
method Routers (line 43) | func (g *GraphQL) Routers(router chi.Router) {
type Config (line 96) | type Config struct
function New (line 104) | func New(ctx context.Context, resolver graphql.Config, log logger.Logger...
FILE: app/graphql/provider.go
function Cfg (line 15) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
function CfgTest (line 28) | func CfgTest() (Config, func(), error) {
function Provider (line 33) | func Provider(ctx context.Context, resolver graphql.Config, log logger.L...
FILE: app/graphql_resolver/injector.go
function Build (line 14) | func Build() (graphql.Config, func(), error) {
function BuildTest (line 18) | func BuildTest() (graphql.Config, func(), error) {
FILE: app/graphql_resolver/mock.go
type ProductServerMock (line 10) | type ProductServerMock struct
method ListProduct (line 14) | func (s *ProductServerMock) ListProduct(ctx context.Context, in *produ...
FILE: app/graphql_resolver/product.go
type productsQueryResolver (line 18) | type productsQueryResolver struct
method List (line 31) | func (r *productsQueryResolver) List(ctx context.Context, obj *graphql...
type productResolver (line 19) | type productResolver struct
method ProductItems (line 68) | func (r *productResolver) ProductItems(ctx context.Context, obj *domai...
method ProductsQuery (line 21) | func (r *Resolver) ProductsQuery() graphql.ProductsQueryResolver {
method Products (line 27) | func (r *queryResolver) Products(ctx context.Context) (*graphql.Products...
method ProductsRoot (line 60) | func (r *queryResolver) ProductsRoot(ctx context.Context) ([]*domain.Pro...
method Product (line 64) | func (r *Resolver) Product() graphql.ProductResolver {
FILE: app/graphql_resolver/product_test.go
function TestMain (line 30) | func TestMain(m *testing.M) {
function TestList (line 52) | func TestList(t *testing.T) {
FILE: app/graphql_resolver/provider.go
function Cfg (line 15) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
function CfgTest (line 22) | func CfgTest() (Config, func(), error) {
function Provider (line 31) | func Provider(ctx context.Context, log logger.Logger, cfg Config, enforc...
FILE: app/graphql_resolver/resolver.go
type Config (line 25) | type Config struct
type Managers (line 30) | type Managers struct
type queryResolver (line 35) | type queryResolver struct
type mutationResolver (line 36) | type mutationResolver struct
type Resolver (line 39) | type Resolver struct
method Mutation (line 48) | func (r *Resolver) Mutation() graphql1.MutationResolver {
method Query (line 53) | func (r *Resolver) Query() graphql1.QueryResolver {
function New (line 58) | func New(ctx context.Context, log logger.Logger, cfg Config, enforcer *c...
FILE: app/graphql_resolver/user.go
type usersQueryResolver (line 12) | type usersQueryResolver struct
method One (line 28) | func (r *usersQueryResolver) One(ctx context.Context, obj *graphql1.Us...
type usersMutationResolver (line 13) | type usersMutationResolver struct
method CreateUser (line 49) | func (r *usersMutationResolver) CreateUser(ctx context.Context, obj *g...
method UsersMutation (line 15) | func (r *Resolver) UsersMutation() graphql1.UsersMutationResolver {
method UsersQuery (line 18) | func (r *Resolver) UsersQuery() graphql1.UsersQueryResolver {
method Users (line 24) | func (r *queryResolver) Users(ctx context.Context) (*graphql1.UsersQuery...
method Users (line 45) | func (r *mutationResolver) Users(ctx context.Context) (*graphql1.UsersMu...
FILE: app/graphql_resolver/user_test.go
type UserParams (line 18) | type UserParams struct
function TestOne (line 24) | func TestOne(t *testing.T) {
FILE: app/graphql_resolver/wire_gen.go
function Build (line 24) | func Build() (graphql.Config, func(), error) {
function BuildTest (line 213) | func BuildTest() (graphql.Config, func(), error) {
FILE: app/grpc/connection.go
function SetPool (line 15) | func SetPool(p *Pool, srv string) {
function GetConnGRPC (line 24) | func GetConnGRPC(poolManager *PoolManager, srv string) (*grpc.ClientConn...
FILE: app/grpc/manager.go
constant prefix (line 19) | prefix = "app.grpc"
type PoolManager (line 24) | type PoolManager struct
method NewPool (line 32) | func (p *PoolManager) NewPool(service string) (_ *Pool, loaded bool, _...
function NewPoolManager (line 77) | func NewPoolManager(ctx context.Context, tracing *tracesdk.TracerProvide...
FILE: app/grpc/pool.go
type Done (line 19) | type Done
type conn (line 21) | type conn struct
method init (line 27) | func (c *conn) init() {
type Pool (line 32) | type Pool struct
method Get (line 42) | func (p *Pool) Get() (*grpc.ClientConn, Done, error) {
type opts (line 49) | type opts struct
type Option (line 58) | type Option
function ConnOptions (line 61) | func ConnOptions(o ...grpc.DialOption) Option {
function MaxConn (line 69) | func MaxConn(value int) Option {
function InitConn (line 77) | func InitConn(value int) Option {
function MaxLifeDuration (line 85) | func MaxLifeDuration(value time.Duration) Option {
function IdleTimeout (line 93) | func IdleTimeout(value time.Duration) Option {
function NewPool (line 101) | func NewPool(ctx context.Context, service, target string, o ...Option) (...
FILE: app/grpc/provider.go
function Cfg (line 23) | func Cfg(cfg *viper.Viper) (*Config, func(), error) {
function CfgTest (line 33) | func CfgTest() (*Config, func(), error) {
type Service (line 38) | type Service struct
type Config (line 48) | type Config struct
function Provider (line 54) | func Provider(ctx context.Context, tracing *tracesdk.TracerProvider, log...
FILE: app/http/http.go
constant prefix (line 15) | prefix = "app.http"
type Config (line 18) | type Config struct
type Http (line 24) | type Http struct
method ListenAndServe (line 33) | func (m *Http) ListenAndServe(wg *sync.WaitGroup, bind ...string) (ser...
function New (line 63) | func New(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Confi...
FILE: app/http/injector.go
function Build (line 16) | func Build() (*Http, func(), error) {
FILE: app/http/logger.go
function Logger (line 11) | func Logger(l logger.Logger) func(next http.Handler) http.Handler {
FILE: app/http/provider.go
function Cfg (line 27) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
function CfgTest (line 38) | func CfgTest() (Config, func(), error) {
function Mux (line 43) | func Mux(managers Managers, log logger.Logger) (*chi.Mux, func(), error) {
type Managers (line 61) | type Managers struct
function Provider (line 72) | func Provider(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg ...
FILE: app/http/wire_gen.go
function Build (line 27) | func Build() (*Http, func(), error) {
FILE: app/http_routers/products-router/injector.go
function Build (line 11) | func Build() (*Manager, func(), error) {
function BuildTest (line 15) | func BuildTest() (*Manager, func(), error) {
FILE: app/http_routers/products-router/manager.go
constant prefix (line 10) | prefix = "app.products-router"
type Manager (line 13) | type Manager struct
type ServiceManagers (line 20) | type ServiceManagers struct
function New (line 24) | func New(ctx context.Context, log logger.Logger, managers ServiceManager...
FILE: app/http_routers/products-router/provider.go
function Cfg (line 12) | func Cfg(cfg *viper.Viper) (*Config, func(), error) {
function CfgTest (line 22) | func CfgTest() (*Config, func(), error) {
type Config (line 27) | type Config struct
function Provider (line 37) | func Provider(ctx context.Context, log logger.Logger, managers ServiceMa...
FILE: app/http_routers/products-router/router.go
type Router (line 20) | type Router struct
method Run (line 27) | func (router *Router) Run(chiRouter chi.Router) {
method GetProductsGrpc (line 33) | func (router *Router) GetProductsGrpc(w http.ResponseWriter, r *http.R...
method GetProductsNats (line 61) | func (router *Router) GetProductsNats(w http.ResponseWriter, r *http.R...
method GetProductsSlowly (line 94) | func (router *Router) GetProductsSlowly(w http.ResponseWriter, r *http...
FILE: app/http_routers/products-router/router_test.go
function TestMain (line 32) | func TestMain(m *testing.M) {
function TestGetProductsGrpc (line 54) | func TestGetProductsGrpc(t *testing.T) {
FILE: app/http_routers/products-router/wire_gen.go
function Build (line 20) | func Build() (*Manager, func(), error) {
function BuildTest (line 123) | func BuildTest() (*Manager, func(), error) {
FILE: app/logger/injector.go
function Build (line 12) | func Build() (Logger, func(), error) {
function BuildTest (line 16) | func BuildTest() (Logger, func(), error) {
FILE: app/logger/logger.go
type Fields (line 4) | type Fields
type Level (line 8) | type Level
method String (line 11) | func (l Level) String() string {
method FromString (line 34) | func (l *Level) FromString(level string) Level {
constant LevelDebug (line 58) | LevelDebug Level = 7
constant LevelInfo (line 60) | LevelInfo Level = 6
constant LevelNotice (line 62) | LevelNotice Level = 5
constant LevelWarning (line 64) | LevelWarning Level = 4
constant LevelError (line 66) | LevelError Level = 3
constant LevelCritical (line 68) | LevelCritical Level = 2
constant LevelAlert (line 70) | LevelAlert Level = 1
constant LevelEmergency (line 72) | LevelEmergency Level = 0
type opts (line 75) | type opts struct
type Option (line 81) | type Option
function Args (line 84) | func Args(a ...interface{}) Option {
function WithFields (line 92) | func WithFields(fields Fields) Option {
type Config (line 100) | type Config struct
type Logger (line 105) | type Logger interface
FILE: app/logger/middleware.go
function UnaryClientInterceptor (line 12) | func UnaryClientInterceptor(log Logger, enable bool) grpc.UnaryClientInt...
function StreamClientInterceptor (line 35) | func StreamClientInterceptor(log Logger, enable bool) grpc.StreamClientI...
function UnaryServerInterceptor (line 57) | func UnaryServerInterceptor(log Logger, enable bool) grpc.UnaryServerInt...
function StreamServerInterceptor (line 80) | func StreamServerInterceptor(log Logger, enable bool) grpc.StreamServerI...
FILE: app/logger/mock.go
type Entity (line 8) | type Entity struct
type Mock (line 16) | type Mock struct
method Printf (line 25) | func (m *Mock) Printf(format string, a ...interface{}) {
method Emergency (line 30) | func (m *Mock) Emergency(format string, opts ...Option) {
method Alert (line 35) | func (m *Mock) Alert(format string, opts ...Option) {
method Critical (line 40) | func (m *Mock) Critical(format string, opts ...Option) {
method Error (line 45) | func (m *Mock) Error(format string, opts ...Option) {
method Warning (line 50) | func (m *Mock) Warning(format string, opts ...Option) {
method Notice (line 55) | func (m *Mock) Notice(format string, opts ...Option) {
method Info (line 60) | func (m *Mock) Info(format string, opts ...Option) {
method Debug (line 65) | func (m *Mock) Debug(format string, opts ...Option) {
method Write (line 70) | func (m *Mock) Write(p []byte) (n int, err error) {
method Log (line 76) | func (m *Mock) Log(level Level, format string, o ...Option) {
method WithFields (line 106) | func (m *Mock) WithFields(fields Fields) Logger {
method Catch (line 129) | func (m *Mock) Catch() <-chan Entity {
function copyMock (line 112) | func copyMock(dst, src *Mock, fields map[string]interface{}) {
function newMock (line 134) | func newMock(ctx context.Context, cfg Config, discard bool) *Mock {
FILE: app/logger/provider.go
function ProviderCfg (line 11) | func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
function ProviderCfgTest (line 24) | func ProviderCfgTest() (Config, func(), error) {
function Provider (line 29) | func Provider(ctx context.Context, cfg Config) (*Zap, func(), error) {
function ProviderTest (line 34) | func ProviderTest(ctx context.Context, cfg Config) (*Mock, func(), error) {
FILE: app/logger/wire_gen.go
function Build (line 17) | func Build() (Logger, func(), error) {
function BuildTest (line 48) | func BuildTest() (Logger, func(), error) {
FILE: app/logger/zap.go
type Zap (line 12) | type Zap struct
method Printf (line 20) | func (z *Zap) Printf(format string, a ...interface{}) {
method Emergency (line 25) | func (z *Zap) Emergency(format string, opts ...Option) {
method Alert (line 30) | func (z *Zap) Alert(format string, opts ...Option) {
method Critical (line 35) | func (z *Zap) Critical(format string, opts ...Option) {
method Error (line 40) | func (z *Zap) Error(format string, opts ...Option) {
method Warning (line 45) | func (z *Zap) Warning(format string, opts ...Option) {
method Notice (line 50) | func (z *Zap) Notice(format string, opts ...Option) {
method Info (line 55) | func (z *Zap) Info(format string, opts ...Option) {
method Debug (line 60) | func (z *Zap) Debug(format string, opts ...Option) {
method Write (line 65) | func (z *Zap) Write(p []byte) (n int, err error) {
method Log (line 71) | func (z *Zap) Log(level Level, format string, o ...Option) {
method WithFields (line 127) | func (z *Zap) WithFields(fields Fields) Logger {
function copyZap (line 133) | func copyZap(dst, src *Zap, fields map[string]interface{}) {
function newZap (line 149) | func newZap(ctx context.Context, cfg Config) *Zap {
FILE: app/tracing/jaeger.go
type Configuration (line 15) | type Configuration struct
constant prefix (line 21) | prefix = "app.tracer"
function newJaegerTracer (line 23) | func newJaegerTracer(ctx context.Context, configuration *Configuration, ...
FILE: app/tracing/provider.go
function Cfg (line 19) | func Cfg(cfg *viper.Viper) (*Configuration, func(), error) {
function Provider (line 29) | func Provider(ctx context.Context, configuration *Configuration, log log...
function ProviderTest (line 37) | func ProviderTest() (*tracesdk.TracerProvider, func(), error) {
FILE: cmd/daemon/daemon.go
function init (line 79) | func init() {
FILE: cmd/health-check-service/health_check_service.go
type Config (line 29) | type Config struct
type server (line 34) | type server struct
method IsAlive (line 39) | func (s *server) IsAlive(ctx context.Context, empty *emptypb.Empty) (*...
function init (line 131) | func init() {
FILE: cmd/jwt/jwt.go
function init (line 12) | func init() {
FILE: cmd/jwt/token.go
function init (line 21) | func init() {
function GenerateJWT (line 71) | func GenerateJWT(privateKey []byte, fields map[string]interface{}) (stri...
FILE: cmd/migrate/migrate.go
function init (line 79) | func init() {
FILE: cmd/product-service/nats_service.go
type natsService (line 8) | type natsService struct
method workerHanlder (line 12) | func (s *natsService) workerHanlder(m *stan.Msg) {
FILE: cmd/product-service/product_service.go
type Config (line 35) | type Config struct
type server (line 42) | type server struct
method ListProduct (line 48) | func (s *server) ListProduct(ctx context.Context, in *products.ListPro...
function init (line 180) | func init() {
FILE: cmd/root.go
constant prefix (line 39) | prefix = "cmd.root"
function init (line 81) | func init() {
function Execute (line 114) | func Execute() {
FILE: generated/graphql/generated.go
function NewExecutableSchema (line 24) | func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
type Config (line 32) | type Config struct
type ResolverRoot (line 38) | type ResolverRoot interface
type DirectiveRoot (line 47) | type DirectiveRoot struct
type ComplexityRoot (line 51) | type ComplexityRoot struct
type MutationResolver (line 100) | type MutationResolver interface
type ProductResolver (line 103) | type ProductResolver interface
type ProductsQueryResolver (line 106) | type ProductsQueryResolver interface
type QueryResolver (line 109) | type QueryResolver interface
type UsersMutationResolver (line 113) | type UsersMutationResolver interface
type UsersQueryResolver (line 116) | type UsersQueryResolver interface
type executableSchema (line 120) | type executableSchema struct
method Schema (line 126) | func (e *executableSchema) Schema() *ast.Schema {
method Complexity (line 130) | func (e *executableSchema) Complexity(typeName, field string, childCom...
method Exec (line 268) | func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseH...
type executionContext (line 308) | type executionContext struct
method introspectSchema (line 313) | func (ec *executionContext) introspectSchema() (*introspection.Schema,...
method introspectType (line 320) | func (ec *executionContext) introspectType(name string) (*introspectio...
method dir_hasUsersPermission_args (line 395) | func (ec *executionContext) dir_hasUsersPermission_args(ctx context.Co...
method field_Query___type_args (line 410) | func (ec *executionContext) field_Query___type_args(ctx context.Contex...
method field_UsersMutation_createUser_args (line 425) | func (ec *executionContext) field_UsersMutation_createUser_args(ctx co...
method field_UsersQuery_one_args (line 449) | func (ec *executionContext) field_UsersQuery_one_args(ctx context.Cont...
method field___Type_enumValues_args (line 464) | func (ec *executionContext) field___Type_enumValues_args(ctx context.C...
method field___Type_fields_args (line 479) | func (ec *executionContext) field___Type_fields_args(ctx context.Conte...
method _Mutation_users (line 502) | func (ec *executionContext) _Mutation_users(ctx context.Context, field...
method _Product_id (line 533) | func (ec *executionContext) _Product_id(ctx context.Context, field gra...
method _Product_name (line 567) | func (ec *executionContext) _Product_name(ctx context.Context, field g...
method _Product_productItems (line 601) | func (ec *executionContext) _Product_productItems(ctx context.Context,...
method _ProductItem_id (line 635) | func (ec *executionContext) _ProductItem_id(ctx context.Context, field...
method _ProductItem_name (line 669) | func (ec *executionContext) _ProductItem_name(ctx context.Context, fie...
method _ProductsListOut_products (line 703) | func (ec *executionContext) _ProductsListOut_products(ctx context.Cont...
method _ProductsQuery_list (line 737) | func (ec *executionContext) _ProductsQuery_list(ctx context.Context, f...
method _Query_users (line 771) | func (ec *executionContext) _Query_users(ctx context.Context, field gr...
method _Query_products (line 802) | func (ec *executionContext) _Query_products(ctx context.Context, field...
method _Query___type (line 833) | func (ec *executionContext) _Query___type(ctx context.Context, field g...
method _Query___schema (line 871) | func (ec *executionContext) _Query___schema(ctx context.Context, field...
method _UsersCreateOut_status (line 902) | func (ec *executionContext) _UsersCreateOut_status(ctx context.Context...
method _UsersCreateOut_id (line 936) | func (ec *executionContext) _UsersCreateOut_id(ctx context.Context, fi...
method _UsersCreateOut_email (line 970) | func (ec *executionContext) _UsersCreateOut_email(ctx context.Context,...
method _UsersMutation_createUser (line 1004) | func (ec *executionContext) _UsersMutation_createUser(ctx context.Cont...
method _UsersOneOut_id (line 1069) | func (ec *executionContext) _UsersOneOut_id(ctx context.Context, field...
method _UsersOneOut_email (line 1103) | func (ec *executionContext) _UsersOneOut_email(ctx context.Context, fi...
method _UsersQuery_one (line 1137) | func (ec *executionContext) _UsersQuery_one(ctx context.Context, field...
method ___Directive_name (line 1202) | func (ec *executionContext) ___Directive_name(ctx context.Context, fie...
method ___Directive_description (line 1236) | func (ec *executionContext) ___Directive_description(ctx context.Conte...
method ___Directive_locations (line 1267) | func (ec *executionContext) ___Directive_locations(ctx context.Context...
method ___Directive_args (line 1301) | func (ec *executionContext) ___Directive_args(ctx context.Context, fie...
method ___EnumValue_name (line 1335) | func (ec *executionContext) ___EnumValue_name(ctx context.Context, fie...
method ___EnumValue_description (line 1369) | func (ec *executionContext) ___EnumValue_description(ctx context.Conte...
method ___EnumValue_isDeprecated (line 1400) | func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Cont...
method ___EnumValue_deprecationReason (line 1434) | func (ec *executionContext) ___EnumValue_deprecationReason(ctx context...
method ___Field_name (line 1465) | func (ec *executionContext) ___Field_name(ctx context.Context, field g...
method ___Field_description (line 1499) | func (ec *executionContext) ___Field_description(ctx context.Context, ...
method ___Field_args (line 1530) | func (ec *executionContext) ___Field_args(ctx context.Context, field g...
method ___Field_type (line 1564) | func (ec *executionContext) ___Field_type(ctx context.Context, field g...
method ___Field_isDeprecated (line 1598) | func (ec *executionContext) ___Field_isDeprecated(ctx context.Context,...
method ___Field_deprecationReason (line 1632) | func (ec *executionContext) ___Field_deprecationReason(ctx context.Con...
method ___InputValue_name (line 1663) | func (ec *executionContext) ___InputValue_name(ctx context.Context, fi...
method ___InputValue_description (line 1697) | func (ec *executionContext) ___InputValue_description(ctx context.Cont...
method ___InputValue_type (line 1728) | func (ec *executionContext) ___InputValue_type(ctx context.Context, fi...
method ___InputValue_defaultValue (line 1762) | func (ec *executionContext) ___InputValue_defaultValue(ctx context.Con...
method ___Schema_types (line 1793) | func (ec *executionContext) ___Schema_types(ctx context.Context, field...
method ___Schema_queryType (line 1827) | func (ec *executionContext) ___Schema_queryType(ctx context.Context, f...
method ___Schema_mutationType (line 1861) | func (ec *executionContext) ___Schema_mutationType(ctx context.Context...
method ___Schema_subscriptionType (line 1892) | func (ec *executionContext) ___Schema_subscriptionType(ctx context.Con...
method ___Schema_directives (line 1923) | func (ec *executionContext) ___Schema_directives(ctx context.Context, ...
method ___Type_kind (line 1957) | func (ec *executionContext) ___Type_kind(ctx context.Context, field gr...
method ___Type_name (line 1991) | func (ec *executionContext) ___Type_name(ctx context.Context, field gr...
method ___Type_description (line 2022) | func (ec *executionContext) ___Type_description(ctx context.Context, f...
method ___Type_fields (line 2053) | func (ec *executionContext) ___Type_fields(ctx context.Context, field ...
method ___Type_interfaces (line 2091) | func (ec *executionContext) ___Type_interfaces(ctx context.Context, fi...
method ___Type_possibleTypes (line 2122) | func (ec *executionContext) ___Type_possibleTypes(ctx context.Context,...
method ___Type_enumValues (line 2153) | func (ec *executionContext) ___Type_enumValues(ctx context.Context, fi...
method ___Type_inputFields (line 2191) | func (ec *executionContext) ___Type_inputFields(ctx context.Context, f...
method ___Type_ofType (line 2222) | func (ec *executionContext) ___Type_ofType(ctx context.Context, field ...
method _Mutation (line 2267) | func (ec *executionContext) _Mutation(ctx context.Context, sel ast.Sel...
method _Product (line 2295) | func (ec *executionContext) _Product(ctx context.Context, sel ast.Sele...
method _ProductItem (line 2341) | func (ec *executionContext) _ProductItem(ctx context.Context, sel ast....
method _ProductsListOut (line 2373) | func (ec *executionContext) _ProductsListOut(ctx context.Context, sel ...
method _ProductsQuery (line 2400) | func (ec *executionContext) _ProductsQuery(ctx context.Context, sel as...
method _Query (line 2436) | func (ec *executionContext) _Query(ctx context.Context, sel ast.Select...
method _UsersCreateOut (line 2488) | func (ec *executionContext) _UsersCreateOut(ctx context.Context, sel a...
method _UsersMutation (line 2525) | func (ec *executionContext) _UsersMutation(ctx context.Context, sel as...
method _UsersOneOut (line 2561) | func (ec *executionContext) _UsersOneOut(ctx context.Context, sel ast....
method _UsersQuery (line 2593) | func (ec *executionContext) _UsersQuery(ctx context.Context, sel ast.S...
method ___Directive (line 2629) | func (ec *executionContext) ___Directive(ctx context.Context, sel ast....
method ___EnumValue (line 2668) | func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast....
method ___Field (line 2704) | func (ec *executionContext) ___Field(ctx context.Context, sel ast.Sele...
method ___InputValue (line 2750) | func (ec *executionContext) ___InputValue(ctx context.Context, sel ast...
method ___Schema (line 2786) | func (ec *executionContext) ___Schema(ctx context.Context, sel ast.Sel...
method ___Type (line 2827) | func (ec *executionContext) ___Type(ctx context.Context, sel ast.Selec...
method unmarshalNBoolean2bool (line 2872) | func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context...
method marshalNBoolean2bool (line 2877) | func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, ...
method unmarshalNID2int (line 2887) | func (ec *executionContext) unmarshalNID2int(ctx context.Context, v in...
method marshalNID2int (line 2892) | func (ec *executionContext) marshalNID2int(ctx context.Context, sel as...
method unmarshalNID2string (line 2902) | func (ec *executionContext) unmarshalNID2string(ctx context.Context, v...
method marshalNID2string (line 2907) | func (ec *executionContext) marshalNID2string(ctx context.Context, sel...
method marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductᚄ (line 2917) | func (ec *executionContext) marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolan...
method marshalNProduct2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProduct (line 2954) | func (ec *executionContext) marshalNProduct2ᚖgithubᚗcomᚋaristatᚋgolang...
method marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItemᚄ (line 2964) | func (ec *executionContext) marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋg...
method marshalNProductItem2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItem (line 3001) | func (ec *executionContext) marshalNProductItem2ᚖgithubᚗcomᚋaristatᚋgo...
method marshalNProductsListOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut (line 3011) | func (ec *executionContext) marshalNProductsListOut2githubᚗcomᚋaristat...
method marshalNProductsListOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut (line 3015) | func (ec *executionContext) marshalNProductsListOut2ᚖgithubᚗcomᚋarista...
method unmarshalNString2string (line 3025) | func (ec *executionContext) unmarshalNString2string(ctx context.Contex...
method marshalNString2string (line 3030) | func (ec *executionContext) marshalNString2string(ctx context.Context,...
method marshalNUsersCreateOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut (line 3040) | func (ec *executionContext) marshalNUsersCreateOut2githubᚗcomᚋaristatᚋ...
method marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut (line 3044) | func (ec *executionContext) marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristat...
method unmarshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus (line 3054) | func (ec *executionContext) unmarshalNUsersCreateOutStatus2githubᚗcomᚋ...
method marshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus (line 3060) | func (ec *executionContext) marshalNUsersCreateOutStatus2githubᚗcomᚋar...
method marshalNUsersOneOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut (line 3064) | func (ec *executionContext) marshalNUsersOneOut2githubᚗcomᚋaristatᚋgol...
method marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut (line 3068) | func (ec *executionContext) marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgo...
method unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum (line 3078) | func (ec *executionContext) unmarshalNUsersPermissionEnum2githubᚗcomᚋa...
method marshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum (line 3084) | func (ec *executionContext) marshalNUsersPermissionEnum2githubᚗcomᚋari...
method marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective (line 3088) | func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋg...
method marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ (line 3092) | func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋ...
method unmarshalN__DirectiveLocation2string (line 3129) | func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx c...
method marshalN__DirectiveLocation2string (line 3134) | func (ec *executionContext) marshalN__DirectiveLocation2string(ctx con...
method unmarshalN__DirectiveLocation2ᚕstringᚄ (line 3144) | func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx...
method marshalN__DirectiveLocation2ᚕstringᚄ (line 3165) | func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx c...
method marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue (line 3202) | func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋg...
method marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField (line 3206) | func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlge...
method marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue (line 3210) | func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋ...
method marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ (line 3214) | func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designs...
method marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 3251) | func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgen...
method marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ (line 3255) | func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlge...
method marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 3292) | func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlge...
method unmarshalN__TypeKind2string (line 3302) | func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Co...
method marshalN__TypeKind2string (line 3307) | func (ec *executionContext) marshalN__TypeKind2string(ctx context.Cont...
method unmarshalOBoolean2bool (line 3317) | func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context...
method marshalOBoolean2bool (line 3322) | func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, ...
method unmarshalOBoolean2ᚖbool (line 3326) | func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Contex...
method marshalOBoolean2ᚖbool (line 3334) | func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context,...
method marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsQuery (line 3341) | func (ec *executionContext) marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋ...
method unmarshalOString2string (line 3348) | func (ec *executionContext) unmarshalOString2string(ctx context.Contex...
method marshalOString2string (line 3353) | func (ec *executionContext) marshalOString2string(ctx context.Context,...
method unmarshalOString2ᚖstring (line 3357) | func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Conte...
method marshalOString2ᚖstring (line 3365) | func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context...
method marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersMutation (line 3372) | func (ec *executionContext) marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋ...
method marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersQuery (line 3379) | func (ec *executionContext) marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgol...
method marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ (line 3386) | func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋ...
method marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ (line 3426) | func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlg...
method marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ (line 3466) | func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designs...
method marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema (line 3506) | func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgql...
method marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ (line 3513) | func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlge...
method marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 3553) | func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlge...
FILE: generated/graphql/models_gen.go
type ProductsListOut (line 13) | type ProductsListOut struct
type ProductsQuery (line 17) | type ProductsQuery struct
type UsersCreateOut (line 21) | type UsersCreateOut struct
type UsersMutation (line 27) | type UsersMutation struct
type UsersOneOut (line 31) | type UsersOneOut struct
type UsersQuery (line 36) | type UsersQuery struct
type UsersCreateOutStatus (line 40) | type UsersCreateOutStatus
method IsValid (line 54) | func (e UsersCreateOutStatus) IsValid() bool {
method String (line 62) | func (e UsersCreateOutStatus) String() string {
method UnmarshalGQL (line 66) | func (e *UsersCreateOutStatus) UnmarshalGQL(v interface{}) error {
method MarshalGQL (line 79) | func (e UsersCreateOutStatus) MarshalGQL(w io.Writer) {
constant UsersCreateOutStatusOk (line 43) | UsersCreateOutStatusOk UsersCreateOutStatus = "OK"
constant UsersCreateOutStatusBadRequest (line 44) | UsersCreateOutStatusBadRequest UsersCreateOutStatus = "BAD_REQU...
constant UsersCreateOutStatusServerInternalError (line 45) | UsersCreateOutStatusServerInternalError UsersCreateOutStatus = "SERVER_I...
type UsersPermissionEnum (line 83) | type UsersPermissionEnum
method IsValid (line 95) | func (e UsersPermissionEnum) IsValid() bool {
method String (line 103) | func (e UsersPermissionEnum) String() string {
method UnmarshalGQL (line 107) | func (e *UsersPermissionEnum) UnmarshalGQL(v interface{}) error {
method MarshalGQL (line 120) | func (e UsersPermissionEnum) MarshalGQL(w io.Writer) {
constant UsersPermissionEnumRead (line 86) | UsersPermissionEnumRead UsersPermissionEnum = "READ"
constant UsersPermissionEnumWrite (line 87) | UsersPermissionEnumWrite UsersPermissionEnum = "WRITE"
FILE: generated/resources/proto/health_checks/health_checks.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type IsAliveOut_Status (line 24) | type IsAliveOut_Status
method Enum (line 43) | func (x IsAliveOut_Status) Enum() *IsAliveOut_Status {
method String (line 49) | func (x IsAliveOut_Status) String() string {
method Descriptor (line 53) | func (IsAliveOut_Status) Descriptor() protoreflect.EnumDescriptor {
method Type (line 57) | func (IsAliveOut_Status) Type() protoreflect.EnumType {
method Number (line 61) | func (x IsAliveOut_Status) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 66) | func (IsAliveOut_Status) EnumDescriptor() ([]byte, []int) {
constant IsAliveOut_OK (line 27) | IsAliveOut_OK IsAliveOut_Status = 0
constant IsAliveOut_NOT_OK (line 28) | IsAliveOut_NOT_OK IsAliveOut_Status = 2
type IsAliveOut (line 70) | type IsAliveOut struct
method Reset (line 78) | func (x *IsAliveOut) Reset() {
method String (line 87) | func (x *IsAliveOut) String() string {
method ProtoMessage (line 91) | func (*IsAliveOut) ProtoMessage() {}
method ProtoReflect (line 93) | func (x *IsAliveOut) ProtoReflect() protoreflect.Message {
method Descriptor (line 106) | func (*IsAliveOut) Descriptor() ([]byte, []int) {
method GetStatus (line 110) | func (x *IsAliveOut) GetStatus() IsAliveOut_Status {
function file_resources_proto_health_checks_health_checks_proto_rawDescGZIP (line 149) | func file_resources_proto_health_checks_health_checks_proto_rawDescGZIP(...
function init (line 174) | func init() { file_resources_proto_health_checks_health_checks_proto_ini...
function file_resources_proto_health_checks_health_checks_proto_init (line 175) | func file_resources_proto_health_checks_health_checks_proto_init() {
FILE: generated/resources/proto/health_checks/health_checks_grpc.pb.go
constant _ (line 16) | _ = grpc.SupportPackageIsVersion7
type HealthChecksClient (line 21) | type HealthChecksClient interface
type healthChecksClient (line 25) | type healthChecksClient struct
method IsAlive (line 33) | func (c *healthChecksClient) IsAlive(ctx context.Context, in *emptypb....
function NewHealthChecksClient (line 29) | func NewHealthChecksClient(cc grpc.ClientConnInterface) HealthChecksClie...
type HealthChecksServer (line 45) | type HealthChecksServer interface
type UnimplementedHealthChecksServer (line 51) | type UnimplementedHealthChecksServer struct
method IsAlive (line 54) | func (UnimplementedHealthChecksServer) IsAlive(context.Context, *empty...
method mustEmbedUnimplementedHealthChecksServer (line 57) | func (UnimplementedHealthChecksServer) mustEmbedUnimplementedHealthChe...
type UnsafeHealthChecksServer (line 62) | type UnsafeHealthChecksServer interface
function RegisterHealthChecksServer (line 66) | func RegisterHealthChecksServer(s grpc.ServiceRegistrar, srv HealthCheck...
function _HealthChecks_IsAlive_Handler (line 70) | func _HealthChecks_IsAlive_Handler(srv interface{}, ctx context.Context,...
FILE: generated/resources/proto/products/products.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type ListProductOut_Status (line 23) | type ListProductOut_Status
method Enum (line 42) | func (x ListProductOut_Status) Enum() *ListProductOut_Status {
method String (line 48) | func (x ListProductOut_Status) String() string {
method Descriptor (line 52) | func (ListProductOut_Status) Descriptor() protoreflect.EnumDescriptor {
method Type (line 56) | func (ListProductOut_Status) Type() protoreflect.EnumType {
method Number (line 60) | func (x ListProductOut_Status) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 65) | func (ListProductOut_Status) EnumDescriptor() ([]byte, []int) {
constant ListProductOut_OK (line 26) | ListProductOut_OK ListProductOut_Status = 0
constant ListProductOut_NOT_FOUND (line 27) | ListProductOut_NOT_FOUND ListProductOut_Status = 2
type Product (line 69) | type Product struct
method Reset (line 78) | func (x *Product) Reset() {
method String (line 87) | func (x *Product) String() string {
method ProtoMessage (line 91) | func (*Product) ProtoMessage() {}
method ProtoReflect (line 93) | func (x *Product) ProtoReflect() protoreflect.Message {
method Descriptor (line 106) | func (*Product) Descriptor() ([]byte, []int) {
method GetId (line 110) | func (x *Product) GetId() int64 {
method GetName (line 117) | func (x *Product) GetName() string {
type ListProductIn (line 124) | type ListProductIn struct
method Reset (line 132) | func (x *ListProductIn) Reset() {
method String (line 141) | func (x *ListProductIn) String() string {
method ProtoMessage (line 145) | func (*ListProductIn) ProtoMessage() {}
method ProtoReflect (line 147) | func (x *ListProductIn) ProtoReflect() protoreflect.Message {
method Descriptor (line 160) | func (*ListProductIn) Descriptor() ([]byte, []int) {
method GetId (line 164) | func (x *ListProductIn) GetId() int64 {
type ListProductOut (line 171) | type ListProductOut struct
method Reset (line 180) | func (x *ListProductOut) Reset() {
method String (line 189) | func (x *ListProductOut) String() string {
method ProtoMessage (line 193) | func (*ListProductOut) ProtoMessage() {}
method ProtoReflect (line 195) | func (x *ListProductOut) ProtoReflect() protoreflect.Message {
method Descriptor (line 208) | func (*ListProductOut) Descriptor() ([]byte, []int) {
method GetStatus (line 212) | func (x *ListProductOut) GetStatus() ListProductOut_Status {
method GetProducts (line 219) | func (x *ListProductOut) GetProducts() []*Product {
function file_resources_proto_products_products_proto_rawDescGZIP (line 263) | func file_resources_proto_products_products_proto_rawDescGZIP() []byte {
function init (line 290) | func init() { file_resources_proto_products_products_proto_init() }
function file_resources_proto_products_products_proto_init (line 291) | func file_resources_proto_products_products_proto_init() {
FILE: generated/resources/proto/products/products_grpc.pb.go
constant _ (line 15) | _ = grpc.SupportPackageIsVersion7
type ProductsClient (line 20) | type ProductsClient interface
type productsClient (line 24) | type productsClient struct
method ListProduct (line 32) | func (c *productsClient) ListProduct(ctx context.Context, in *ListProd...
function NewProductsClient (line 28) | func NewProductsClient(cc grpc.ClientConnInterface) ProductsClient {
type ProductsServer (line 44) | type ProductsServer interface
type UnimplementedProductsServer (line 50) | type UnimplementedProductsServer struct
method ListProduct (line 53) | func (UnimplementedProductsServer) ListProduct(context.Context, *ListP...
method mustEmbedUnimplementedProductsServer (line 56) | func (UnimplementedProductsServer) mustEmbedUnimplementedProductsServe...
type UnsafeProductsServer (line 61) | type UnsafeProductsServer interface
function RegisterProductsServer (line 65) | func RegisterProductsServer(s grpc.ServiceRegistrar, srv ProductsServer) {
function _Products_ListProduct_Handler (line 69) | func _Products_ListProduct_Handler(srv interface{}, ctx context.Context,...
FILE: main.go
function main (line 5) | func main() {
FILE: resources/migrations/20181215164636-create_users.sql
type users (line 4) | CREATE TABLE users(
type users_email (line 10) | CREATE UNIQUE INDEX users_email ON users USING btree (email)
Condensed preview — 106 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (396K chars).
[
{
"path": ".circleci/config.yml",
"chars": 1899,
"preview": "version: 2.1\njobs:\n test:\n docker:\n - image: cimg/go:1.17\n working_directory: ~/golang-example-app\n steps"
},
{
"path": ".gitignore",
"chars": 328,
"preview": "# Binaries for programs and plugins\n*.exe\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of"
},
{
"path": "Makefile",
"chars": 2392,
"preview": "GO_DIR ?= $(shell pwd)\nGO_PKG ?= $(shell go list -e -f \"{{ .ImportPath }}\")\n\nGOOS ?= $(shell go env GOOS || echo linux)\n"
},
{
"path": "README.md",
"chars": 5466,
"preview": "\n\n# Golang Example Application\n\n# Table of Contents\n\n- [Overview](#overview)\n- [Package l"
},
{
"path": "app/auth/middleware.go",
"chars": 3724,
"preview": "package auth\n\nimport (\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\t\"githu"
},
{
"path": "app/auth/provider.go",
"chars": 655,
"preview": "package auth\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/"
},
{
"path": "app/casbin/provider.go",
"chars": 1002,
"preview": "package casbin\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/casbin/casbin\"\n\tfileadapte"
},
{
"path": "app/common/bcrypt.go",
"chars": 357,
"preview": "package common\n\nimport \"golang.org/x/crypto/bcrypt\"\n\nfunc HashPassword(password string, cost int) (string, error) {\n\tbyt"
},
{
"path": "app/common/constants.go",
"chars": 52,
"preview": "package common\n\nconst (\n\tSrvProducts = \"products\"\n)\n"
},
{
"path": "app/common/graphql.go",
"chars": 586,
"preview": "package common\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/vektah/gqlparser/v2/gqlerror\"\n\n\t\"github.com/9"
},
{
"path": "app/common/jaeger.go",
"chars": 951,
"preview": "package common\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n\t\"go.opentelemetry.io/otel/exporters/jaege"
},
{
"path": "app/config/injector.go",
"chars": 243,
"preview": "// +build wireinject\n\npackage config\n\nimport (\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Build returns s"
},
{
"path": "app/config/provider.go",
"chars": 422,
"preview": "package config\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/google/wire\"\n\t\"github.com/"
},
{
"path": "app/config/wire_gen.go",
"chars": 470,
"preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
},
{
"path": "app/context/context.go",
"chars": 1101,
"preview": "package context\n\nimport (\n\t\"context\"\n\n\t\"github.com/mitchellh/mapstructure\"\n)\n\nconst prefix = \"app.context\"\n\n// Manager\nt"
},
{
"path": "app/dataloader/dataloader.go",
"chars": 1681,
"preview": "//go:generate go run github.com/vektah/dataloaden ProductItemLoader int []*github.com/aristat/golang-example-app/generat"
},
{
"path": "app/dataloader/productitemloader_gen.go",
"chars": 6083,
"preview": "// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.\n\npackage dataloader\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github."
},
{
"path": "app/db/db.go",
"chars": 638,
"preview": "package db\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/jinzhu/gorm\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n"
},
{
"path": "app/db/domain/product.go",
"chars": 107,
"preview": "package domain\n\ntype Product struct {\n\tID int\n\tName string\n\tproductItems []ProductItem\n}\n"
},
{
"path": "app/db/domain/product_item.go",
"chars": 67,
"preview": "package domain\n\ntype ProductItem struct {\n\tID int\n\tName string\n}\n"
},
{
"path": "app/db/domain/user.go",
"chars": 351,
"preview": "package domain\n\ntype User struct {\n\tID int `gorm:\"column:id\"`\n\tEmail string `gorm:\"column:"
},
{
"path": "app/db/injector.go",
"chars": 347,
"preview": "// +build wireinject\n\npackage db\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.com/google/wir"
},
{
"path": "app/db/provider.go",
"chars": 1792,
"preview": "package db\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/jinzhu/gorm\"\n\n\t\"github.com/aristat/golang-example-app/app/"
},
{
"path": "app/db/repo/provider.go",
"chars": 460,
"preview": "package repo\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\t\"github.com/google/wire\"\n)\n\n// Repo for a"
},
{
"path": "app/db/repo/users.go",
"chars": 784,
"preview": "package repo\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\t\"github.com/jinzhu/gorm\"\n)\n\ntype UsersRep"
},
{
"path": "app/db/repo/users_test.go",
"chars": 3509,
"preview": "package repo_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"golang.org/x/crypto/bcrypt\"\n\n\t\"github.com/aristat/golang-example-app"
},
{
"path": "app/db/wire_gen.go",
"chars": 2440,
"preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
},
{
"path": "app/entrypoint/entrypoint.go",
"chars": 1633,
"preview": "package entrypoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\tvi *viper.Viper\n\tmu "
},
{
"path": "app/entrypoint/entrypoint_test.go",
"chars": 404,
"preview": "package entrypoint_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypo"
},
{
"path": "app/entrypoint/provider.go",
"chars": 572,
"preview": "package entrypoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/google/wire\"\n)\n\n// ContextProvider\nfunc Con"
},
{
"path": "app/graphql/graphql.go",
"chars": 2703,
"preview": "package graphql\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/99designs/gqlgen/graphql/han"
},
{
"path": "app/graphql/provider.go",
"chars": 998,
"preview": "package graphql\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\n\t\"github.com/arista"
},
{
"path": "app/graphql_resolver/injector.go",
"chars": 638,
"preview": "// +build wireinject\n\npackage graphql_resolver\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/ar"
},
{
"path": "app/graphql_resolver/mock.go",
"chars": 630,
"preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/"
},
{
"path": "app/graphql_resolver/product.go",
"chars": 2004,
"preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/dataloader\"\n\n\t\"github"
},
{
"path": "app/graphql_resolver/product_test.go",
"chars": 1736,
"preview": "package graphql_resolver_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github."
},
{
"path": "app/graphql_resolver/provider.go",
"chars": 953,
"preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\n\t\"github.com/casbin/casbin\"\n\n\t\"github.com/aristat/golang-example-app/app/"
},
{
"path": "app/graphql_resolver/resolver.go",
"chars": 2070,
"preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/99designs/gqlgen/graphq"
},
{
"path": "app/graphql_resolver/resolver_gen.go",
"chars": 25,
"preview": "package graphql_resolver\n"
},
{
"path": "app/graphql_resolver/user.go",
"chars": 1623,
"preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\tgraphql1 \"github.co"
},
{
"path": "app/graphql_resolver/user_test.go",
"chars": 2192,
"preview": "package graphql_resolver_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/spf13/cast\"\n\n\t\"golang.org/x/crypto/bcrypt\"\n\n"
},
{
"path": "app/graphql_resolver/wire_gen.go",
"chars": 6760,
"preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
},
{
"path": "app/grpc/connection.go",
"chars": 641,
"preview": "package grpc\n\nimport (\n\t\"sync\"\n\n\t\"google.golang.org/grpc\"\n)\n\nvar (\n\tsrvMu sync.Mutex\n\tpoolSrv = map[string]*Pool{}\n)\n\n"
},
{
"path": "app/grpc/manager.go",
"chars": 2033,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"errors\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"go.opentelemetry.io/contrib/inst"
},
{
"path": "app/grpc/pool.go",
"chars": 2169,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\tgrpcpool \"github.com/processout/grpc-go-poo"
},
{
"path": "app/grpc/provider.go",
"chars": 1327,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\n\t\"github.com/aristat/"
},
{
"path": "app/http/http.go",
"chars": 1177,
"preview": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/go-chi/chi/v5\"\n\n\t\"github.com/go-session/session\"\n\n\t\""
},
{
"path": "app/http/injector.go",
"chars": 712,
"preview": "// +build wireinject\n\npackage http\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/auth\"\n\t\"github.com/aristat/gola"
},
{
"path": "app/http/logger.go",
"chars": 701,
"preview": "package http\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/go-chi/chi/"
},
{
"path": "app/http/provider.go",
"chars": 1885,
"preview": "package http\n\nimport (\n\t\"context\"\n\n\t\"github.com/riandyrn/otelchi\"\n\n\t\"github.com/aristat/golang-example-app/app/dataloade"
},
{
"path": "app/http/wire_gen.go",
"chars": 7770,
"preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
},
{
"path": "app/http_routers/products-router/injector.go",
"chars": 369,
"preview": "// +build wireinject\n\npackage products_router\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.c"
},
{
"path": "app/http_routers/products-router/manager.go",
"chars": 726,
"preview": "package products_router\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/gol"
},
{
"path": "app/http_routers/products-router/provider.go",
"chars": 923,
"preview": "package products_router\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/google/wi"
},
{
"path": "app/http_routers/products-router/router.go",
"chars": 2482,
"preview": "package products_router\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/nats-io/stan.go\"\n\n\t\"gith"
},
{
"path": "app/http_routers/products-router/router_test.go",
"chars": 1902,
"preview": "package products_router_test\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"strconv\"\n\t\"stri"
},
{
"path": "app/http_routers/products-router/wire_gen.go",
"chars": 3857,
"preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
},
{
"path": "app/logger/injector.go",
"chars": 523,
"preview": "// +build wireinject\n\npackage logger\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/"
},
{
"path": "app/logger/logger.go",
"chars": 3148,
"preview": "package logger\n\ntype (\n\tFields map[string]interface{}\n)\n\n// Level represent RFC5424 logger severity\ntype Level int8\n\n// "
},
{
"path": "app/logger/middleware.go",
"chars": 2890,
"preview": "package logger\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryClientInterceptor wrapper t"
},
{
"path": "app/logger/mock.go",
"chars": 3089,
"preview": "package logger\n\nimport (\n\t\"context\"\n)\n\n// Entity represent log struct with all assets\ntype Entity struct {\n\tLevel Level"
},
{
"path": "app/logger/provider.go",
"chars": 1290,
"preview": "package logger\n\nimport (\n\t\"context\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// ProviderCfg returns confi"
},
{
"path": "app/logger/wire_gen.go",
"chars": 1423,
"preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
},
{
"path": "app/logger/zap.go",
"chars": 3836,
"preview": "package logger\n\nimport (\n\t\"context\"\n\n\t\"go.uber.org/zap/zapcore\"\n\n\t\"go.uber.org/zap\"\n)\n\n// Zap is uber/zap logger impleme"
},
{
"path": "app/provider/provider.go",
"chars": 753,
"preview": "package provider\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/casbin\"\n\t\"github.com/aristat/golang-example-app/a"
},
{
"path": "app/tracing/jaeger.go",
"chars": 1245,
"preview": "package tracing\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/exporters/jaeger\"\n\t\"go.opentelemetry.io/otel/sdk/resour"
},
{
"path": "app/tracing/provider.go",
"chars": 1094,
"preview": "package tracing\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/sp"
},
{
"path": "cmd/daemon/daemon.go",
"chars": 1794,
"preview": "package daemon\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-a"
},
{
"path": "cmd/health-check-service/health_check_service.go",
"chars": 3104,
"preview": "package health_check_service\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/propaga"
},
{
"path": "cmd/jwt/jwt.go",
"chars": 226,
"preview": "package jwt\n\nimport \"github.com/spf13/cobra\"\n\nvar Cmd = &cobra.Command{\n\tUse: \"jwt\",\n\tShort: \"Tools fo"
},
{
"path": "cmd/jwt/token.go",
"chars": 2410,
"preview": "package jwt\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/spf13/cast\"\n\n\t\"github.com/golang-"
},
{
"path": "cmd/migrate/migrate.go",
"chars": 2236,
"preview": "package migrate\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t_ \"gith"
},
{
"path": "cmd/product-service/nats_service.go",
"chars": 311,
"preview": "package product_service\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/nats-io/stan.go\"\n)\n\nt"
},
{
"path": "cmd/product-service/product_service.go",
"chars": 4803,
"preview": "package product_service\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log\"\n\t\"net\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t"
},
{
"path": "cmd/root.go",
"chars": 2640,
"preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"gith"
},
{
"path": "dbconfig.yml",
"chars": 153,
"preview": "development:\n dialect: postgres\n datasource: dbname=golang_example_development sslmode=disable\n dir: resources/"
},
{
"path": "docker/app/Dockerfile",
"chars": 516,
"preview": "FROM golang:1.17.9-alpine3.15 as builder\n\nRUN apk add --update make \\\n && rm -rf /tmp/* \\\n && rm -rf /var/cache/ap"
},
{
"path": "docker/app/files/docker/bin/entrypoint.sh",
"chars": 35,
"preview": "#!/usr/bin/env sh\n\nexec ./bin \"$@\"\n"
},
{
"path": "docker-compose.yml",
"chars": 2050,
"preview": "version: '3.7'\nservices:\n jaeger:\n image: jaegertracing/all-in-one:latest\n networks:\n - intranet\n ports:\n"
},
{
"path": "generated/graphql/generated.go",
"chars": 99100,
"preview": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage graphql\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n"
},
{
"path": "generated/graphql/models_gen.go",
"chars": 2653,
"preview": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage graphql\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\n\t\"git"
},
{
"path": "generated/resources/proto/health_checks/health_checks.pb.go",
"chars": 8533,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc v3.17.3\n// sou"
},
{
"path": "generated/resources/proto/health_checks/health_checks_grpc.pb.go",
"chars": 3668,
"preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage health_checks\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google."
},
{
"path": "generated/resources/proto/products/products.pb.go",
"chars": 12199,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc v3.17.3\n// sou"
},
{
"path": "generated/resources/proto/products/products_grpc.pb.go",
"chars": 3504,
"preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage products\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golan"
},
{
"path": "go.mod",
"chars": 1703,
"preview": "module github.com/aristat/golang-example-app\n\nrequire (\n\tgithub.com/99designs/gqlgen v0.12.2\n\tgithub.com/agnivade/levens"
},
{
"path": "go.sum",
"chars": 92294,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
},
{
"path": "gqlgen.yml",
"chars": 596,
"preview": "schema:\n - \"resources/graphql/*.graphql\"\n\nexec:\n filename: generated/graphql/generated.go\n\nmodel:\n filename: generate"
},
{
"path": "main.go",
"chars": 97,
"preview": "package main\n\nimport \"github.com/aristat/golang-example-app/cmd\"\n\nfunc main() {\n\tcmd.Execute()\n}\n"
},
{
"path": "prototool.yaml",
"chars": 211,
"preview": "protoc:\n version: 3.8.0\n\ngenerate:\n go_options:\n import_path: github.com/aristat/golang-example-app\n\n plugins:\n "
},
{
"path": "resources/casbin/model.conf",
"chars": 224,
"preview": "[request_definition]\nr = sub, obj, act\n\n[policy_definition]\np = sub, obj, act\n\n[role_definition]\ng = _, _\n\n[policy_effec"
},
{
"path": "resources/casbin/policy.csv",
"chars": 85,
"preview": "p, reader, users, read\np, owner, users, write\n\ng, reader, anonymous\ng, owner, reader\n"
},
{
"path": "resources/configs/development.yaml",
"chars": 957,
"preview": "session:\n redisUrl: localhost:6379\n redisDB: 10\ndb:\n url: postgresql://localhost:5432/golang_example_development?sslm"
},
{
"path": "resources/configs/docker_development.yaml",
"chars": 969,
"preview": "session:\n redisUrl: redis:6379\n redisDB: 10\ndb:\n url: postgres://postgres@postgres:5432/golang_example_development?ss"
},
{
"path": "resources/graphql/products.graphql",
"chars": 236,
"preview": "type ProductsQuery {\n list: ProductsListOut!\n}\n\ntype Product {\n id: ID!\n name: String!\n productItems: [Produ"
},
{
"path": "resources/graphql/root.graphql",
"chars": 109,
"preview": "type Query {\n users: UsersQuery\n products: ProductsQuery\n}\n\ntype Mutation {\n users: UsersMutation\n}\n"
},
{
"path": "resources/graphql/user.graphql",
"chars": 583,
"preview": "type UsersOneOut {\n id: ID!\n email: String!\n}\n\ntype UsersQuery {\n one(email: String!): UsersOneOut! @hasUsersPe"
},
{
"path": "resources/keys/local/private_key.pem",
"chars": 1679,
"preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA0yucnZD57YJ5bPjdZfltW1sObqjT89R6fiHJRkwtA29COZro\nH+I2ZNtXJ6Y5zOuE4DVgeCR"
},
{
"path": "resources/keys/local/public_key.pem",
"chars": 451,
"preview": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0yucnZD57YJ5bPjdZflt\nW1sObqjT89R6fiHJRkwtA29COZro"
},
{
"path": "resources/migrations/20181215164636-create_users.sql",
"chars": 248,
"preview": "\n-- +migrate Up\n\nCREATE TABLE users(\n id SERIAL PRIMARY KEY,\n email VARCHAR(255) NOT NULL DEFAULT '',\n encrypte"
},
{
"path": "resources/migrations/20181216210607-records.sql",
"chars": 245,
"preview": "\n-- +migrate Up\n\n-- password: 123456789\nINSERT INTO users (email, encrypted_password) VALUES ('test@gmail.com', '$2a$10$"
},
{
"path": "resources/proto/health_checks/health_checks.proto",
"chars": 358,
"preview": "syntax = \"proto3\";\n\npackage health_checks;\n\nimport \"google/protobuf/empty.proto\";\n\noption go_package=\"github.com/aristat"
},
{
"path": "resources/proto/products/products.proto",
"chars": 452,
"preview": "syntax = \"proto3\";\n\npackage products;\n\noption go_package=\"github.com/aristat/golang-example-app/products\";\n\nmessage Prod"
},
{
"path": "resources/templates/helpers/errors.html",
"chars": 165,
"preview": "{{ define \"errors\" }}\n {{if .errors }}\n {{range .errors}}\n <h1>\n {{ . }}\n "
},
{
"path": "scripts/docker-compose-start.sh",
"chars": 136,
"preview": "#!/bin/bash\n\ndocker-compose rm\nREMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image\ndo"
},
{
"path": "scripts/remove_docker_containers.sh",
"chars": 324,
"preview": "#!/bin/bash\n\necho \"Start removing containers\"\n\nif [ \"$REMOVE_CONTAINERS\" == ON ]; then\n docker_containers=$(docker ps -"
}
]
About this extraction
This page contains the full source code of the Aristat/golang-example-app GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 106 files (354.4 KB), approximately 132.3k tokens, and a symbol index with 527 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.