github.com/HaswinVidanage/gqlgen@v0.8.1-0.20220609041233-69528c1bf712/example/todo/todo.go (about) 1 //go:generate go run ../../testdata/gqlgen.go 2 3 package todo 4 5 import ( 6 "context" 7 "errors" 8 "fmt" 9 "time" 10 11 "github.com/HaswinVidanage/gqlgen/graphql" 12 "github.com/mitchellh/mapstructure" 13 ) 14 15 var you = &User{ID: 1, Name: "You"} 16 var them = &User{ID: 2, Name: "Them"} 17 18 func New() Config { 19 c := Config{ 20 Resolvers: &resolvers{ 21 todos: []Todo{ 22 {ID: 1, Text: "A todo not to forget", Done: false, owner: you}, 23 {ID: 2, Text: "This is the most important", Done: false, owner: you}, 24 {ID: 3, Text: "Somebody else's todo", Done: true, owner: them}, 25 {ID: 4, Text: "Please do this or else", Done: false, owner: you}, 26 }, 27 lastID: 4, 28 }, 29 } 30 c.Directives.HasRole = func(ctx context.Context, obj interface{}, next graphql.Resolver, role Role) (interface{}, error) { 31 switch role { 32 case RoleAdmin: 33 // No admin for you! 34 return nil, nil 35 case RoleOwner: 36 ownable, isOwnable := obj.(Ownable) 37 if !isOwnable { 38 return nil, fmt.Errorf("obj cant be owned") 39 } 40 41 if ownable.Owner().ID != you.ID { 42 return nil, fmt.Errorf("you dont own that") 43 } 44 } 45 46 return next(ctx) 47 } 48 return c 49 } 50 51 type resolvers struct { 52 todos []Todo 53 lastID int 54 } 55 56 func (r *resolvers) MyQuery() MyQueryResolver { 57 return (*QueryResolver)(r) 58 } 59 60 func (r *resolvers) MyMutation() MyMutationResolver { 61 return (*MutationResolver)(r) 62 } 63 64 type QueryResolver resolvers 65 66 func (r *QueryResolver) Todo(ctx context.Context, id int) (*Todo, error) { 67 time.Sleep(220 * time.Millisecond) 68 69 if id == 666 { 70 panic("critical failure") 71 } 72 73 for _, todo := range r.todos { 74 if todo.ID == id { 75 return &todo, nil 76 } 77 } 78 return nil, errors.New("not found") 79 } 80 81 func (r *QueryResolver) LastTodo(ctx context.Context) (*Todo, error) { 82 if len(r.todos) == 0 { 83 return nil, errors.New("not found") 84 } 85 return &r.todos[len(r.todos)-1], nil 86 } 87 88 func (r *QueryResolver) Todos(ctx context.Context) ([]Todo, error) { 89 return r.todos, nil 90 } 91 92 type MutationResolver resolvers 93 94 func (r *MutationResolver) CreateTodo(ctx context.Context, todo TodoInput) (*Todo, error) { 95 newID := r.id() 96 97 newTodo := Todo{ 98 ID: newID, 99 Text: todo.Text, 100 owner: you, 101 } 102 103 if todo.Done != nil { 104 newTodo.Done = *todo.Done 105 } 106 107 r.todos = append(r.todos, newTodo) 108 109 return &newTodo, nil 110 } 111 112 func (r *MutationResolver) UpdateTodo(ctx context.Context, id int, changes map[string]interface{}) (*Todo, error) { 113 var affectedTodo *Todo 114 115 for i := 0; i < len(r.todos); i++ { 116 if r.todos[i].ID == id { 117 affectedTodo = &r.todos[i] 118 break 119 } 120 } 121 122 if affectedTodo == nil { 123 return nil, nil 124 } 125 126 err := mapstructure.Decode(changes, affectedTodo) 127 if err != nil { 128 panic(err) 129 } 130 131 return affectedTodo, nil 132 } 133 134 func (r *MutationResolver) id() int { 135 r.lastID++ 136 return r.lastID 137 }