Skip to content

Commit f567fbb

Browse files
martyganzMart Ganzevlesn1ru4l
authored
feat(api): add tagunusedSchema & deprecatedSchema to public GraphQL API (#6951)
Co-authored-by: Mart Ganzevles <[email protected]> Co-authored-by: Laurin Quast <[email protected]>
1 parent b864ef2 commit f567fbb

File tree

10 files changed

+486
-52
lines changed

10 files changed

+486
-52
lines changed

.changeset/cold-timers-pull.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'hive': minor
3+
---
4+
5+
Add `SchemaVersion.unusedSchema` and `SchemaVersion.deprecatedSchema` to the public API schema.

integration-tests/tests/api/schema/unused.spec.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import { initSeed } from '../../../testkit/seed';
88

99
const IntegrationTestsUnusedSchemaQuery = graphql(/* GraphQL */ `
1010
query IntegrationTestsUnusedSchema(
11-
$usageInput: UnusedSchemaExplorerUsageInput!
11+
$usagePeriod: DateRangeInput!
1212
$targetRef: TargetReferenceInput!
1313
) {
1414
latestValidVersion(target: $targetRef) {
15-
unusedSchema(usage: $usageInput) {
15+
unusedSchema(period: { absoluteRange: $usagePeriod }) {
1616
types {
1717
__typename
1818
... on GraphQLObjectType {
@@ -74,9 +74,7 @@ test.concurrent(
7474
targetRef: {
7575
byId: target.id,
7676
},
77-
usageInput: {
78-
period,
79-
},
77+
usagePeriod: period,
8078
},
8179
authToken: writeToken.secret,
8280
}).then(r => r.expectNoGraphQLErrors());
@@ -133,9 +131,7 @@ test.concurrent(
133131
targetRef: {
134132
byId: target.id,
135133
},
136-
usageInput: {
137-
period,
138-
},
134+
usagePeriod: period,
139135
},
140136
authToken: writeToken.secret,
141137
}).then(r => r.expectNoGraphQLErrors());

packages/services/api/src/modules/schema/module.graphql.ts

Lines changed: 105 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ export default gql`
420420
}
421421
422422
"""
423-
Describes a schema change for either a schema version (\`SchemaVersion\`) or schema check (\`SchemaCheck\`).
423+
Describes a schema change for either a schema version ('SchemaVersion') or schema check ('SchemaCheck').
424424
"""
425425
type SchemaChange {
426426
criticality: CriticalityLevel!
@@ -433,11 +433,11 @@ export default gql`
433433
)
434434
"""
435435
The severity level of this schema change.
436-
Note: A schema change with the impact \`SeverityLevelType.BREAKING\` can still be safe based on the usage (\`SchemaChange.isSafeBasedOnUsage\`).
436+
Note: A schema change with the impact 'SeverityLevelType.BREAKING' can still be safe based on the usage ('SchemaChange.isSafeBasedOnUsage').
437437
"""
438438
severityLevel: SeverityLevelType! @tag(name: "public")
439439
"""
440-
The reason for the schema changes severity level (\`SchemaChange.severityLevel\`)
440+
The reason for the schema changes severity level ('SchemaChange.severityLevel')
441441
"""
442442
severityReason: String @tag(name: "public")
443443
"""
@@ -746,6 +746,13 @@ export default gql`
746746
pageInfo: PageInfo! @tag(name: "public")
747747
}
748748
749+
input SchemaExplorerPeriodInput @oneOf {
750+
"""
751+
A full range using a start and end date.
752+
"""
753+
absoluteRange: DateRangeInput @tag(name: "public")
754+
}
755+
749756
type SchemaVersion {
750757
id: ID! @tag(name: "public")
751758
"""
@@ -796,8 +803,29 @@ export default gql`
796803
Experimental: This field is not stable and may change in the future.
797804
"""
798805
explorer(usage: SchemaExplorerUsageInput): SchemaExplorer
799-
unusedSchema(usage: UnusedSchemaExplorerUsageInput): UnusedSchemaExplorer
800-
deprecatedSchema(usage: DeprecatedSchemaExplorerUsageInput): DeprecatedSchemaExplorer
806+
"""
807+
An overview of unused fields and their types within the GraphQL schema.
808+
"""
809+
unusedSchema(
810+
"""
811+
The period to use in order to determind whether a field is unused.
812+
A field is unused if it has not been requested within the specified period.
813+
814+
Defaults to the last 30 days by default.
815+
"""
816+
period: SchemaExplorerPeriodInput @tag(name: "public")
817+
): UnusedSchemaExplorer @tag(name: "public")
818+
"""
819+
An overview of deprecated fields and types with their usage in the GraphQL schema.
820+
"""
821+
deprecatedSchema(
822+
"""
823+
The period for which the usage data should be included within the result.
824+
825+
Defaults to the last 30 days by default.
826+
"""
827+
period: SchemaExplorerPeriodInput @tag(name: "public")
828+
): DeprecatedSchemaExplorer @tag(name: "public")
801829
802830
schemaCompositionErrors: SchemaErrorConnection @tag(name: "public")
803831
@@ -846,14 +874,6 @@ export default gql`
846874
period: DateRangeInput!
847875
}
848876
849-
input UnusedSchemaExplorerUsageInput {
850-
period: DateRangeInput!
851-
}
852-
853-
input DeprecatedSchemaExplorerUsageInput {
854-
period: DateRangeInput!
855-
}
856-
857877
type MetadataAttribute {
858878
name: String!
859879
values: [String!]!
@@ -873,30 +893,66 @@ export default gql`
873893
supergraphMetadata: SupergraphMetadata
874894
}
875895
896+
"""
897+
Explorer for navigating unused schema parts within the contextual provided period.
898+
"""
876899
type UnusedSchemaExplorer {
877-
types: [GraphQLNamedType!]!
900+
"""
901+
The affected unused types and their fields/values/members etc.
902+
903+
The types within the result only contain unused fields/values/members, all other entities are excluded,
904+
they are not a representation of the full GraphQL schema.
905+
"""
906+
types: [GraphQLNamedType!]! @tag(name: "public")
878907
}
879908
909+
"""
910+
Explorer for navigating the deprecated schema parts with usage data provided by the contextual period.
911+
"""
880912
type DeprecatedSchemaExplorer {
881-
types: [GraphQLNamedType!]!
913+
"""
914+
The affected types whose fields/values/members are deprecated.
915+
916+
The types within the result only contain deprecated fields/values/members, all other entities are excluded,
917+
they are not a representation of the full GraphQL schema.
918+
"""
919+
types: [GraphQLNamedType!]! @tag(name: "public")
882920
}
883921
884-
type SchemaCoordinateUsage {
922+
"""
923+
Information about the schema coordinate usage within the contextual period.
924+
"""
925+
type SchemaCoordinateUsage @tag(name: "public") {
926+
"""
927+
The total amount of usages of the schema coordinate within the contextual period.
928+
"""
885929
total: Float!
930+
"""
931+
Whether the schema coordinate is used within the contextual period.
932+
"""
886933
isUsed: Boolean!
887934
"""
888935
A list of clients that use this schema coordinate within GraphQL operation documents.
889936
Is null if used by none clients.
890937
"""
891938
usedByClients: [String!]
939+
"""
940+
The top operations executed for this schema coordinate within the contextual period.
941+
"""
892942
topOperations(limit: Int!): [SchemaCoordinateUsageOperation!]!
893943
}
894944
895-
type SchemaCoordinateUsageOperation {
945+
type SchemaCoordinateUsageOperation @tag(name: "public") {
946+
"""
947+
The name of the GraphQL operation.
948+
"""
896949
name: String!
950+
"""
951+
The hash of the GraphQL operation
952+
"""
897953
hash: String!
898954
"""
899-
The number of times the operation was called.
955+
The number of times the operation was called within the contextual period.
900956
"""
901957
count: Float!
902958
}
@@ -907,7 +963,7 @@ export default gql`
907963
List of service names that own the field/type.
908964
Resolves to null if the entity (field, type, scalar) does not belong to any service.
909965
"""
910-
ownedByServiceNames: [String!]
966+
ownedByServiceNames: [String!] @tag(name: "public")
911967
}
912968
913969
type SchemaMetadata {
@@ -925,15 +981,27 @@ export default gql`
925981
source: String
926982
}
927983
928-
union GraphQLNamedType =
929-
| GraphQLObjectType
930-
| GraphQLInterfaceType
931-
| GraphQLUnionType
932-
| GraphQLEnumType
933-
| GraphQLInputObjectType
934-
| GraphQLScalarType
984+
interface GraphQLNamedType @tag(name: "public") {
985+
"""
986+
The name of the GraphQL type.
987+
"""
988+
name: String!
989+
"""
990+
The description of the GraphQL type.
991+
"""
992+
description: String
993+
"""
994+
The usage of the type within the specified period.
995+
"""
996+
usage: SchemaCoordinateUsage!
997+
"""
998+
Metadata specific to Apollo Federation Projects.
999+
Is null if no meta information is available (e.g. this is not an apollo federation project).
1000+
"""
1001+
supergraphMetadata: SupergraphMetadata
1002+
}
9351003
936-
type GraphQLObjectType {
1004+
type GraphQLObjectType implements GraphQLNamedType @tag(name: "public") {
9371005
name: String!
9381006
description: String
9391007
fields: [GraphQLField!]!
@@ -946,7 +1014,7 @@ export default gql`
9461014
supergraphMetadata: SupergraphMetadata
9471015
}
9481016
949-
type GraphQLInterfaceType {
1017+
type GraphQLInterfaceType implements GraphQLNamedType @tag(name: "public") {
9501018
name: String!
9511019
description: String
9521020
fields: [GraphQLField!]!
@@ -959,7 +1027,7 @@ export default gql`
9591027
supergraphMetadata: SupergraphMetadata
9601028
}
9611029
962-
type GraphQLUnionType {
1030+
type GraphQLUnionType implements GraphQLNamedType @tag(name: "public") {
9631031
name: String!
9641032
description: String
9651033
members: [GraphQLUnionTypeMember!]!
@@ -971,7 +1039,7 @@ export default gql`
9711039
supergraphMetadata: SupergraphMetadata
9721040
}
9731041
974-
type GraphQLUnionTypeMember {
1042+
type GraphQLUnionTypeMember @tag(name: "public") {
9751043
name: String!
9761044
usage: SchemaCoordinateUsage!
9771045
"""
@@ -981,7 +1049,7 @@ export default gql`
9811049
supergraphMetadata: SupergraphMetadata
9821050
}
9831051
984-
type GraphQLEnumType {
1052+
type GraphQLEnumType implements GraphQLNamedType @tag(name: "public") {
9851053
name: String!
9861054
description: String
9871055
deprecationReason: String
@@ -994,7 +1062,7 @@ export default gql`
9941062
supergraphMetadata: SupergraphMetadata
9951063
}
9961064
997-
type GraphQLInputObjectType {
1065+
type GraphQLInputObjectType implements GraphQLNamedType @tag(name: "public") {
9981066
name: String!
9991067
description: String
10001068
fields: [GraphQLInputField!]!
@@ -1006,7 +1074,7 @@ export default gql`
10061074
supergraphMetadata: SupergraphMetadata
10071075
}
10081076
1009-
type GraphQLScalarType {
1077+
type GraphQLScalarType implements GraphQLNamedType @tag(name: "public") {
10101078
name: String!
10111079
description: String
10121080
usage: SchemaCoordinateUsage!
@@ -1017,7 +1085,7 @@ export default gql`
10171085
supergraphMetadata: SupergraphMetadata
10181086
}
10191087
1020-
type GraphQLField {
1088+
type GraphQLField @tag(name: "public") {
10211089
name: String!
10221090
description: String
10231091
type: String!
@@ -1032,7 +1100,7 @@ export default gql`
10321100
supergraphMetadata: SupergraphMetadata
10331101
}
10341102
1035-
type GraphQLInputField {
1103+
type GraphQLInputField @tag(name: "public") {
10361104
name: String!
10371105
description: String
10381106
type: String!
@@ -1047,7 +1115,7 @@ export default gql`
10471115
supergraphMetadata: SupergraphMetadata
10481116
}
10491117
1050-
type GraphQLArgument {
1118+
type GraphQLArgument @tag(name: "public") {
10511119
name: String!
10521120
description: String
10531121
type: String!
@@ -1057,7 +1125,7 @@ export default gql`
10571125
usage: SchemaCoordinateUsage!
10581126
}
10591127
1060-
type GraphQLEnumValue {
1128+
type GraphQLEnumValue @tag(name: "public") {
10611129
name: String!
10621130
description: String
10631131
isDeprecated: Boolean!

packages/services/api/src/modules/schema/resolvers/SchemaVersion.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export const SchemaVersion: SchemaVersionResolvers = {
119119
},
120120
};
121121
},
122-
unusedSchema: async (version, { usage }, { injector }) => {
122+
unusedSchema: async (version, args, { injector }) => {
123123
const [schemaAst, supergraphAst] = await Promise.all([
124124
injector.get(SchemaVersionHelper).getCompositeSchemaAst(version),
125125
injector.get(SchemaVersionHelper).getSupergraphAst(version),
@@ -129,19 +129,23 @@ export const SchemaVersion: SchemaVersionResolvers = {
129129
return null;
130130
}
131131

132+
const period = args.period?.absoluteRange
133+
? parseDateRangeInput(args.period.absoluteRange)
134+
: createPeriod('30d');
135+
132136
const usedCoordinates = await injector.get(OperationsManager).getReportedSchemaCoordinates({
133137
targetId: version.targetId,
134138
projectId: version.projectId,
135139
organizationId: version.organizationId,
136-
period: usage?.period ? parseDateRangeInput(usage.period) : createPeriod('30d'),
140+
period,
137141
});
138142

139143
const supergraph = supergraphAst ? extractSuperGraphInformation(supergraphAst) : null;
140144

141145
return {
142146
sdl: stripUsedSchemaCoordinatesFromDocumentNode(schemaAst, usedCoordinates),
143147
usage: {
144-
period: usage?.period ? parseDateRangeInput(usage.period) : createPeriod('30d'),
148+
period,
145149
organizationId: version.organizationId,
146150
projectId: version.projectId,
147151
targetId: version.targetId,
@@ -158,7 +162,7 @@ export const SchemaVersion: SchemaVersionResolvers = {
158162
},
159163
};
160164
},
161-
deprecatedSchema: async (version, { usage }, { injector }) => {
165+
deprecatedSchema: async (version, args, { injector }) => {
162166
const [schemaAst, supergraphAst] = await Promise.all([
163167
injector.get(SchemaVersionHelper).getCompositeSchemaAst(version),
164168
injector.get(SchemaVersionHelper).getSupergraphAst(version),
@@ -170,10 +174,14 @@ export const SchemaVersion: SchemaVersionResolvers = {
170174

171175
const supergraph = supergraphAst ? extractSuperGraphInformation(supergraphAst) : null;
172176

177+
const period = args.period?.absoluteRange
178+
? parseDateRangeInput(args.period.absoluteRange)
179+
: createPeriod('30d');
180+
173181
return {
174182
sdl: onlyDeprecatedDocumentNode(schemaAst),
175183
usage: {
176-
period: usage?.period ? parseDateRangeInput(usage.period) : createPeriod('30d'),
184+
period,
177185
organizationId: version.organizationId,
178186
projectId: version.projectId,
179187
targetId: version.targetId,

0 commit comments

Comments
 (0)