Convert Figma logo to code with AI

99designs logogqlgen

go generate based graphql server library

9,867
1,147
9,867
326

Top Related Projects

GraphQL server with a focus on ease of use

1,584

⚡️ 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

  1. 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!]!
}
  1. 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
}
  1. 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

  1. Install gqlgen:

    go get github.com/99designs/gqlgen
    
  2. Initialize a new project:

    mkdir myproject && cd myproject
    go mod init myproject
    gqlgen init
    
  3. Define your schema in schema.graphql

  4. Generate code:

    gqlgen generate
    
  5. Implement resolvers in graph/schema.resolvers.go

  6. 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.

1,584

⚡️ 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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

gqlgen

gqlgen Integration Coverage Status Go Report Card Go Reference Read the Docs

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

  1. Initialise a new go module

    mkdir example
    cd example
    go mod init example
    
  2. Add github.com/99designs/gqlgen to your project's tools.go

    printf '//go:build tools\npackage tools\nimport (_ "github.com/99designs/gqlgen"\n _ "github.com/99designs/gqlgen/graphql/introspection")' | gofmt > tools.go
    
    go mod tidy
    
  3. Initialise gqlgen config and generate models

    go run github.com/99designs/gqlgen init
    
    go mod tidy
    
  4. Start the graphql server

    go run server.go
    

More help to get started:

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