mirror of
https://github.com/vale981/apollo-server
synced 2025-03-06 02:01:40 -05:00
Generate schemaHash from schema
This commit adds a new field to the GraphQLServiceContext which is a hashed representation of the schema. This is useful as a key value to represent the schema and is sent as part of reporting to engine when enabled
This commit is contained in:
parent
40d21f7d6a
commit
d10f961646
4 changed files with 40 additions and 0 deletions
|
@ -38,11 +38,15 @@
|
|||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tag": "^2.9.2",
|
||||
"graphql-tools": "^4.0.0",
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"lodash": "^4.17.10",
|
||||
"subscriptions-transport-ws": "^0.9.11",
|
||||
"ws": "^6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/json-stable-stringify": "^1.0.32"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ import {
|
|||
PlaygroundRenderPageOptions,
|
||||
} from './playground';
|
||||
|
||||
import { generateSchemaHash } from './utils/schemaHash';
|
||||
|
||||
const NoIntrospection = (context: ValidationContext) => ({
|
||||
Field(node: FieldDefinitionNode) {
|
||||
if (node.name.value === '__schema' || node.name.value === '__type') {
|
||||
|
@ -87,6 +89,7 @@ export class ApolloServerBase {
|
|||
private engineReportingAgent?: EngineReportingAgent;
|
||||
private engineServiceId?: string;
|
||||
private extensions: Array<() => GraphQLExtension>;
|
||||
private schemaHash: string;
|
||||
protected plugins: ApolloServerPlugin[] = [];
|
||||
|
||||
protected schema: GraphQLSchema;
|
||||
|
@ -266,6 +269,10 @@ export class ApolloServerBase {
|
|||
});
|
||||
}
|
||||
|
||||
// The schema hash is a string representation of the shape of the schema
|
||||
// it is used for reporting and can be used for a cache key if needed
|
||||
this.schemaHash = generateSchemaHash(this.schema);
|
||||
|
||||
// Note: doRunQuery will add its own extensions if you set tracing,
|
||||
// or cacheControl.
|
||||
this.extensions = [];
|
||||
|
@ -341,6 +348,7 @@ export class ApolloServerBase {
|
|||
plugin.serverWillStart &&
|
||||
plugin.serverWillStart({
|
||||
schema: this.schema,
|
||||
schemaHash: this.schemaHash,
|
||||
engine: {
|
||||
serviceID: this.engineServiceId,
|
||||
},
|
||||
|
|
|
@ -15,6 +15,7 @@ import { KeyValueCache } from 'apollo-server-caching';
|
|||
|
||||
export interface GraphQLServiceContext {
|
||||
schema: GraphQLSchema;
|
||||
schemaHash: string;
|
||||
engine: {
|
||||
serviceID?: string;
|
||||
};
|
||||
|
|
27
packages/apollo-server-core/src/utils/schemaHash.ts
Normal file
27
packages/apollo-server-core/src/utils/schemaHash.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { parse } from 'graphql/language';
|
||||
import { execute, ExecutionResult } from 'graphql/execution';
|
||||
import { getIntrospectionQuery, IntrospectionSchema } from 'graphql/utilities';
|
||||
import stableStringify from 'json-stable-stringify';
|
||||
import { GraphQLSchema } from 'graphql/type';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
export function generateSchemaHash(schema: GraphQLSchema): string {
|
||||
const introspectionQuery = getIntrospectionQuery();
|
||||
const documentAST = parse(introspectionQuery);
|
||||
const result = execute(schema, documentAST) as ExecutionResult;
|
||||
|
||||
if (!result || !result.data || !result.data.__schema) {
|
||||
throw new Error('Unable to generate server introspection document.');
|
||||
}
|
||||
|
||||
const introspectionSchema: IntrospectionSchema = result.data.__schema;
|
||||
|
||||
// It's important that we perform a deterministic stringification here
|
||||
// since, depending on changes in the underlying `graphql-js` execution
|
||||
// layer, varying orders of the properties in the introspection
|
||||
const stringifiedSchema = stableStringify(introspectionSchema);
|
||||
|
||||
return createHash('sha512')
|
||||
.update(stringifiedSchema)
|
||||
.digest('hex');
|
||||
}
|
Loading…
Add table
Reference in a new issue