We are working on a fairly large Apollo project. A very simplified version of our api looks like this:
type Operation {
foo: String
activity: Activity
}
type Activity {
bar: String
# Lots of fields here ...
}
We've realised splitting Operation
and Activity
does no benefit and adds complexity. We'd like to merge them. But there's a lot of queries that assume this structure in the code base. In order to make the transition gradual we add @deprecated
directives:
type Operation {
foo: String
bar: String
activity: Activity @deprecated
}
type Activity {
bar: String @deprecated(reason: "Use Operation.bar instead")
# Lots of fields here ...
}
Is there some way to highlight those deprecations going forward? Preferably by printing a warning in the browser console when (in the test environment) running a query that uses a deprecated field?
To fix all deprecation warnings, follow the below steps: Replace update() with updateOne() , updateMany() , or replaceOne() Replace remove() with deleteOne() or deleteMany() . Replace count() with countDocuments() , unless you want to count how many documents are in the whole collection (no filter).
Deprecation warnings are a common thing in our industry. They are warnings that notify us that a specific feature (e.g. a method) will be removed soon (usually in the next minor or major version) and should be replaced with something else.
The standard error handling mechanism from GraphQL with return a JSON containing: a data key which contains the data corresponding to the GraphQL operation (query, mutation, subscription) invoked and. an errors key which contains an array of errors returned by the server, with a message and location.
If a mutation updates a single existing entity, Apollo Client can automatically update that entity's value in its cache when the mutation returns. To do so, the mutation must return the id of the modified entity, along with the values of the fields that were modified.
So coming back to GraphQL two years later I just found out that schema directives can be customized (nowadays?). So here's a solution:
import { SchemaDirectiveVisitor } from "graphql-tools"
import { defaultFieldResolver } from "graphql"
import { ApolloServer } from "apollo-server"
class DeprecatedDirective extends SchemaDirectiveVisitor {
public visitFieldDefinition(field ) {
field.isDeprecated = true
field.deprecationReason = this.args.reason
const { resolve = defaultFieldResolver, } = field
field.resolve = async function (...args) {
const [_,__,___,info,] = args
const { operation, } = info
const queryName = operation.name.value
// eslint-disable-next-line no-console
console.warn(
`Deprecation Warning:
Query [${queryName}] used field [${field.name}]
Deprecation reason: [${field.deprecationReason}]`)
return resolve.apply(this, args)
}
}
public visitEnumValue(value) {
value.isDeprecated = true
value.deprecationReason = this.args.reason
}
}
new ApolloServer({
typeDefs,
resolvers,
schemaDirectives: {
deprecated: DeprecatedDirective,
},
}).listen().then(({ url, }) => {
console.log(`🚀 Server ready at ${url}`)
})
This works on the server instead of the client. It should print all the info needed to track down the faulty query on the client though. And having it in the server logs seem preferable from a maintenance perspective.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With