github.com/99designs/gqlgen@v0.17.45/docs/content/recipes/migration-0.11.md (about)

     1  ---
     2  title: "Migrating to 0.11"
     3  description: Changes in gqlgen 0.11
     4  linkTitle: Migrating to 0.11
     5  menu: { main: { parent: 'recipes' } }
     6  ---
     7  
     8  ## Updated gqlparser
     9  
    10  gqlparser had a breaking change, if you have any references to it in your project your going to need to update
    11  them from `github.com/vektah/gqlparser` to `github.com/vektah/gqlparser/v2`.
    12  
    13  ```bash
    14  sed -i 's/github.com\/vektah\/gqlparser/github.com\/vektah\/gqlparser\/v2/' $(find -name '*.go')
    15  ```
    16  
    17  ## Handler Refactor
    18  
    19  The handler package has grown organically for a long time, 0.11 is a large cleanup of the handler package to make it
    20  more modular and easier to maintain once we get to 1.0.
    21  
    22  
    23  ### Transports
    24  
    25  Transports are the first thing that run, they handle decoding the incoming http request, and encoding the graphql
    26  response. Supported transports are:
    27  
    28   - GET
    29   - JSON POST
    30   - Multipart form
    31   - UrlEncoded form
    32   - GRAPHQL
    33   - Websockets
    34  
    35  new usage looks like this
    36  ```go
    37  srv := New(es)
    38  
    39  srv.AddTransport(transport.Websocket{
    40  	KeepAlivePingInterval: 10 * time.Second,
    41  })
    42  srv.AddTransport(transport.Options{})
    43  srv.AddTransport(transport.GET{})
    44  srv.AddTransport(transport.POST{})
    45  srv.AddTransport(transport.MultipartForm{})
    46  srv.AddTransport(transport.UrlEncodedForm{})
    47  srv.AddTransport(transport.GRAPHQL{})
    48  ```
    49  
    50  ### New handler extension API
    51  
    52  The core of this changes the handler package to be a set of composable extensions. The extensions implement a set of optional interfaces:
    53  
    54   - **OperationParameterMutator** runs before creating a OperationContext (formerly RequestContext). allows manipulating the raw query before parsing.
    55   - **OperationContextMutator** runs after creating the OperationContext, but before executing the root resolver.
    56   - **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.
    57   - **ResponseInterceptor** runs around each graphql operation response. This can be called many times for a single operation the case of subscriptions.
    58   - **FieldInterceptor** runs around each field
    59  
    60  ![Anatomy of a request@2x](https://user-images.githubusercontent.com/2247982/68181515-c8a27c00-ffeb-11e9-86f6-1673e7179ecb.png)
    61  
    62  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)`.
    63  
    64  There are a few convenience methods for defining middleware inline, instead of creating an extension
    65  
    66  ```go
    67  srv := handler.New(es)
    68  srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) {
    69  	// this function will be called around every field. next() will evaluate the field and return
    70  	// its computed value.
    71  	return next(ctx)
    72  })
    73  srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
    74  	// This function will be called around every operation, next() will return a function that when
    75  	// called will evaluate one response. Eventually next will return nil, signalling there are no
    76  	// more results to be returned by the server.
    77  	return next(ctx)
    78  })
    79  srv.AroundResponses(func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
    80  	// This function will be called around each response in the operation. next() will evaluate
    81  	// and return a single response.
    82  	return next(ctx)
    83  })
    84  ```
    85  
    86  
    87  Some of the features supported out of the box by handler extensions:
    88  
    89   - APQ
    90   - Query Complexity
    91   - Error Presenters and Recover Func
    92   - Introspection Query support
    93   - Query AST cache
    94   - Tracing API
    95  
    96  They can be `Use`'d like this:
    97  
    98  ```go
    99  srv := handler.New(es)
   100  srv.Use(extension.Introspection{})
   101  srv.Use(extension.AutomaticPersistedQuery{
   102  	Cache: lru.New(100),
   103  })
   104  srv.Use(apollotracing.Tracer{})
   105  ```
   106  
   107  ### Default server
   108  
   109  We provide a set of default extensions and transports if you aren't ready to customize them yet. Simply:
   110  ```go
   111  handler.NewDefaultServer(es)
   112  ```
   113  
   114  ### More consistent naming
   115  
   116  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...
   117  
   118  ### Removal of tracing
   119  
   120  Many of the old interfaces collapse down into just a few extension points:
   121  
   122  ![Anatomy of a request](/request_anatomy.png)
   123  
   124  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 don't need to know which extension points it was listening to, the new handler extensions have the same goal.
   125  
   126  ### Backward compatibility
   127  
   128  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:
   129  
   130   - 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.
   131   - The Tracer interface has been removed, any tracers will need to be reimplemented against the new extension interface.
   132  
   133  ## New resolver layout
   134  
   135  0.11 also added a new way to generate and layout resolvers on disk. We used to only generate resolver implementations
   136  whenever the file didnt exist. This behaviour is still there for those that are already used to it, However there is a
   137  new mode you can turn on in config:
   138  
   139  ```yaml
   140  resolver:
   141    layout: follow-schema
   142    dir: graph
   143  ```
   144  
   145  This tells gqlgen to generate resolvers next to the schema file that declared the graphql field, which looks like this:
   146  
   147  ![follow-schema layout](/schema_layout.png)