diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d3eec8749c..86b5336554e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -75,7 +75,7 @@
- In addition to the `result.data` property, `useQuery` and `useLazyQuery` will now provide a `result.previousData` property, which can be useful when a network request is pending and `result.data` is undefined, since `result.previousData` can be rendered instead of rendering an empty/loading state.
[@hwillson](https://github.com/hwillson) in [#7082](https://github.com/apollographql/apollo-client/pull/7082)
-- The schema link package (`@apollo/client/link/schema`) will now validate incoming queries against its client-side schema, and return `errors` as a GraphQL server would.
+- Passing `validate: true` to the `SchemaLink` constructor will enable validation of incoming queries against the local schema before execution, returning validation errors in `result.errors`, just like a non-local GraphQL endpoint typically would.
[@amannn](https://github.com/amannn) in [#7094](https://github.com/apollographql/apollo-client/pull/7094)
- Allow optional arguments in `keyArgs: [...]` arrays for `InMemoryCache` field policies.
diff --git a/src/link/schema/__tests__/schemaLink.ts b/src/link/schema/__tests__/schemaLink.ts
index 79da8ee02e4..0e6329ac49e 100644
--- a/src/link/schema/__tests__/schemaLink.ts
+++ b/src/link/schema/__tests__/schemaLink.ts
@@ -65,17 +65,19 @@ describe('SchemaLink', () => {
});
it('calls error when fetch fails', done => {
- const schema = makeExecutableSchema({
- typeDefs,
- resolvers: {
- Query: {
- sampleQuery() {
- throw new Error('Unauthorized');
+ const link = new SchemaLink({
+ validate: true,
+ schema: makeExecutableSchema({
+ typeDefs,
+ resolvers: {
+ Query: {
+ sampleQuery() {
+ throw new Error('Unauthorized');
+ }
}
}
- }
+ }),
});
- const link = new SchemaLink({ schema });
const observable = execute(link, {
query: sampleQuery,
});
@@ -199,8 +201,12 @@ describe('SchemaLink', () => {
});
it('reports errors for unknown queries', done => {
- const schema = makeExecutableSchema({typeDefs})
- const link = new SchemaLink({ schema });
+ const link = new SchemaLink({
+ validate: true,
+ schema: makeExecutableSchema({
+ typeDefs,
+ }),
+ });
const observable = execute(link, {
query: gql`
query {
diff --git a/src/link/schema/index.ts b/src/link/schema/index.ts
index 7479b128abd..1a8f23837b6 100644
--- a/src/link/schema/index.ts
+++ b/src/link/schema/index.ts
@@ -24,6 +24,12 @@ export namespace SchemaLink {
* A context to provide to resolvers declared within the schema.
*/
context?: ResolverContext | ResolverContextFunction;
+
+ /**
+ * Validate incoming queries against the given schema, returning
+ * validation errors as a GraphQL server would.
+ */
+ validate?: boolean;
}
}
@@ -31,12 +37,14 @@ export class SchemaLink extends ApolloLink {
public schema: SchemaLink.Options["schema"];
public rootValue: SchemaLink.Options["rootValue"];
public context: SchemaLink.Options["context"];
+ public validate: boolean;
constructor(options: SchemaLink.Options) {
super();
this.schema = options.schema;
this.rootValue = options.rootValue;
this.context = options.context;
+ this.validate = !!options.validate;
}
public request(operation: Operation): Observable {
@@ -48,9 +56,11 @@ export class SchemaLink extends ApolloLink {
: this.context
)
).then(context => {
- const validationErrors = validate(this.schema, operation.query);
- if (validationErrors.length > 0) {
- return { errors: validationErrors };
+ if (this.validate) {
+ const validationErrors = validate(this.schema, operation.query);
+ if (validationErrors.length > 0) {
+ return { errors: validationErrors };
+ }
}
return execute(