Migrating from v2
to v3
With new major version comes breaking changes. This
section will guide you through the process of migrating from v2
to v3
.
1. Remove graphql
as a peer dependency
We have designed the new envelop
to be engine agnostic. This means that graphql
is no longer a
peer dependency. You still want to use graphql-js
but you can easily use any GraphQL Engine since
envelop
now simply wraps the parse
, validate
, execute
and subscribe
functions that you
provide.
- import { envelop } from '@envelop/core';
+ import { envelop, useEngine } from '@envelop/core';
+ import * as GraphQLJS from 'graphql'
- const getEnveloped = envelop([ ... ])
+ const getEnveloped = envelop({ plugins: [ useEngine(GraphQLJS), ... ] })
2. Removed orchestrator tracing
GraphQLSchema
was wrapped to provide resolvers/fields tracing from the schema. Issue with this
approach was it was very specific to the underlying engine’s implementation. With the new version we
no longer want to depend to a specific implementation. Now users can wrap their schemas and add
tracing themselves.
1. Removed onResolverCalled
We decided to drop onResolverCalled
hook and instead
provide a new plugin that will let you hook into this
phase.
import { parse, validate, specifiedRules,execute, subscribe } from 'graphql'
import { envelop, Plugin, useEngine } from '@envelop/core'
+ import { useOnResolve } from '@envelop/on-resolve'
import { onResolverCalled } from './my-resolver'
function useResolve(): Plugin {
return {
- onResolverCalled: onResolverCalled,
+ onPluginInit: ({ addPlugin }) => {
+ addPlugin(useOnResolve(onResolverCalled))
+ },
}
}
const getEnveloped = envelop({
plugins: [
useEngine({ parse, validate,specifiedRules, execute, subscribe }),
// ... other plugins ...
useResolve(),
],
});
2. Drop useTiming
plugin
This plugin was dependent on tracing the schema. As we no longer support wrap the schema out of the box we decided to drop this plugin.
At this moment we do not have any alternative. We recommend using a tracing solution.
3. Remove EnvelopError
To keep the core agnostic from a specific implementation we no longer provide the EnvelopError
class. To ensure an error is GraphQLError
envelop check if it an instanceOf Error
and the name
of error is GraphQLError
. We provide a helper utility isGraphQLError
to check if an error is a
GraphQLError
.
- import {EnvelopError} from '@envelop/core'
+ import { GraphQLError } from 'graphql'
const main () => {
try {
// ...
} catch (error) {
- throw EnvelopError(error)
+ throw GraphQLError(error)
}
}
1.@envelop/sentry
default will skip all GraphQLError
Since we no longer support EnvelopError
it will skip sending any errors to sentry that are
GraphQLError
.
4. Remove isIntrospectionDocument
and isIntrospectionQuery
utility
To keep core agnostic we recommend you create your own utility for this.
5. Remove useAsyncSchema
plugin
This was a mistake from beginning as we cannot asynchronously validate
and parse
since with
graphql
these functions are synchronous in nature.
You should first load your schema and then create the envelop instance and pass the schema to it.
import * as GraphQLJS from 'graphql'
import { envelop, useEngine, useSchema } from '@envelop/core'
// This assumes you are using Node v14.8+ where top-level await is supported
const schema = await loadSchema()
const getEnveloped = envelop({
plugins: [useEngine(GraphQLJS), useSchema(schema)]
})
6. Rename useLazyLoadedSchema
to useSchemaByContext
Original name was very misleading since lazy loading could mean it can be asynchronous in nature.
This plugin was renamed to better reflect its purpose. It is now called useSchemaByContext
7. Drop enableIf
utility
This utility was used to enable plugins conditionally. For a better developer experience we have dropped this utility and favor more type safe way to conditionally enable plugins.
- import { envelop, useMaskedErrors, enableIf } from '@envelop/core'
+ import { envelop, useMaskedErrors, useEngine } from '@envelop/core'
import * as GraphQLJS from 'graphql'
const isProd = process.env.NODE_ENV === 'production'
const getEnveloped = envelop({
plugins: [
useEngine(GraphQLJS),
// This plugin is enabled only in production
- enableIf(isProd, useMaskedErrors())
+ isProd && useMaskedErrors()
]
})
8. Update options for useMaskedErrors
plugin
- We removed
handleValidationErrors
andhandleParseErrors
options since ONLY masking validation errors OR ONLY disabling introspection errors does not make sense, as both can be abused for reverse-engineering the GraphQL schema (see https://github.com/nikitastupin/clairvoyance for reverse-engineering the schema based on validation error suggestions). Instead you should useuseErrorHandler
plugin where you can access each phase and decide what to do with the error. - Renamed
formatError
tomaskError
import { envelop, useMaskedErrors, useEngine, isGraphQLError } from '@envelop/core'
import * as GraphQLJS from 'graphql'
export const customFormatError: MaskError = err => {
if (isGraphQLError(err)) {
return new GraphQLError('Sorry, something went wrong.')
}
return err
}
const getEnveloped = envelop({
plugins: [
useEngine(GraphQLJS),
- useMaskedErrors({ formatError: customFormatError })
+ useMaskedErrors({ maskError: customFormatError })
]
})
9. Drop support for Node.js v12
Node.js v12 is no longer supported by the Node.js team. https://github.com/nodejs/Release/#end-of-life-releases