github.com/maeglindeveloper/gqlgen@v0.13.1-0.20210413081235-57808b12a0a0/docs/content/reference/apq.md (about)

     1  ---
     2  title: "Automatic persisted queries"
     3  description:
     4  linkTitle: "APQ"
     5  menu: { main: { parent: 'reference', weight: 10 } }
     6  ---
     7  
     8  When you work with GraphQL by default your queries are transferred with every request. That can waste significant
     9  bandwidth. To avoid that you can use Automatic Persisted Queries (APQ).
    10  
    11  With APQ you send only query hash to the server. If hash is not found on a server then client makes a second request
    12  to register query hash with original query on a server.
    13  
    14  ## Usage
    15  
    16  In order to enable Automatic Persisted Queries you need to change your client. For more information see
    17  [Automatic Persisted Queries Link](https://github.com/apollographql/apollo-link-persisted-queries) documentation.
    18  
    19  For the server you need to implement the `graphql.Cache` interface and pass an instance to
    20  the `extension.AutomaticPersistedQuery` type. Make sure the extension is applied to your GraphQL handler.
    21  
    22  See example using [go-redis](https://github.com/go-redis/redis) package below:
    23  ```go
    24  import (
    25  	"context"
    26  	"time"
    27  
    28  	"github.com/99designs/gqlgen/graphql/handler"
    29  	"github.com/99designs/gqlgen/graphql/handler/extension"
    30  	"github.com/99designs/gqlgen/graphql/handler/transport"
    31  	"github.com/go-redis/redis"
    32  )
    33  
    34  type Cache struct {
    35  	client redis.UniversalClient
    36  	ttl    time.Duration
    37  }
    38  
    39  const apqPrefix = "apq:"
    40  
    41  func NewCache(redisAddress string, password string, ttl time.Duration) (*Cache, error) {
    42  	client := redis.NewClient(&redis.Options{
    43  		Addr:     redisAddress,
    44  	})
    45  
    46  	err := client.Ping().Err()
    47  	if err != nil {
    48  		return nil, fmt.Errorf("could not create cache: %w", err)
    49  	}
    50  
    51  	return &Cache{client: client, ttl: ttl}, nil
    52  }
    53  
    54  func (c *Cache) Add(ctx context.Context, key string, value interface{}) {
    55  	c.client.Set(apqPrefix+key, value, c.ttl)
    56  }
    57  
    58  func (c *Cache) Get(ctx context.Context, key string) (interface{}, bool) {
    59  	s, err := c.client.Get(apqPrefix + key).Result()
    60  	if err != nil {
    61  		return struct{}{}, false
    62  	}
    63  	return s, true
    64  }
    65  
    66  func main() {
    67  	cache, err := NewCache(cfg.RedisAddress, 24*time.Hour)
    68  	if err != nil {
    69  		log.Fatalf("cannot create APQ redis cache: %v", err)
    70  	}
    71  
    72  	c := Config{ Resolvers: &resolvers{} }
    73  	gqlHandler := handler.New(
    74  		generated.NewExecutableSchema(c),
    75  	)
    76  	gqlHandler.AddTransport(transport.POST{})
    77  	gqlHandler.Use(extension.AutomaticPersistedQuery{Cache: cache})
    78  	http.Handle("/query", gqlHandler)
    79  }
    80  ```