Skip to content

Instantly share code, notes, and snippets.

@silvandiepen
Last active April 29, 2020 09:07
Show Gist options
  • Save silvandiepen/9a7508fedb97242ccbbfdf014616703f to your computer and use it in GitHub Desktop.
Save silvandiepen/9a7508fedb97242ccbbfdf014616703f to your computer and use it in GitHub Desktop.
GITHUB_API_KEY=[YOUR_API_KEY]
/* eslint-disable no-console */
import { ApolloLink, Observable } from 'apollo-link';
const opts = { onlyErrors: false };
const defaultLogger = ({
operation,
response,
graphQLErrors,
networkError
}) => {
const operationType = operation.query.definitions[0].operation;
if (graphQLErrors || networkError || (response && !opts.onlyErrors)) {
console.log(
`[Operation] apollo ${operationType} ${operation.operationName}`
);
}
if (response && !opts.onlyErrors) {
console.log(`[Operation Result] ${JSON.stringify(response)}`);
}
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
console.error(
`[GraphQL Error] Message: "${message}", Locations: ${JSON.stringify(
locations
)}, Path: "${path}"`
)
);
}
if (networkError) {
console.error(`[Network Error] "${networkError}"`);
}
};
const loggerLink = (logger) => {
return new ApolloLink((operation, forward) => {
return new Observable((observer) => {
let sub;
try {
sub = forward(operation).subscribe({
next: (result) => {
if (result.errors) {
logger({
graphQLErrors: result.errors,
response: result,
operation
});
} else {
logger({
response: result,
operation
});
}
observer.next(result);
},
error: (networkError) => {
logger({
operation,
networkError,
// Network errors can return GraphQL errors on for example a 403
graphQLErrors: networkError.result && networkError.result.errors
});
observer.error(networkError);
},
complete: observer.complete.bind(observer)
});
} catch (e) {
logger({ networkError: e, operation });
observer.error(e);
}
return () => {
if (sub) sub.unsubscribe();
};
});
});
};
export default class ApolloLogger extends ApolloLink {
link;
constructor({ logger = null, options = null } = {}) {
super();
opts.onlyErrors = (options && options.onlyErrors) === true;
this.link = loggerLink(logger || defaultLogger);
}
request(operation, forward) {
return this.link.request(operation, forward);
}
}
query {
repositoryOwner(login: "[YOUR_USERNAME]") {
repository(name: "[YOUR_REPOSITORY_NAME]") {
object(expression: "master:") {
... on Tree {
entries {
name
object {
... on Blob {
text
}
}
}
}
}
}
}
}
// Client-side only configs, DO NOT add server-side config here, i.e. database password
export const GRAPHQL_API = 'https://api.github.com/graphql';
import { ApolloLink } from 'apollo-link';
import { setContext } from 'apollo-link-context';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { GRAPHQL_API } from '../../config';
import ApolloLogger from './ApolloLogger';
export default () => {
const loggerLink =
process.env.NODE_ENV !== 'production' ? [new ApolloLogger()] : [];
const httpLink = new HttpLink({
uri: GRAPHQL_API,
credentials: 'same-origin'
});
const authLink = setContext((_, { headers }) => {
const token = process.env.GITHUB_API_KEY
? process.env.GITHUB_API_KEY
: null;
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : null
}
};
});
return {
link: ApolloLink.from([...loggerLink, authLink, httpLink]),
cache: new InMemoryCache()
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment