@@ -13,6 +13,8 @@ public struct ApolloSchemaDownloader {
1313 case couldNotExtractSDLFromRegistryJSON
1414 case couldNotCreateSDLDataToWrite( schema: String )
1515 case couldNotConvertIntrospectionJSONToSDL( underlying: Error )
16+ case couldNotCreateURLComponentsFromEndpointURL( url: URL )
17+ case couldNotGetURLFromURLComponents( components: URLComponents )
1618
1719 public var errorDescription : String ? {
1820 switch self {
@@ -29,7 +31,11 @@ public struct ApolloSchemaDownloader {
2931 case . couldNotCreateSDLDataToWrite( let schema) :
3032 return " Could not convert SDL schema into data to write to the filesystem. Schema: \( schema) "
3133 case . couldNotConvertIntrospectionJSONToSDL( let underlying) :
32- return " Could not convert downloaded introspection JSON into SDL format. Underlying error: \( underlying) "
34+ return " Could not convert downloaded introspection JSON into SDL format. Underlying error: \( underlying) "
35+ case . couldNotCreateURLComponentsFromEndpointURL( let url) :
36+ return " Could not create URLComponents from \( url) for Introspection. "
37+ case . couldNotGetURLFromURLComponents( let components) :
38+ return " Could not get URL from \( components) . "
3339 }
3440 }
3541 }
@@ -43,18 +49,36 @@ public struct ApolloSchemaDownloader {
4349 try FileManager . default. apollo. createContainingFolderIfNeeded ( for: configuration. outputURL)
4450
4551 switch configuration. downloadMethod {
46- case . introspection( let endpointURL) :
47- try self . downloadViaIntrospection ( from: endpointURL, configuration: configuration)
52+ case . introspection( let endpointURL, let httpMethod ) :
53+ try self . downloadViaIntrospection ( from: endpointURL, httpMethod : httpMethod , configuration: configuration)
4854 case . apolloRegistry( let settings) :
4955 try self . downloadFromRegistry ( with: settings, configuration: configuration)
5056 }
5157 }
5258
59+ private static func request( url: URL ,
60+ httpMethod: ApolloSchemaDownloadConfiguration . DownloadMethod . HTTPMethod ,
61+ headers: [ ApolloSchemaDownloadConfiguration . HTTPHeader ] ,
62+ bodyData: Data ? = nil ) -> URLRequest {
63+
64+ var request = URLRequest ( url: url)
65+
66+ request. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
67+ for header in headers {
68+ request. addValue ( header. value, forHTTPHeaderField: header. key)
69+ }
70+
71+ request. httpMethod = String ( describing: httpMethod)
72+ request. httpBody = bodyData
73+
74+ return request
75+ }
76+
5377 // MARK: - Schema Registry
5478
5579 static let RegistryEndpoint = URL ( string: " https://graphql.api.apollographql.com/api/graphql " ) !
5680
57- private static let RegistryDownloadQuery = """
81+ static let RegistryDownloadQuery = """
5882 query DownloadSchema($graphID: ID!, $variant: String!) {
5983 service(id: $graphID) {
6084 variant(name: $variant) {
@@ -74,27 +98,9 @@ public struct ApolloSchemaDownloader {
7498
7599 CodegenLogger . log ( " Downloading schema from registry " , logLevel: . debug)
76100
77- var variables = [ String: String] ( )
78- variables [ " graphID " ] = settings. graphID
79-
80- if let variant = settings. variant {
81- variables [ " variant " ] = variant
82- }
83-
84- let body = UntypedGraphQLRequestBodyCreator . requestBody ( for: self . RegistryDownloadQuery,
85- variables: variables,
86- operationName: " DownloadSchema " )
87-
88- var urlRequest = URLRequest ( url: self . RegistryEndpoint)
89- urlRequest. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
90- urlRequest. addValue ( settings. apiKey, forHTTPHeaderField: " x-api-key " )
91- for header in configuration. headers {
92- urlRequest. addValue ( header. value, forHTTPHeaderField: header. key)
93- }
94- urlRequest. httpMethod = " POST "
95- urlRequest. httpBody = try JSONSerialization . data ( withJSONObject: body, options: [ . sortedKeys] )
101+ let urlRequest = try registryRequest ( with: settings, headers: configuration. headers)
96102 let jsonOutputURL = configuration. outputURL. apollo. parentFolderURL ( ) . appendingPathComponent ( " registry_response.json " )
97-
103+
98104 try URLDownloader ( ) . downloadSynchronously ( with: urlRequest,
99105 to: jsonOutputURL,
100106 timeout: configuration. downloadTimeout)
@@ -104,6 +110,31 @@ public struct ApolloSchemaDownloader {
104110 CodegenLogger . log ( " Successfully downloaded schema from registry " , logLevel: . debug)
105111 }
106112
113+ static func registryRequest( with settings: ApolloSchemaDownloadConfiguration . DownloadMethod . ApolloRegistrySettings ,
114+ headers: [ ApolloSchemaDownloadConfiguration . HTTPHeader ] ) throws -> URLRequest {
115+
116+ var variables = [ String: String] ( )
117+ variables [ " graphID " ] = settings. graphID
118+ if let variant = settings. variant {
119+ variables [ " variant " ] = variant
120+ }
121+
122+ let requestBody = UntypedGraphQLRequestBodyCreator . requestBody ( for: self . RegistryDownloadQuery,
123+ variables: variables,
124+ operationName: " DownloadSchema " )
125+ let bodyData = try JSONSerialization . data ( withJSONObject: requestBody, options: [ . sortedKeys] )
126+
127+ var allHeaders = headers
128+ allHeaders. append ( ApolloSchemaDownloadConfiguration . HTTPHeader ( key: " x-api-key " , value: settings. apiKey) )
129+
130+ let urlRequest = request ( url: self . RegistryEndpoint,
131+ httpMethod: . POST,
132+ headers: allHeaders,
133+ bodyData: bodyData)
134+
135+ return urlRequest
136+ }
137+
107138 static func convertFromRegistryJSONToSDLFile( jsonFileURL: URL , configuration: ApolloSchemaDownloadConfiguration ) throws {
108139 let jsonData : Data
109140
@@ -143,7 +174,7 @@ public struct ApolloSchemaDownloader {
143174
144175 // MARK: - Schema Introspection
145176
146- private static let IntrospectionQuery = """
177+ static let IntrospectionQuery = """
147178 query IntrospectionQuery {
148179 __schema {
149180 queryType { name }
@@ -235,21 +266,13 @@ public struct ApolloSchemaDownloader {
235266 """
236267
237268
238- static func downloadViaIntrospection( from endpointURL: URL , configuration: ApolloSchemaDownloadConfiguration ) throws {
269+ static func downloadViaIntrospection( from endpointURL: URL ,
270+ httpMethod: ApolloSchemaDownloadConfiguration . DownloadMethod . HTTPMethod ,
271+ configuration: ApolloSchemaDownloadConfiguration ) throws {
272+
239273 CodegenLogger . log ( " Downloading schema via introspection from \( endpointURL) " , logLevel: . debug)
240-
241- var urlRequest = URLRequest ( url: endpointURL)
242- urlRequest. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
243274
244- for header in configuration. headers {
245- urlRequest. addValue ( header. value, forHTTPHeaderField: header. key)
246- }
247-
248- let body = UntypedGraphQLRequestBodyCreator . requestBody ( for: self . IntrospectionQuery,
249- variables: nil ,
250- operationName: " IntrospectionQuery " )
251- urlRequest. httpMethod = " POST "
252- urlRequest. httpBody = try JSONSerialization . data ( withJSONObject: body, options: [ . sortedKeys] )
275+ let urlRequest = try introspectionRequest ( from: endpointURL, httpMethod: httpMethod, headers: configuration. headers)
253276 let jsonOutputURL = configuration. outputURL. apollo. parentFolderURL ( ) . appendingPathComponent ( " introspection_response.json " )
254277
255278 try URLDownloader ( ) . downloadSynchronously ( with: urlRequest,
@@ -260,7 +283,38 @@ public struct ApolloSchemaDownloader {
260283
261284 CodegenLogger . log ( " Successfully downloaded schema via introspection " , logLevel: . debug)
262285 }
263-
286+
287+ static func introspectionRequest( from endpointURL: URL ,
288+ httpMethod: ApolloSchemaDownloadConfiguration . DownloadMethod . HTTPMethod ,
289+ headers: [ ApolloSchemaDownloadConfiguration . HTTPHeader ] ) throws -> URLRequest {
290+ let urlRequest : URLRequest
291+
292+ switch httpMethod {
293+ case . POST:
294+ let requestBody = UntypedGraphQLRequestBodyCreator . requestBody ( for: self . IntrospectionQuery,
295+ variables: nil ,
296+ operationName: " IntrospectionQuery " )
297+ let bodyData = try JSONSerialization . data ( withJSONObject: requestBody, options: [ . sortedKeys] )
298+ urlRequest = request ( url: endpointURL,
299+ httpMethod: httpMethod,
300+ headers: headers,
301+ bodyData: bodyData)
302+
303+ case . GET( let queryParameterName) :
304+ guard var components = URLComponents ( url: endpointURL, resolvingAgainstBaseURL: true ) else {
305+ throw SchemaDownloadError . couldNotCreateURLComponentsFromEndpointURL ( url: endpointURL)
306+ }
307+ components. queryItems = [ URLQueryItem ( name: queryParameterName, value: IntrospectionQuery) ]
308+
309+ guard let url = components. url else {
310+ throw SchemaDownloadError . couldNotGetURLFromURLComponents ( components: components)
311+ }
312+ urlRequest = request ( url: url, httpMethod: httpMethod, headers: headers)
313+ }
314+
315+ return urlRequest
316+ }
317+
264318 static func convertFromIntrospectionJSONToSDLFile( jsonFileURL: URL , configuration: ApolloSchemaDownloadConfiguration ) throws {
265319 let frontend = try ApolloCodegenFrontend ( )
266320 let schema : GraphQLSchema
0 commit comments