some cleanup and gqlgen setup

This commit is contained in:
2024-11-01 19:55:30 +05:30
parent e41d27cf97
commit 1fb2d7d154
39 changed files with 5619 additions and 144 deletions

4
graph/auth.graphql Normal file
View File

@@ -0,0 +1,4 @@
extend type Mutation {
login(username: String!, email: String!): Boolean!
logout: Boolean!
}

20
graph/auth.resolvers.go Normal file
View File

@@ -0,0 +1,20 @@
package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.55
import (
"context"
"fmt"
)
// Login is the resolver for the login field.
func (r *mutationResolver) Login(ctx context.Context, username string, email string) (bool, error) {
panic(fmt.Errorf("not implemented: Login - login"))
}
// Logout is the resolver for the logout field.
func (r *mutationResolver) Logout(ctx context.Context) (bool, error) {
panic(fmt.Errorf("not implemented: Logout - logout"))
}

View File

@@ -0,0 +1,519 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package generated
import (
"context"
"errors"
"fmt"
"strconv"
"sync/atomic"
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection"
"github.com/vektah/gqlparser/v2/ast"
)
// region ************************** generated!.gotpl **************************
type MutationResolver interface {
Login(ctx context.Context, username string, email string) (bool, error)
Logout(ctx context.Context) (bool, error)
}
type QueryResolver interface {
HeartBeat(ctx context.Context) (bool, error)
}
// endregion ************************** generated!.gotpl **************************
// region ***************************** args.gotpl *****************************
func (ec *executionContext) field_Mutation_login_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
arg0, err := ec.field_Mutation_login_argsUsername(ctx, rawArgs)
if err != nil {
return nil, err
}
args["username"] = arg0
arg1, err := ec.field_Mutation_login_argsEmail(ctx, rawArgs)
if err != nil {
return nil, err
}
args["email"] = arg1
return args, nil
}
func (ec *executionContext) field_Mutation_login_argsUsername(
ctx context.Context,
rawArgs map[string]interface{},
) (string, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("username"))
if tmp, ok := rawArgs["username"]; ok {
return ec.unmarshalNString2string(ctx, tmp)
}
var zeroVal string
return zeroVal, nil
}
func (ec *executionContext) field_Mutation_login_argsEmail(
ctx context.Context,
rawArgs map[string]interface{},
) (string, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
if tmp, ok := rawArgs["email"]; ok {
return ec.unmarshalNString2string(ctx, tmp)
}
var zeroVal string
return zeroVal, 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{}{}
arg0, err := ec.field_Query___type_argsName(ctx, rawArgs)
if err != nil {
return nil, err
}
args["name"] = arg0
return args, nil
}
func (ec *executionContext) field_Query___type_argsName(
ctx context.Context,
rawArgs map[string]interface{},
) (string, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
if tmp, ok := rawArgs["name"]; ok {
return ec.unmarshalNString2string(ctx, tmp)
}
var zeroVal string
return zeroVal, nil
}
// endregion ***************************** args.gotpl *****************************
// region ************************** directives.gotpl **************************
// endregion ************************** directives.gotpl **************************
// region **************************** field.gotpl *****************************
func (ec *executionContext) _Mutation_login(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_login(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().Login(rctx, fc.Args["username"].(string), fc.Args["email"].(string))
})
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) fieldContext_Mutation_login(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Mutation_login_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
func (ec *executionContext) _Mutation_logout(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_logout(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().Logout(rctx)
})
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) fieldContext_Mutation_logout(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Query_heartBeat(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query_heartBeat(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().HeartBeat(rctx)
})
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) fieldContext_Query_heartBeat(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query___type(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.introspectType(fc.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) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "kind":
return ec.fieldContext___Type_kind(ctx, field)
case "name":
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
return ec.fieldContext___Type_interfaces(ctx, field)
case "possibleTypes":
return ec.fieldContext___Type_possibleTypes(ctx, field)
case "enumValues":
return ec.fieldContext___Type_enumValues(ctx, field)
case "inputFields":
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
case "specifiedByURL":
return ec.fieldContext___Type_specifiedByURL(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query___schema(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
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) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "description":
return ec.fieldContext___Schema_description(ctx, field)
case "types":
return ec.fieldContext___Schema_types(ctx, field)
case "queryType":
return ec.fieldContext___Schema_queryType(ctx, field)
case "mutationType":
return ec.fieldContext___Schema_mutationType(ctx, field)
case "subscriptionType":
return ec.fieldContext___Schema_subscriptionType(ctx, field)
case "directives":
return ec.fieldContext___Schema_directives(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name)
},
}
return fc, nil
}
// endregion **************************** field.gotpl *****************************
// region **************************** input.gotpl *****************************
// endregion **************************** input.gotpl *****************************
// region ************************** interface.gotpl ***************************
// endregion ************************** interface.gotpl ***************************
// region **************************** object.gotpl ****************************
var mutationImplementors = []string{"Mutation"}
func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors)
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
Object: "Mutation",
})
out := graphql.NewFieldSet(fields)
deferred := make(map[string]*graphql.FieldSet)
for i, field := range fields {
innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
Object: field.Name,
Field: field,
})
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("Mutation")
case "login":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_login(ctx, field)
})
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "logout":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_logout(ctx, field)
})
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch(ctx)
if out.Invalids > 0 {
return graphql.Null
}
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
for label, dfs := range deferred {
ec.processDeferredGroup(graphql.DeferredGroup{
Label: label,
Path: graphql.GetPath(ctx),
FieldSet: dfs,
Context: ctx,
})
}
return out
}
var queryImplementors = []string{"Query"}
func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors)
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
Object: "Query",
})
out := graphql.NewFieldSet(fields)
deferred := make(map[string]*graphql.FieldSet)
for i, field := range fields {
innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
Object: field.Name,
Field: field,
})
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("Query")
case "heartBeat":
field := field
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_heartBeat(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&fs.Invalids, 1)
}
return res
}
rrm := func(ctx context.Context) graphql.Marshaler {
return ec.OperationContext.RootResolverMiddleware(ctx,
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
case "__type":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Query___type(ctx, field)
})
case "__schema":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Query___schema(ctx, field)
})
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch(ctx)
if out.Invalids > 0 {
return graphql.Null
}
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
for label, dfs := range deferred {
ec.processDeferredGroup(graphql.DeferredGroup{
Label: label,
Path: graphql.GetPath(ctx),
FieldSet: dfs,
Context: ctx,
})
}
return out
}
// endregion **************************** object.gotpl ****************************
// region ***************************** type.gotpl *****************************
// endregion ***************************** type.gotpl *****************************

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,261 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package generated
import (
"bytes"
"context"
"errors"
"sync/atomic"
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection"
gqlparser "github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
)
// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
return &executableSchema{
schema: cfg.Schema,
resolvers: cfg.Resolvers,
directives: cfg.Directives,
complexity: cfg.Complexity,
}
}
type Config struct {
Schema *ast.Schema
Resolvers ResolverRoot
Directives DirectiveRoot
Complexity ComplexityRoot
}
type ResolverRoot interface {
Mutation() MutationResolver
Query() QueryResolver
}
type DirectiveRoot struct {
}
type ComplexityRoot struct {
Mutation struct {
Login func(childComplexity int, username string, email string) int
Logout func(childComplexity int) int
}
Query struct {
HeartBeat func(childComplexity int) int
}
}
type executableSchema struct {
schema *ast.Schema
resolvers ResolverRoot
directives DirectiveRoot
complexity ComplexityRoot
}
func (e *executableSchema) Schema() *ast.Schema {
if e.schema != nil {
return e.schema
}
return parsedSchema
}
func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
ec := executionContext{nil, e, 0, 0, nil}
_ = ec
switch typeName + "." + field {
case "Mutation.login":
if e.complexity.Mutation.Login == nil {
break
}
args, err := ec.field_Mutation_login_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.Login(childComplexity, args["username"].(string), args["email"].(string)), true
case "Mutation.logout":
if e.complexity.Mutation.Logout == nil {
break
}
return e.complexity.Mutation.Logout(childComplexity), true
case "Query.heartBeat":
if e.complexity.Query.HeartBeat == nil {
break
}
return e.complexity.Query.HeartBeat(childComplexity), true
}
return 0, false
}
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
rc := graphql.GetOperationContext(ctx)
ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)}
inputUnmarshalMap := graphql.BuildUnmarshalerMap()
first := true
switch rc.Operation.Operation {
case ast.Query:
return func(ctx context.Context) *graphql.Response {
var response graphql.Response
var data graphql.Marshaler
if first {
first = false
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
data = ec._Query(ctx, rc.Operation.SelectionSet)
} else {
if atomic.LoadInt32(&ec.pendingDeferred) > 0 {
result := <-ec.deferredResults
atomic.AddInt32(&ec.pendingDeferred, -1)
data = result.Result
response.Path = result.Path
response.Label = result.Label
response.Errors = result.Errors
} else {
return nil
}
}
var buf bytes.Buffer
data.MarshalGQL(&buf)
response.Data = buf.Bytes()
if atomic.LoadInt32(&ec.deferred) > 0 {
hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0
response.HasNext = &hasNext
}
return &response
}
case ast.Mutation:
return func(ctx context.Context) *graphql.Response {
if !first {
return nil
}
first = false
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
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
deferred int32
pendingDeferred int32
deferredResults chan graphql.DeferredResult
}
func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) {
atomic.AddInt32(&ec.pendingDeferred, 1)
go func() {
ctx := graphql.WithFreshResponseContext(dg.Context)
dg.FieldSet.Dispatch(ctx)
ds := graphql.DeferredResult{
Path: dg.Path,
Label: dg.Label,
Result: dg.FieldSet,
Errors: graphql.GetErrors(ctx),
}
// null fields should bubble up
if dg.FieldSet.Invalids > 0 {
ds.Result = graphql.Null
}
ec.deferredResults <- ds
}()
}
func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
if ec.DisableIntrospection {
return nil, errors.New("introspection disabled")
}
return introspection.WrapSchema(ec.Schema()), nil
}
func (ec *executionContext) introspectType(name string) (*introspection.Type, error) {
if ec.DisableIntrospection {
return nil, errors.New("introspection disabled")
}
return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil
}
var sources = []*ast.Source{
{Name: "../auth.graphql", Input: `extend type Mutation {
login(username: String!, email: String!): Boolean!
logout: Boolean!
}
`, BuiltIn: false},
{Name: "../index.graphql", Input: `# GraphQL schema example
#
# https://gqlgen.com/getting-started/
type Mutation
type Query {
heartBeat: Boolean!
}
"""
Maps a Time GraphQL scalar to a Go time.Time struct.
"""
scalar Time
"""
type Map(Go type: map[string]interface{})
"""
scalar Map
"""
Go type interface{}
"""
scalar Any
scalar Void
"""
directive to map Go type
type User @goModel(model: "github.com/my/app/models.User") {
id: ID! @goField(name: "todoId")
name: String!
@goField(forceResolver: true)
@goTag(key: "xorm", value: "-")
@goTag(key: "yaml")
}
"""
directive @goModel(
model: String
models: [String!]
forceGenerate: Boolean
) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION
"""
directive to map Go type
"""
directive @goField(
forceResolver: Boolean
name: String
omittable: Boolean
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
directive @goTag(key: String!, value: String) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
`, BuiltIn: false},
}
var parsedSchema = gqlparser.MustLoadSchema(sources...)

52
graph/index.graphql Normal file
View File

@@ -0,0 +1,52 @@
# GraphQL schema example
#
# https://gqlgen.com/getting-started/
type Mutation
type Query {
heartBeat: Boolean!
}
"""
Maps a Time GraphQL scalar to a Go time.Time struct.
"""
scalar Time
"""
type Map(Go type: map[string]interface{})
"""
scalar Map
"""
Go type interface{}
"""
scalar Any
scalar Void
"""
directive to map Go type
type User @goModel(model: "github.com/my/app/models.User") {
id: ID! @goField(name: "todoId")
name: String!
@goField(forceResolver: true)
@goTag(key: "xorm", value: "-")
@goTag(key: "yaml")
}
"""
directive @goModel(
model: String
models: [String!]
forceGenerate: Boolean
) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION
"""
directive to map Go type
"""
directive @goField(
forceResolver: Boolean
name: String
omittable: Boolean
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
directive @goTag(key: String!, value: String) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION

28
graph/index.resolvers.go Normal file
View File

@@ -0,0 +1,28 @@
package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.55
import (
"context"
graph "gitserver.in/patialtech/rano/graph/generated"
)
// HeartBeat is the resolver for the heartBeat field.
func (r *queryResolver) HeartBeat(ctx context.Context) (bool, error) {
// do needful checkup
//
return true, nil
}
// Mutation returns graph.MutationResolver implementation.
func (r *Resolver) Mutation() graph.MutationResolver { return &mutationResolver{r} }
// Query returns graph.QueryResolver implementation.
func (r *Resolver) Query() graph.QueryResolver { return &queryResolver{r} }
type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }

1
graph/model/model.go Normal file
View File

@@ -0,0 +1 @@
package model

View File

@@ -0,0 +1,9 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package model
type Mutation struct {
}
type Query struct {
}

152
graph/resolver.go Normal file
View File

@@ -0,0 +1,152 @@
//go:generate go run github.com/99designs/gqlgen generate
package graph
import (
"context"
"log/slog"
"net/http"
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/vektah/gqlparser/gqlerror"
"gitserver.in/patialtech/rano/graph/generated"
"gitserver.in/patialtech/rano/pkg/logger"
)
// This file will not be regenerated automatically.
//
// It serves as dependency injection for your app, add any dependencies you require here.
type Resolver struct{}
var srv *handler.Server
func init() {
srv = handler.NewDefaultServer(schema())
// limit query complexity
srv.Use(extension.FixedComplexityLimit(90))
// recover
srv.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
oc := graphql.GetOperationContext(ctx)
// TODO: sanitize oc.RawQuery
logger.Error(err.(error), slog.String("gqlQuery", oc.RawQuery))
return gqlerror.Errorf("Internal server error!")
})
}
// schema creates a graphql executable schema.
func schema() graphql.ExecutableSchema {
c := generated.Config{
Resolvers: &Resolver{},
}
// c.Directives.Authorize = func(ctx context.Context, obj interface{}, next graphql.Resolver, groups []*permission.Group) (res interface{}, err error) {
// // get session user
// user := account.CtxUser(ctx)
// if user == nil {
// // session user isn't found
// return nil, errors.New("401 Unauthorized")
// }
// // has roles count more than 0
// if len(groups) == 0 { // we just want to authorize, no need to check has a role
// return next(ctx)
// }
// // user is in desired role
// for _, g := range groups {
// if g == nil {
// continue
// }
// // Role Check
// switch *g {
// case permission.GroupRFXAdmin,
// permission.GroupDealerAdmin,
// permission.GroupInstallerAdmin,
// permission.GroupIntegratorAdmin:
// if enum.RoleAdmin != user.Role {
// continue
// }
// case permission.GroupRFXUser,
// permission.GroupDealerUser,
// permission.GroupInstallerUser,
// permission.GroupIntegratorUser:
// if enum.RoleSiteUser != user.Role {
// continue
// }
// default:
// continue
// }
// // ORG must be present
// if user.Partner == nil {
// continue
// }
// // ORG Type Check
// switch *g {
// case permission.GroupRFXAdmin, permission.GroupRFXUser:
// if enum.PartnerRFX == user.Partner.Type {
// return next(ctx)
// }
// case permission.GroupDealerAdmin, permission.GroupDealerUser:
// if enum.PartnerDealer == user.Partner.Type {
// return next(ctx)
// }
// case permission.GroupInstallerAdmin, permission.GroupInstallerUser:
// if enum.PartnerInstaller == user.Partner.Type {
// return next(ctx)
// }
// case permission.GroupIntegratorAdmin, permission.GroupIntegratorUser:
// if enum.PartnerIntegrator == user.Partner.Type {
// return next(ctx)
// }
// }
// }
// // failed, user is not authorized to go next
// return nil, msg.NewError(msg.NotAuthorized)
// }
// c.Directives.FieldFor = func(
// ctx context.Context, obj interface{}, next graphql.Resolver, roles []*enum.Role, defaultVal interface{},
// ) (res interface{}, err error) {
// // get session user
// user := account.CtxUser(ctx)
// if user == nil { // return empty if user info not found
// return "", nil
// }
// // check user has a role allowed for current operation
// for _, role := range roles {
// if role != nil && user.Role == *role {
// // on match just call next
// return next(ctx)
// }
// }
// return defaultVal, nil
// }
return generated.NewExecutableSchema(c)
}
// GraphiQL route handler
func GraphiQL(queryEndpoint string) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
h := playground.Handler("GraphQL", queryEndpoint)
h.ServeHTTP(w, r)
}
}
// Query graph
func Query(w http.ResponseWriter, r *http.Request) {
// srv.ServeHTTP(w, r.WithContext(userCtx(r)))
srv.ServeHTTP(w, r)
}

34
graph/server/main.go Normal file
View File

@@ -0,0 +1,34 @@
package main
import (
"net/http"
"os"
"gitserver.in/patialtech/mux"
"gitserver.in/patialtech/rano/graph"
"gitserver.in/patialtech/rano/pkg/logger"
)
func main() {
r := mux.NewRouter()
// graphiql
r.Get("/graphiql", graph.GraphiQL("/query"))
// graph query
r.Post("/query", graph.Query)
// catch all
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello there"))
})
port := os.Getenv("GRAPH_PORT")
if port == "" {
port = "4001"
}
r.Serve(func(srv *http.Server) error {
srv.Addr = ":" + port
logger.Info("graph server listening on %s", srv.Addr)
return srv.ListenAndServe()
})
}