feature(api): update gqlgen & add complexity limit

This commit is contained in:
Jordan Knott
2020-04-10 21:22:22 -05:00
parent 6b41461a6a
commit e022e7914a
10 changed files with 104 additions and 30 deletions

View File

@ -101,11 +101,11 @@ type ComplexityRoot struct {
}
Task struct {
CreatedAt func(childComplexity int) int
Name func(childComplexity int) int
Position func(childComplexity int) int
TaskGroupID func(childComplexity int) int
TaskID func(childComplexity int) int
CreatedAt func(childComplexity int) int
Name func(childComplexity int) int
Position func(childComplexity int) int
TaskGroup func(childComplexity int) int
TaskID func(childComplexity int) int
}
TaskGroup struct {
@ -164,7 +164,7 @@ type QueryResolver interface {
TaskGroups(ctx context.Context) ([]pg.TaskGroup, error)
}
type TaskResolver interface {
TaskGroupID(ctx context.Context, obj *pg.Task) (string, error)
TaskGroup(ctx context.Context, obj *pg.Task) (*pg.TaskGroup, error)
}
type TaskGroupResolver interface {
ProjectID(ctx context.Context, obj *pg.TaskGroup) (string, error)
@ -505,12 +505,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Task.Position(childComplexity), true
case "Task.taskGroupID":
if e.complexity.Task.TaskGroupID == nil {
case "Task.taskGroup":
if e.complexity.Task.TaskGroup == nil {
break
}
return e.complexity.Task.TaskGroupID(childComplexity), true
return e.complexity.Task.TaskGroup(childComplexity), true
case "Task.taskID":
if e.complexity.Task.TaskID == nil {
@ -740,7 +740,7 @@ type TaskGroup {
type Task {
taskID: ID!
taskGroupID: String!
taskGroup: TaskGroup!
createdAt: Time!
name: String!
position: Float!
@ -2382,7 +2382,7 @@ func (ec *executionContext) _Task_taskID(ctx context.Context, field graphql.Coll
return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res)
}
func (ec *executionContext) _Task_taskGroupID(ctx context.Context, field graphql.CollectedField, obj *pg.Task) (ret graphql.Marshaler) {
func (ec *executionContext) _Task_taskGroup(ctx context.Context, field graphql.CollectedField, obj *pg.Task) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@ -2399,7 +2399,7 @@ func (ec *executionContext) _Task_taskGroupID(ctx context.Context, field graphql
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.Task().TaskGroupID(rctx, obj)
return ec.resolvers.Task().TaskGroup(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
@ -2411,9 +2411,9 @@ func (ec *executionContext) _Task_taskGroupID(ctx context.Context, field graphql
}
return graphql.Null
}
res := resTmp.(string)
res := resTmp.(*pg.TaskGroup)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
return ec.marshalNTaskGroup2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTaskGroup(ctx, field.Selections, res)
}
func (ec *executionContext) _Task_createdAt(ctx context.Context, field graphql.CollectedField, obj *pg.Task) (ret graphql.Marshaler) {
@ -4825,7 +4825,7 @@ func (ec *executionContext) _Task(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "taskGroupID":
case "taskGroup":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
@ -4833,7 +4833,7 @@ func (ec *executionContext) _Task(ctx context.Context, sel ast.SelectionSet, obj
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Task_taskGroupID(ctx, field, obj)
res = ec._Task_taskGroup(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}

View File

@ -2,21 +2,46 @@ package graph
import (
"net/http"
"os"
"time"
"github.com/99designs/gqlgen/handler"
"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"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/jordanknott/project-citadel/api/pg"
)
// NewHandler returns a new graphql endpoint handler.
func NewHandler(repo pg.Repository) http.Handler {
return handler.GraphQL(NewExecutableSchema(Config{
srv := handler.New(NewExecutableSchema(Config{
Resolvers: &Resolver{
Repository: repo,
},
}))
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))
srv.Use(extension.AutomaticPersistedQuery{
Cache: lru.New(100),
})
if isProd := os.Getenv("PRODUCTION") == "true"; isProd {
srv.Use(extension.FixedComplexityLimit(10))
} else {
srv.Use(extension.Introspection{})
}
return srv
}
// NewPlaygroundHandler returns a new GraphQL Playground handler.
func NewPlaygroundHandler(endpoint string) http.Handler {
return handler.Playground("GraphQL Playground", endpoint)
return playground.Handler("GraphQL Playground", endpoint)
}

View File

@ -50,7 +50,7 @@ type TaskGroup {
type Task {
taskID: ID!
taskGroupID: String!
taskGroup: TaskGroup!
createdAt: Time!
name: String!
position: Float!

View File

@ -1,6 +1,7 @@
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.
package graph
import (
"context"
@ -198,8 +199,9 @@ func (r *queryResolver) TaskGroups(ctx context.Context) ([]pg.TaskGroup, error)
return r.Repository.GetAllTaskGroups(ctx)
}
func (r *taskResolver) TaskGroupID(ctx context.Context, obj *pg.Task) (string, error) {
return obj.TaskGroupID.String(), nil
func (r *taskResolver) TaskGroup(ctx context.Context, obj *pg.Task) (*pg.TaskGroup, error) {
taskGroup, err := r.Repository.GetTaskGroupByID(ctx, obj.TaskGroupID)
return &taskGroup, err
}
func (r *taskGroupResolver) ProjectID(ctx context.Context, obj *pg.TaskGroup) (string, error) {
@ -215,13 +217,26 @@ func (r *teamResolver) Projects(ctx context.Context, obj *pg.Team) ([]pg.Project
return r.Repository.GetAllProjectsForTeam(ctx, obj.TeamID)
}
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }
// Mutation returns MutationResolver implementation.
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }
// Organization returns OrganizationResolver implementation.
func (r *Resolver) Organization() OrganizationResolver { return &organizationResolver{r} }
func (r *Resolver) Project() ProjectResolver { return &projectResolver{r} }
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
func (r *Resolver) Task() TaskResolver { return &taskResolver{r} }
func (r *Resolver) TaskGroup() TaskGroupResolver { return &taskGroupResolver{r} }
func (r *Resolver) Team() TeamResolver { return &teamResolver{r} }
// Project returns ProjectResolver implementation.
func (r *Resolver) Project() ProjectResolver { return &projectResolver{r} }
// Query returns QueryResolver implementation.
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
// Task returns TaskResolver implementation.
func (r *Resolver) Task() TaskResolver { return &taskResolver{r} }
// TaskGroup returns TaskGroupResolver implementation.
func (r *Resolver) TaskGroup() TaskGroupResolver { return &taskGroupResolver{r} }
// Team returns TeamResolver implementation.
func (r *Resolver) Team() TeamResolver { return &teamResolver{r} }
type mutationResolver struct{ *Resolver }
type organizationResolver struct{ *Resolver }