Top Related Projects
GraphQL server with a focus on ease of use
⚡️ A Go framework for rapidly building powerful graphql services
Quick Overview
gqlgen is a Go library for building GraphQL servers. It takes a schema-first approach, automatically generating code based on your GraphQL schema, and provides a flexible and performant runtime for executing GraphQL queries.
Pros
- Schema-first approach, allowing for clear API design
- Automatic code generation, reducing boilerplate and potential errors
- High performance, with support for concurrency and batching
- Extensible plugin system for customizing code generation
Cons
- Learning curve for developers new to GraphQL or code generation
- May require additional setup compared to simpler GraphQL libraries
- Generated code can sometimes be complex or difficult to understand
- Limited control over some aspects of the generated code
Code Examples
- Defining a GraphQL schema:
type User {
id: ID!
name: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type Query {
user(id: ID!): User
posts: [Post!]!
}
- Implementing a resolver:
func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) {
user, err := r.DB.GetUserByID(id)
if err != nil {
return nil, err
}
return user, nil
}
- Using dataloaders for efficient data fetching:
func (r *userResolver) Posts(ctx context.Context, obj *model.User) ([]*model.Post, error) {
return r.PostLoader.Load(ctx, obj.ID)
}
Getting Started
-
Install gqlgen:
go get github.com/99designs/gqlgen
-
Initialize a new project:
mkdir myproject && cd myproject go mod init myproject gqlgen init
-
Define your schema in
schema.graphql
-
Generate code:
gqlgen generate
-
Implement resolvers in
graph/schema.resolvers.go
-
Run your server:
package main import ( "log" "net/http" "myproject/graph" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" ) func main() { srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) http.Handle("/", playground.Handler("GraphQL playground", "/query")) http.Handle("/query", srv) log.Fatal(http.ListenAndServe(":8080", nil)) }
Competitor Comparisons
GraphQL server with a focus on ease of use
Pros of graphql-go
- More lightweight and minimalistic approach
- Easier to integrate into existing Go projects
- Better performance for simpler GraphQL schemas
Cons of graphql-go
- Less feature-rich compared to gqlgen
- Requires more manual implementation of resolvers
- Limited code generation capabilities
Code Comparison
graphql-go:
type query struct{}
func (q *query) Hello() string {
return "Hello, world!"
}
schema := graphql.MustParseSchema(schemaString, &query{})
gqlgen:
type Query struct{}
func (q *Query) Hello(ctx context.Context) string {
return "Hello, world!"
}
// Generated code handles schema parsing and execution
Summary
graphql-go offers a more lightweight approach with better performance for simpler schemas, making it easier to integrate into existing Go projects. However, it requires more manual implementation and has limited code generation capabilities compared to gqlgen.
gqlgen provides a more feature-rich experience with extensive code generation, making it easier to work with complex schemas and reducing boilerplate code. It also offers better type safety and integration with Go's type system.
The choice between the two depends on the project's complexity, performance requirements, and developer preferences. For simpler projects or those requiring fine-grained control, graphql-go might be preferable. For larger, more complex GraphQL APIs, gqlgen's features and code generation capabilities may be more beneficial.
⚡️ A Go framework for rapidly building powerful graphql services
Pros of Thunder
- Simpler API and less boilerplate code required
- Built-in support for real-time subscriptions
- More flexible schema definition approach
Cons of Thunder
- Less mature and smaller community compared to gqlgen
- Fewer features and customization options
- Limited documentation and examples available
Code Comparison
Thunder schema definition:
type User struct {
ID string
Name string
}
func (u *User) FullName() string {
return u.Name
}
gqlgen schema definition:
type User {
id: ID!
name: String!
fullName: String!
}
Thunder resolver:
func (r *Resolver) User(ctx context.Context, args struct{ ID string }) (*User, error) {
return &User{ID: args.ID, Name: "John Doe"}, nil
}
gqlgen resolver:
func (r *queryResolver) User(ctx context.Context, id string) (*User, error) {
return &User{ID: id, Name: "John Doe"}, nil
}
Both Thunder and gqlgen are popular GraphQL server libraries for Go. Thunder offers a simpler API and built-in real-time subscriptions, while gqlgen provides more features and customization options. The choice between them depends on project requirements and developer preferences.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
gqlgen
What is gqlgen?
gqlgen is a Go library for building GraphQL servers without any fuss.
- gqlgen is based on a Schema first approach â You get to Define your API using the GraphQL Schema Definition Language.
- gqlgen prioritizes Type safety â You should never see
map[string]interface{}
here. - gqlgen enables Codegen â We generate the boring bits, so you can focus on building your app quickly.
Still not convinced enough to use gqlgen? Compare gqlgen with other Go graphql implementations
Quick start
-
mkdir example cd example go mod init example
-
Add
github.com/99designs/gqlgen
to your project's tools.goprintf '//go:build tools\npackage tools\nimport (_ "github.com/99designs/gqlgen"\n _ "github.com/99designs/gqlgen/graphql/introspection")' | gofmt > tools.go go mod tidy
-
Initialise gqlgen config and generate models
go run github.com/99designs/gqlgen init go mod tidy
-
Start the graphql server
go run server.go
More help to get started:
- Getting started tutorial - a comprehensive guide to help you get started
- Real-world examples show how to create GraphQL applications
- Reference docs for the APIs
Reporting Issues
If you think you've found a bug, or something isn't behaving the way you think it should, please raise an issue on GitHub.
Contributing
We welcome contributions, Read our Contribution Guidelines to learn more about contributing to gqlgen
Frequently asked questions
How do I prevent fetching child objects that might not be used?
When you have nested or recursive schema like this:
type User {
id: ID!
name: String!
friends: [User!]!
}
You need to tell gqlgen that it should only fetch friends if the user requested it. There are two ways to do this;
-
Using Custom Models
Write a custom model that omits the friends field:
type User struct {
ID int
Name string
}
And reference the model in gqlgen.yml
:
# gqlgen.yml
models:
User:
model: github.com/you/pkg/model.User # go import path to the User struct above
-
Using Explicit Resolvers
If you want to keep using the generated model, mark the field as requiring a resolver explicitly in gqlgen.yml
like this:
# gqlgen.yml
models:
User:
fields:
friends:
resolver: true # force a resolver to be generated
After doing either of the above and running generate we will need to provide a resolver for friends:
func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) {
// select * from user where friendid = obj.ID
return friends, nil
}
You can also use inline config with directives to achieve the same result
directive @goModel(model: String, models: [String!]) on OBJECT
| INPUT_OBJECT
| SCALAR
| ENUM
| INTERFACE
| UNION
directive @goField(forceResolver: Boolean, name: String, omittable: Boolean) on INPUT_FIELD_DEFINITION
| FIELD_DEFINITION
type User @goModel(model: "github.com/you/pkg/model.User") {
id: ID! @goField(name: "todoId")
friends: [User!]! @goField(forceResolver: true)
}
Can I change the type of the ID from type String to Type Int?
Yes! You can by remapping it in config as seen below:
models:
ID: # The GraphQL type ID is backed by
model:
- github.com/99designs/gqlgen/graphql.IntID # a go integer
- github.com/99designs/gqlgen/graphql.ID # or a go string
- github.com/99designs/gqlgen/graphql.UintID # or a go uint
This means gqlgen will be able to automatically bind to strings or ints for models you have written yourself, but the first model in this list is used as the default type and it will always be used when:
- Generating models based on schema
- As arguments in resolvers
There isn't any way around this, gqlgen has no way to know what you want in a given context.
Why do my interfaces have getters? Can I disable these?
These were added in v0.17.14 to allow accessing common interface fields without casting to a concrete type. However, certain fields, like Relay-style Connections, cannot be implemented with simple getters.
If you'd prefer to not have getters generated in your interfaces, you can add the following in your gqlgen.yml
:
# gqlgen.yml
omit_getters: true
Other Resources
Top Related Projects
GraphQL server with a focus on ease of use
⚡️ A Go framework for rapidly building powerful graphql services
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot