- Notifications
You must be signed in to change notification settings - Fork0
Grishezz/apollo-studio-data-fetcher
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This project is aimed to provide actual query duration statistics fromapollo-studio.
These timing metrics (AKA timing-hints) can then be utilized in a custom graphql complexity estimator and plugged into thegraphql-query-complexity library designed to"... protect your GraphQL servers against resource exhaustion and DoS attacks".
- create a
schema.graphql
containing the AST version of your graphql schema inside thedata
folder - create a
.env
file, based on.env.example
- build with
yarn
- run with
yarn run
- logins into apollo-studio using puppeteer and intercepts your auth cookies, and the timing metrics persistent query hash
- reads your schema from
schema.graphql
, and runs a graphql timing metric query, via apollo-studio graphql api(using cookies and persistent query hash from [1]) - arranges the data into an object of the following structure:
{"Address.city":0.003780965612170304,"Address.country":0.0036712738793939926,"Address.entrance":0.0037941881736387904,...}
- stores this data in an aws s3 bucket
Note: you can (and it makes sense to) run the above logic periodically.
In yourapollo-server
implementation, add a plugin:
import{getComplexity,simpleEstimator}from'graphql-query-complexity';...classComplexityValidatorimplementsApolloServerPlugin<any>{ ...requestDidStart(requestContext:GraphQLRequestContext<any>):GraphQLRequestListener<any>|void{return{didResolveOperation({ request, document}){constquery=request.operationName ?separateOperations(document)[request.operationName] :document;constcomplexity=getComplexity({ schema, query,variables:request.variables,estimators:[// where timingMetrics is the data generated by this (apollo-studio-data-fetcher) projecttimingBasedEstimator(timingMetrics),simpleEstimator({defaultComplexity:100})],});validateComplexity(...);}};}}
while the timingBasedEstimator implementation can be something along these lines:
import{ComplexityEstimatorArgs}from'graphql-query-complexity';import{get}from'lodash';/** * Complexity estimator based on actual query timing metrics fetched from apollo-studio. * The return unit is milliseconds-equivalent. * *@param timingMetrics */exportfunctiontimingBasedEstimator(timingMetrics){return(options:ComplexityEstimatorArgs)=>{consttimingMetricKey=`${options.type.name}.${options.field.name}`;consttimingMetricValue=timingMetrics[timingMetricKey];if(timingMetricValue){// Your actual calculation might be different, using such a multiplier, is just an examle.constmultiplier=Math.max(get(options,'args.first',1),get(options,'args.last',1));return(timingMetricValue+options.childComplexity)*multiplier;}returnundefined;// Fallback to simpleEstimator.};}
- add some tests
- support mutation / interfaces / unions etc.
About
This project is aimed to provide actual query duration statistics from apollo-studio.
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
No releases published
Packages0
No packages published