Skip to content

Commit d6befd4

Browse files
Add support for persisted GraphQL Queries (#3979)
* Add support for persisted GraphQL Queries * fix: preserve full GraphQL metadata when both query and persistedQuery are present * ✨ Add support for persisted GraphQL queries * ♻️ Remove unnecessary persistedQuery from tests --------- Co-authored-by: roman.gaignault <roman.gaignault@datadoghq.com>
1 parent 099bdbc commit d6befd4

File tree

2 files changed

+52
-13
lines changed

2 files changed

+52
-13
lines changed

packages/rum-core/src/domain/resource/graphql.spec.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,15 @@ describe('GraphQL detection and metadata extraction', () => {
9898
expect(result).toBeUndefined()
9999
})
100100

101-
it('should return undefined for non-GraphQL request body', () => {
101+
it('should return metadata with undefined fields for non-GraphQL request body', () => {
102102
const requestBody = JSON.stringify({ data: 'some data' })
103103
const result = extractGraphQlRequestMetadata(requestBody, true)
104-
expect(result).toBeUndefined()
104+
expect(result).toEqual({
105+
operationType: undefined,
106+
operationName: undefined,
107+
variables: undefined,
108+
payload: undefined,
109+
})
105110
})
106111

107112
it('should handle GraphQL queries with leading and trailing whitespace', () => {
@@ -129,7 +134,12 @@ describe('GraphQL detection and metadata extraction', () => {
129134
})
130135

131136
const result = extractGraphQlRequestMetadata(requestBody, true)
132-
expect(result).toBeUndefined()
137+
expect(result).toEqual({
138+
operationType: undefined,
139+
operationName: 'GetUser',
140+
variables: '{"id":"123"}',
141+
payload: '{ user { id name } }',
142+
})
133143
})
134144

135145
it('should return undefined for queries with invalid operation type', () => {
@@ -140,7 +150,28 @@ describe('GraphQL detection and metadata extraction', () => {
140150
})
141151

142152
const result = extractGraphQlRequestMetadata(requestBody, true)
143-
expect(result).toBeUndefined()
153+
expect(result).toEqual({
154+
operationType: undefined,
155+
operationName: 'GetUser',
156+
variables: '{"id":"123"}',
157+
payload: 'invalid GetUser { user { id name } }',
158+
})
159+
})
160+
161+
it('should extract operation name and variables when query is absent', () => {
162+
const requestBody = JSON.stringify({
163+
operationName: 'GetUser',
164+
variables: { id: '123' },
165+
})
166+
167+
const result = extractGraphQlRequestMetadata(requestBody, true)
168+
169+
expect(result).toEqual({
170+
operationType: undefined,
171+
operationName: 'GetUser',
172+
variables: '{"id":"123"}',
173+
payload: undefined,
174+
})
144175
})
145176
})
146177

packages/rum-core/src/domain/resource/graphql.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface GraphQlError {
1515
}
1616

1717
export interface GraphQlMetadata {
18-
operationType: 'query' | 'mutation' | 'subscription'
18+
operationType?: 'query' | 'mutation' | 'subscription'
1919
operationName?: string
2020
variables?: string
2121
payload?: string
@@ -88,7 +88,11 @@ export function extractGraphQlRequestMetadata(
8888
return
8989
}
9090

91-
let graphqlBody: { query?: string; operationName?: string; variables?: unknown }
91+
let graphqlBody: {
92+
query?: string
93+
operationName?: string
94+
variables?: unknown
95+
}
9296

9397
try {
9498
graphqlBody = JSON.parse(requestBody)
@@ -97,18 +101,22 @@ export function extractGraphQlRequestMetadata(
97101
return
98102
}
99103

100-
if (!graphqlBody || !graphqlBody.query) {
104+
if (!graphqlBody) {
101105
return
102106
}
103107

104-
const query = graphqlBody.query.trim()
105-
const operationType = getOperationType(query)
106-
const operationName = graphqlBody.operationName
108+
let operationType: 'query' | 'mutation' | 'subscription' | undefined
109+
let payload: string | undefined
107110

108-
if (!operationType) {
109-
return
111+
if (graphqlBody.query) {
112+
const trimmedQuery = graphqlBody.query.trim()
113+
operationType = getOperationType(trimmedQuery)
114+
if (trackPayload) {
115+
payload = safeTruncate(trimmedQuery, GRAPHQL_PAYLOAD_LIMIT, '...')
116+
}
110117
}
111118

119+
const operationName = graphqlBody.operationName
112120
let variables: string | undefined
113121
if (graphqlBody.variables) {
114122
variables = JSON.stringify(graphqlBody.variables)
@@ -118,7 +126,7 @@ export function extractGraphQlRequestMetadata(
118126
operationType,
119127
operationName,
120128
variables,
121-
payload: trackPayload ? safeTruncate(query, GRAPHQL_PAYLOAD_LIMIT, '...') : undefined,
129+
payload,
122130
}
123131
}
124132

0 commit comments

Comments
 (0)