Skip to content

A simple library to extract requested fields from a GraphQL request. Supports fragments, aliases and all GraphQL features.

Notifications You must be signed in to change notification settings

gbaptista/requested-fields

Repository files navigation

requested-fields Build Status Maintainability Test Coverage

A simple library to extract requested fields from a GraphQL request. Supports fragments, aliases and all GraphQL features.

Quick Guide

import (
	fields "github.com/gbaptista/requested-fields"
)

Examples of how to use with graphql-go and chi:

Query Tree

Create the query tree and pass it through context:

query := `{ user { name } }`

ctx := context.WithValue(request.Context(),
		fields.ContextKey, fields.BuildTree(query))

Resolvers Field

Include a Field field in all resolvers:

type Query struct {
	Field fields.Field `graphql:"query"`
}

type UserResolver struct {
	Field fields.Field `graphql:"user"`
}

Requested Fields

Always set parent resolver on all resolvers. To access the fields use the fields.RequestedFor function:

func (queryResolver *Query) User(ctx context.Context) *UserResolver {
	userResolver := &UserResolver{}
	userResolver.Field.SetParent(queryResolver)
  
	log.Println(fmt.Sprintf(
		"Query.User Fields: %v", fields.RequestedFor(ctx, userResolver)))

	return userResolver
}

func (userResolver *UserResolver) Address(ctx context.Context) *AddressResolver {
	addressResolver := &AddressResolver{}
	addressResolver.Field.SetParent(userResolver)

	log.Println(fmt.Sprintf(
		"User.Address Fields: %v", fields.RequestedFor(ctx, addressResolver)))

	return addressResolver
}

Accessing Fields on Deeper Levels

fields.RequestedForAt(ctx, queryResolver, "user.address")
fields.RequestedForAt(ctx, userResolver, "address")
fields.RequestedForAt(ctx, userResolver, "address.country")

Custom Names

For resources with different names:

type Article {
  title: String
  author: User
}

Use the SetCustomName function:

func (articleResolver *ArticleResolver) Author(ctx context.Context) *UserResolver {
	authorResolver := &UserResolver{}

	authorResolver.Field.SetCustomName("author")
	authorResolver.Field.SetParent(articleResolver)

	return authorResolver
}

Complete Demo with Real Requests

For a complete use example go to gbaptista/requested-fields-demo.

Known Issues

When aliases for the same resource are used at the same level:

{
  user(id: 3) {
    id
    name
    birthday
  }

  custom_user: user(id: 4) {
    id
    name
    age
  }
}

The requested fields will be the fields of all equal resources at the same level:

[]string{"id", "name", "birthday", "age"}

An alternative to this behavior is to use the BuildTreeUsingAliases function:

BuildTreeUsingAliases

{
  user(id: 3) {
    id
    custom_name: name
    birthday
  }

  custom_user: user(id: 4) {
    id
    name
    age
  }
}

The requested fields will be:

map[string][]string{
    "": []string{"user", "custom_user"},
    "user": []string{"id", "custom_name", "birthday"},
    "custom_user": []string{"id", "name", "age"}}

About

A simple library to extract requested fields from a GraphQL request. Supports fragments, aliases and all GraphQL features.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages