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 ```