A GraphQL, RESTful server with Golang, gorm, gqlgen, go-playground/validator. Implement PubSub by github.com/moby/moby/pkg/pubsub created by Docker.
Copy .env.example
to .env
and .env.dev
# create tables
make migrate
# create GraphQL file
make build_graphql
# build server
make build
# start server
.build/gin_graphql
- GraphQL Playground: http://localhost:5566/graphql
- GraphQL Query: http://localhost:5566/graphql/query
https://gqlgen.com/ You could initialize a new project using the recommended folder structure by running this command
go run github.com/99designs/gqlgen init
├── go.mod
├── go.sum
├── gqlgen.yml - The gqlgen config file, knobs for controlling the generated code.
├── graph
│ ├── generated - A package that only contains the generated runtime
│ │ └── generated.go - DO NOT EDIT !
│ ├── model - A package for all your graph models, generated or otherwise
│ │ └── models_gen.go - DO NOT EDIT !
│ ├── resolver.go - The root graph resolver type. This file wont get regenerated
│ ├── schema.graphqls - Some schema. You can split the schema into as many graphql files as you like
│ └── schema.resolvers.go - the resolver implementation for schema.graphql
└── server.go - The entry point to your app. Customize it however you see fit
At the top of our resolver.go, between package and import, add the following line:
//go:generate go run github.com/99designs/gqlgen
This magic comment tells go generate what command to run when we want to regenerate our code.
To run go generate recursively over your entire project, use this command:go generate ./...
Path: graph/schema.graphqls
.
type Mutation {
deleteMeetUp(id: ID!): Boolean! @hasRole(role: ADMIN) @isAuthenticated
}
directive @isAuthenticated on FIELD_DEFINITION
directive @hasRole(role: Role!) on FIELD_DEFINITION
Path: graph/directives/directiveAuth.go
func IsAuthenticated(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) {
ctxUserID := ctx.Value(CurrentUserKey)
if ctxUserID == nil {
return nil, graph.ErrUnauthenticated
}
return next(ctx)
}
Path: main.go
c := generated.Config{Resolvers: &graph.Resolver{}}
// Schema Directive
c.Directives.IsAuthenticated = directives.IsAuthenticated
c.Directives.HasRole = directives.HasRole
srv := handler.NewDefaultServer(generated.NewExecutableSchema(c))
return func(c *gin.Context) {
srv.ServeHTTP(c.Writer, c.Request)
}
- modify your schema
graph/schema.graphqls
- run gqlgen
./script/gqlgen.sh
orgo run -v github.com/99designs/gqlgen
- modify resolvers
graph/resolver.go
make migrate mode={auto | drop | refresh}
or go run database/migrate.go -m=auto
http://localhost:5566/swagger/index.html
swag init
[GIN-debug] GET /admin/pprof/ --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/cmdline --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/profile --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] POST /admin/pprof/symbol --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/symbol --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/trace --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/allocs --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/block --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/goroutine --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/heap --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/mutex --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
[GIN-debug] GET /admin/pprof/threadcreate --> github.com/gin-contrib/pprof.pprofHandler.func1 (4 handlers)
# Initiation Go project
go mod init
go mod tidy
# download Go package
go mod download
graph/prelude.resolvers.go:19:34: cannot refer to unexported name generated.__DirectiveResolver
- rollback the version of gqlparser from github.com/vektah/gqlparser/v2 v2.2.0 to github.com/vektah/gqlparser/v2 v2.1.0
go mod edit -require github.com/vektah/gqlparser/v2@v2.1.0 go clean -i github.com/vektah/gqlparser/v2 go get github.com/vektah/gqlparser/v2@v2.1.0