github.com/bewolv/gqlgen@v0.10.12/docs/content/recipes/migration-0.11.md (about) 1 --- 2 title: "Migrating to 0.11" 3 description: Using the new graphql/handler package in gqlgen 0.11 4 linkTitle: Migrating to 0.11 5 menu: { main: { parent: 'recipes' } } 6 --- 7 8 The handler package has grown organically for a long time, 0.11 is a large cleanup of the handler package to make it 9 more modular and easier to maintain once we get to 1.0. 10 11 12 ### Transports 13 14 Transports are the first thing that run, they handle decoding the incoming http request, and encoding the graphql 15 response. Supported transports are: 16 17 - GET 18 - JSON POST 19 - Multipart form 20 - Websockets 21 22 new usage looks like this 23 ```go 24 srv := New(es) 25 26 srv.AddTransport(transport.Websocket{ 27 KeepAlivePingInterval: 10 * time.Second, 28 }) 29 srv.AddTransport(transport.Options{}) 30 srv.AddTransport(transport.GET{}) 31 srv.AddTransport(transport.POST{}) 32 srv.AddTransport(transport.MultipartForm{}) 33 ``` 34 35 ### New handler extension API 36 37 The core of this changes the handler package to be a set of composable extensions. The extensions implement a set of optional interfaces: 38 39 - **OperationParameterMutator** runs before creating a OperationContext (formerly RequestContext). allows manipulating the raw query before parsing. 40 - **OperationContextMutator** runs after creating the OperationContext, but before executing the root resolver. 41 - **OperationInterceptor** runs for each incoming query after parsing and validation, for basic requests the writer will be invoked once, for subscriptions it will be invoked multiple times. 42 - **ResponseInterceptor** runs around each graphql operation response. This can be called many times for a single operation the case of subscriptions. 43 - **FieldInterceptor** runs around each field 44 45  46 47 Users of an extension should not need to know which extension points are being used by a given extension, they are added to the server simply by calling `Use(extension)`. 48 49 There are a few convenience methods for defining middleware inline, instead of creating an extension 50 51 ```go 52 srv := handler.New(es) 53 srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { 54 // this function will be called around every field. next() will evaluate the field and return 55 // its computed value. 56 return next(ctx) 57 }) 58 srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { 59 // This function will be called around every operation, next() will return a function that when 60 // called will evaluate one response. Eventually next will return nil, signalling there are no 61 // more results to be returned by the server. 62 return next(ctx) 63 }) 64 srv.AroundResponses(func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { 65 // This function will be called around each response in the operation. next() will evaluate 66 // and return a single response. 67 return next(ctx) 68 }) 69 ``` 70 71 72 Some of the features supported out of the box by handler extensions: 73 74 - APQ 75 - Query Complexity 76 - Error Presenters and Recover Func 77 - Introspection Query support 78 - Query AST cache 79 - Tracing API 80 81 They can be `Use`'d like this: 82 83 ```go 84 srv := handler.New(es) 85 srv.Use(extension.Introspection{}) 86 srv.Use(extension.AutomaticPersistedQuery{ 87 Cache: lru.New(100), 88 }) 89 srv.Use(apollotracing.Tracer{}) 90 ``` 91 92 ### Default server 93 94 We provide a set of default extensions and transports if you aren't ready to customize them yet. Simply: 95 ```go 96 handler.NewDefaultServer(es) 97 ``` 98 99 ### More contesistent naming 100 101 As part of cleaning up the names the RequestContext has been renamed to OperationContext, as there can be multiple created during the lifecycle of a request. A new ResponseContext has also been created and error handling has been moved here. This allows each response in a subscription to have its own errors. I'm not sure what bugs this might have been causing before... 102 103 ### Removal of tracing 104 105 Many of the old interfaces collapse down into just a few extension points: 106 107  108 109 The tracing interface has also been removed, tracing stats are now measured in core (eg time to parse query) and made available on the operation/response contexts. Much of the old interface was designed so that users of a tracer dont need to know which extension points it was listening to, the new handler extensions have the same goal. 110 111 ### Backward compatibility 112 113 There is a backwards compatibility layer that keeps most of the original interface in place. There are a few places where BC is known to be broken: 114 115 - ResponseMiddleware: The signature used to be `func(ctx context.Context, next func(ctx context.Context) []byte) []byte` and is now `func(ctx context.Context) *Response`. We could maintain BC by marshalling to json before and after, but the change is pretty easy to make and is likely to cause less issues. 116 - The Tracer interface has been removed, any tracers will need to be reimplemented against the new extension interface.