-
-
Save kyliepace/14d6fba0860b28598248f4783df3ca3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
parse, | |
TypeInfo, | |
ValidationContext, | |
visit, | |
visitWithTypeInfo, | |
getNamedType, | |
OperationDefinitionNode, | |
FieldNode, | |
GraphQLSchema, | |
SelectionNode, | |
DocumentNode, | |
DefinitionNode, | |
GraphQLNamedType, | |
} from 'graphql' | |
import createCostAnalysis from 'graphql-cost-analysis' | |
import { GraphQLRequestContext } from 'apollo-server-core' | |
import { Logger } from 'pino' | |
interface CostInput { | |
requestContext: GraphQLRequestContext | |
schema: GraphQLSchema | |
} | |
export class QueryCostAnalyzerService { | |
errorMessage = 'The query exceeds the maximum cost' | |
constructor() {} | |
buildAnalyzer(variables) { | |
return createCostAnalysis({ | |
maximumCost: 1000, // to be determined | |
variables: variables, | |
defaultCost: 1, // let's just blanket cost every field with this value for now | |
onComplete: cost => { | |
console.log(`graphql-cost-analysis cost for request was ${cost}`) // in prod we wouldn't have a console log here | |
}, | |
}) | |
} | |
// do some graphQL things to calculate the cost | |
getCost({requestContext, schema}: CostInput ): number { | |
const typeInfo = new TypeInfo(schema) | |
if (!requestContext.source) { | |
return 0 | |
} | |
const ast = parse(requestContext.source) | |
const onBudgetExceeded = () => { } // leaving this blank for now | |
const validationContext = new ValidationContext( | |
schema, | |
ast, | |
typeInfo, | |
onBudgetExceeded | |
) | |
const analysisVisitor = this.buildAnalyzer( | |
requestContext.request.variables, | |
)(validationContext) | |
// Unfortunately not functional approach | |
// Go through AST and register all costs | |
visit(ast, visitWithTypeInfo(typeInfo, analysisVisitor)) | |
return analysisVisitor.cost || 0 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment