Skip to content

Commit

Permalink
Require opting into SchemaLink validation.
Browse files Browse the repository at this point in the history
Follow-up to #7094, to avoid enabling validation by default, since
@apollo/client@3.3.0 is not a major release.
  • Loading branch information
benjamn committed Nov 24, 2020
1 parent 6b1e1d4 commit e27be1e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. <br/>
[@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. <br/>
- 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. <br/>
[@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. <br/>
Expand Down
26 changes: 16 additions & 10 deletions src/link/schema/__tests__/schemaLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand Down Expand Up @@ -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 {
Expand Down
16 changes: 13 additions & 3 deletions src/link/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,27 @@ 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;
}
}

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<FetchResult> {
Expand All @@ -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(
Expand Down

0 comments on commit e27be1e

Please sign in to comment.