Back

Golang Graphql

1. Install a GraphQL Library

go get -u github.com/99designs/gqlgen

2. Generate GraphQL Schema (schema.graphql)

type Query {
  products: [Product!]!
  product(id: ID!): Product
}

type Mutation {
  register(username: String!, password: String!): User!
  login(username: String!, password: String!): AuthPayload!
  createProduct(name: String!, price: Float!): Product! @auth
}

type Product {
  id: ID!
  name: String!
  price: Float!
}

type User {
  id: ID!
  username: String!
}

type AuthPayload {
  token: String!
}

# Add @auth directive to mutations that require authentication
directive @auth on FIELD_DEFINITION

Notes:

  • We define queries for fetching products, mutations for user registration, login, and product creation.
  • The @auth directive is a custom directive we'll define for authorization.

3. Generate GraphQL Code (gqlgen.yml)

schema:
  - schema.graphql
model:
  filename: graph/models.go
resolver:
  filename: graph/resolver.go
  type: Resolver

Run this to generate the core GraphQL code:

gqlgen

4. Implement Resolvers (graph/resolver.go)

package graph

import "go-fiber-api/utils"

// This file will not be regenerated automatically.
//
// It serves as dependency injection for your app, add any dependencies you require here.

type Resolver struct{}

// Mutation resolvers
func (r *Resolver) Mutation() MutationResolver {
    return &mutationResolver{r}
}

// Query resolvers
func (r *Resolver) Query() QueryResolver {
    return &queryResolver{r}
}

type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }

// Example - Modify with actual authentication/product logic
func (r *mutationResolver) CreateProduct(ctx context.Context, name string, price float64) (*models.Product, error) {
    // Authorization check (fetch user ID from JWT in context)
    // ...

    product := &models.Product{
        Name:  name,
        Price: price,
    }

    // Save to database (using utils.db)
    // ...

    return product, nil
}

5. Authorization Directive (graph/directives.go)

package graph

// ...

func (r *Resolver) Directive() DirectiveRoot {
    return &directiveRoot{r}
}

type directiveRoot struct{ *Resolver }

// Auth implements the @auth directive
func (r *directiveRoot) Auth(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) {
    // Extract JWT from context (set in middleware)
    // ... Authorization logic...

    return next(ctx)
}

6. Integrate with Fiber

  • Create a GraphQL handler in main.go.
  • Add a GraphQL endpoint to your Fiber app.