Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update how requests are created so custom subclasses of HTTP requests can be used #1405

Merged
merged 8 commits into from
Sep 22, 2020
44 changes: 28 additions & 16 deletions Apollo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,13 @@
9BE071AF2368D34D00FA5952 /* Matchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BE071AE2368D34D00FA5952 /* Matchable.swift */; };
9BE071B12368D3F500FA5952 /* Dictionary+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BE071B02368D3F500FA5952 /* Dictionary+Helpers.swift */; };
9BE74D3D23FB4A8E006D354F /* FileFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BE74D3C23FB4A8E006D354F /* FileFinder.swift */; };
9BEDC79E22E5D2CF00549BF6 /* RequestCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEDC79D22E5D2CF00549BF6 /* RequestCreator.swift */; };
9BEDC79E22E5D2CF00549BF6 /* RequestBodyCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEDC79D22E5D2CF00549BF6 /* RequestBodyCreator.swift */; };
9BEEDC2824E351E5001D1294 /* MaxRetryInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEDC2724E351E5001D1294 /* MaxRetryInterceptor.swift */; };
9BEEDC2B24E61995001D1294 /* TestURLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEDC2A24E61995001D1294 /* TestURLs.swift */; };
9BF1A95122CA6E71005292C2 /* GraphQLGETTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BF1A95022CA6E71005292C2 /* GraphQLGETTransformer.swift */; };
9BF6C94325194DE2000D5B93 /* MultipartFormData+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BF6C91725194D7B000D5B93 /* MultipartFormData+Testing.swift */; };
9BF6C97025194ED7000D5B93 /* MultipartFormDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BF6C95225194EA5000D5B93 /* MultipartFormDataTests.swift */; };
9BF6C99C25195019000D5B93 /* String+IncludesForTesting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BF6C99B25195019000D5B93 /* String+IncludesForTesting.swift */; };
9F19D8441EED568200C57247 /* ResultOrPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F19D8431EED568200C57247 /* ResultOrPromise.swift */; };
9F19D8461EED8D3B00C57247 /* ResultOrPromiseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F19D8451EED8D3B00C57247 /* ResultOrPromiseTests.swift */; };
9F27D4641D40379500715680 /* JSONStandardTypeConversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F27D4631D40379500715680 /* JSONStandardTypeConversions.swift */; };
Expand Down Expand Up @@ -238,8 +241,8 @@
9FF90A6F1DDDEB420034C3B6 /* InputValueEncodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF90A6A1DDDEB420034C3B6 /* InputValueEncodingTests.swift */; };
9FF90A711DDDEB420034C3B6 /* ReadFieldValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF90A6B1DDDEB420034C3B6 /* ReadFieldValueTests.swift */; };
9FF90A731DDDEB420034C3B6 /* ParseQueryResponseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF90A6C1DDDEB420034C3B6 /* ParseQueryResponseTests.swift */; };
C3279FC72345234D00224790 /* TestCustomRequestCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3279FC52345233000224790 /* TestCustomRequestCreator.swift */; };
C338DF1722DD9DE9006AF33E /* RequestCreatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C338DF1622DD9DE9006AF33E /* RequestCreatorTests.swift */; };
C3279FC72345234D00224790 /* TestCustomRequestBodyCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3279FC52345233000224790 /* TestCustomRequestBodyCreator.swift */; };
C338DF1722DD9DE9006AF33E /* RequestBodyCreatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C338DF1622DD9DE9006AF33E /* RequestBodyCreatorTests.swift */; };
C35D43C222DDD4AC00BCBABE /* b.txt in Resources */ = {isa = PBXBuildFile; fileRef = C35D43BE22DDD3C100BCBABE /* b.txt */; };
C35D43C322DDD4AF00BCBABE /* c.txt in Resources */ = {isa = PBXBuildFile; fileRef = C35D43BF22DDD3C100BCBABE /* c.txt */; };
C35D43C622DDE28D00BCBABE /* a.txt in Resources */ = {isa = PBXBuildFile; fileRef = C304EBD322DDC7B200748F72 /* a.txt */; };
Expand Down Expand Up @@ -689,10 +692,13 @@
9BE071AE2368D34D00FA5952 /* Matchable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Matchable.swift; sourceTree = "<group>"; };
9BE071B02368D3F500FA5952 /* Dictionary+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Helpers.swift"; sourceTree = "<group>"; };
9BE74D3C23FB4A8E006D354F /* FileFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileFinder.swift; sourceTree = "<group>"; };
9BEDC79D22E5D2CF00549BF6 /* RequestCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestCreator.swift; sourceTree = "<group>"; };
9BEDC79D22E5D2CF00549BF6 /* RequestBodyCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestBodyCreator.swift; sourceTree = "<group>"; };
9BEEDC2724E351E5001D1294 /* MaxRetryInterceptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaxRetryInterceptor.swift; sourceTree = "<group>"; };
9BEEDC2A24E61995001D1294 /* TestURLs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestURLs.swift; sourceTree = "<group>"; };
9BF1A95022CA6E71005292C2 /* GraphQLGETTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLGETTransformer.swift; sourceTree = "<group>"; };
9BF6C91725194D7B000D5B93 /* MultipartFormData+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MultipartFormData+Testing.swift"; sourceTree = "<group>"; };
9BF6C95225194EA5000D5B93 /* MultipartFormDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartFormDataTests.swift; sourceTree = "<group>"; };
9BF6C99B25195019000D5B93 /* String+IncludesForTesting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+IncludesForTesting.swift"; sourceTree = "<group>"; };
9F19D8431EED568200C57247 /* ResultOrPromise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResultOrPromise.swift; sourceTree = "<group>"; };
9F19D8451EED8D3B00C57247 /* ResultOrPromiseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResultOrPromiseTests.swift; sourceTree = "<group>"; };
9F27D4631D40379500715680 /* JSONStandardTypeConversions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONStandardTypeConversions.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -751,8 +757,8 @@
9FF90A6B1DDDEB420034C3B6 /* ReadFieldValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadFieldValueTests.swift; sourceTree = "<group>"; };
9FF90A6C1DDDEB420034C3B6 /* ParseQueryResponseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseQueryResponseTests.swift; sourceTree = "<group>"; };
C304EBD322DDC7B200748F72 /* a.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = a.txt; sourceTree = "<group>"; };
C3279FC52345233000224790 /* TestCustomRequestCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestCustomRequestCreator.swift; sourceTree = "<group>"; };
C338DF1622DD9DE9006AF33E /* RequestCreatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestCreatorTests.swift; sourceTree = "<group>"; };
C3279FC52345233000224790 /* TestCustomRequestBodyCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestCustomRequestBodyCreator.swift; sourceTree = "<group>"; };
C338DF1622DD9DE9006AF33E /* RequestBodyCreatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestBodyCreatorTests.swift; sourceTree = "<group>"; };
C35D43BE22DDD3C100BCBABE /* b.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = b.txt; sourceTree = "<group>"; };
C35D43BF22DDD3C100BCBABE /* c.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = c.txt; sourceTree = "<group>"; };
C377CCA822D798BD00572E03 /* GraphQLFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLFile.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -928,13 +934,15 @@
9B0417812390320A00C9EC4E /* TestHelpers */ = {
isa = PBXGroup;
children = (
C3279FC52345233000224790 /* TestCustomRequestCreator.swift */,
9B64F6752354D219002D1BB5 /* URL+QueryDict.swift */,
9B21FD762422C8CC00998B5C /* TestFileHelper.swift */,
9B4F4540244A2A9200C2CF7D /* HTTPBinAPI.swift */,
9BC139A524EDCAD900876D29 /* BlindRetryingTestInterceptor.swift */,
9BC139A724EDCE4F00876D29 /* RetryToCountThenSucceedInterceptor.swift */,
9B2B66F32513FAFE00B53ABF /* CancellationHandlingInterceptor.swift */,
9B4F4540244A2A9200C2CF7D /* HTTPBinAPI.swift */,
9BF6C91725194D7B000D5B93 /* MultipartFormData+Testing.swift */,
9BC139A724EDCE4F00876D29 /* RetryToCountThenSucceedInterceptor.swift */,
9BF6C99B25195019000D5B93 /* String+IncludesForTesting.swift */,
C3279FC52345233000224790 /* TestCustomRequestBodyCreator.swift */,
9B21FD762422C8CC00998B5C /* TestFileHelper.swift */,
9B64F6752354D219002D1BB5 /* URL+QueryDict.swift */,
);
name = TestHelpers;
sourceTree = "<group>";
Expand Down Expand Up @@ -1518,13 +1526,14 @@
9FF90A6A1DDDEB420034C3B6 /* InputValueEncodingTests.swift */,
E86D8E03214B32DA0028EFE1 /* JSONTests.swift */,
9F91CF8E1F6C0DB2008DD0BE /* MutatingResultsTests.swift */,
9BF6C95225194EA5000D5B93 /* MultipartFormDataTests.swift */,
9F295E301E27534800A24949 /* NormalizeQueryResults.swift */,
9FF90A6C1DDDEB420034C3B6 /* ParseQueryResponseTests.swift */,
9FE1C6E61E634C8D00C02284 /* PromiseTests.swift */,
F16D083B21EF6F7300C458B8 /* QueryFromJSONBuildingTests.swift */,
9FF90A6B1DDDEB420034C3B6 /* ReadFieldValueTests.swift */,
9B96500824BE6201003C29C0 /* RequestChainTests.swift */,
C338DF1622DD9DE9006AF33E /* RequestCreatorTests.swift */,
C338DF1622DD9DE9006AF33E /* RequestBodyCreatorTests.swift */,
9F19D8451EED8D3B00C57247 /* ResultOrPromiseTests.swift */,
9B4F4542244A2AD300C2CF7D /* URLSessionClientTests.swift */,
9B9BBB1A24DB75E60021C30F /* UploadTests.swift */,
Expand Down Expand Up @@ -1562,7 +1571,7 @@
9FF90A5B1DDDEB100034C3B6 /* GraphQLResponse.swift */,
C377CCAA22D7992E00572E03 /* MultipartFormData.swift */,
9F69FFA81D42855900E000B1 /* NetworkTransport.swift */,
9BEDC79D22E5D2CF00549BF6 /* RequestCreator.swift */,
9BEDC79D22E5D2CF00549BF6 /* RequestBodyCreator.swift */,
9B4F453E244A27B900C2CF7D /* URLSessionClient.swift */,
9B554CC3247DC29A002F452A /* TaskData.swift */,
);
Expand Down Expand Up @@ -2486,7 +2495,7 @@
9B260BF3245A026F00562176 /* RequestChain.swift in Sources */,
9FF90A611DDDEB100034C3B6 /* GraphQLResponse.swift in Sources */,
9F27D4641D40379500715680 /* JSONStandardTypeConversions.swift in Sources */,
9BEDC79E22E5D2CF00549BF6 /* RequestCreator.swift in Sources */,
9BEDC79E22E5D2CF00549BF6 /* RequestBodyCreator.swift in Sources */,
9BE071AD2368D08700FA5952 /* Collection+Helpers.swift in Sources */,
9FA6F3681E65DF4700BF8D73 /* GraphQLResultAccumulator.swift in Sources */,
9FF90A651DDDEB100034C3B6 /* GraphQLExecutor.swift in Sources */,
Expand Down Expand Up @@ -2515,6 +2524,7 @@
5BB2C0232380836100774170 /* VersionNumberTests.swift in Sources */,
9B78C71E2326E86E000C8C32 /* ErrorGenerationTests.swift in Sources */,
9FC9A9C81E2EFE6E0023C4D5 /* CacheKeyForFieldTests.swift in Sources */,
9BF6C99C25195019000D5B93 /* String+IncludesForTesting.swift in Sources */,
9F91CF8F1F6C0DB2008DD0BE /* MutatingResultsTests.swift in Sources */,
9B9BBB1C24DB760B0021C30F /* UploadTests.swift in Sources */,
9BC139A424EDCA6C00876D29 /* InterceptorTests.swift in Sources */,
Expand All @@ -2523,7 +2533,7 @@
9B4F4543244A2AD300C2CF7D /* URLSessionClientTests.swift in Sources */,
9F19D8461EED8D3B00C57247 /* ResultOrPromiseTests.swift in Sources */,
9F533AB31E6C4A4200CBE097 /* BatchedLoadTests.swift in Sources */,
C3279FC72345234D00224790 /* TestCustomRequestCreator.swift in Sources */,
C3279FC72345234D00224790 /* TestCustomRequestBodyCreator.swift in Sources */,
9B95EDC022CAA0B000702BB2 /* GETTransformerTests.swift in Sources */,
9FF90A6F1DDDEB420034C3B6 /* InputValueEncodingTests.swift in Sources */,
9FE1C6E71E634C8D00C02284 /* PromiseTests.swift in Sources */,
Expand All @@ -2536,11 +2546,13 @@
9B21FD752422C29D00998B5C /* GraphQLFileTests.swift in Sources */,
E86D8E05214B32FD0028EFE1 /* JSONTests.swift in Sources */,
9F8622FA1EC2117C00C38162 /* FragmentConstructionAndConversionTests.swift in Sources */,
C338DF1722DD9DE9006AF33E /* RequestCreatorTests.swift in Sources */,
C338DF1722DD9DE9006AF33E /* RequestBodyCreatorTests.swift in Sources */,
F16D083C21EF6F7300C458B8 /* QueryFromJSONBuildingTests.swift in Sources */,
9BF6C97025194ED7000D5B93 /* MultipartFormDataTests.swift in Sources */,
9FF90A711DDDEB420034C3B6 /* ReadFieldValueTests.swift in Sources */,
9F295E311E27534800A24949 /* NormalizeQueryResults.swift in Sources */,
9FF90A731DDDEB420034C3B6 /* ParseQueryResponseTests.swift in Sources */,
9BF6C94325194DE2000D5B93 /* MultipartFormData+Testing.swift in Sources */,
9B4F4541244A2A9200C2CF7D /* HTTPBinAPI.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
10 changes: 5 additions & 5 deletions Sources/Apollo/JSONRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation
/// A request which sends JSON related to a GraphQL operation.
open class JSONRequest<Operation: GraphQLOperation>: HTTPRequest<Operation> {

public let requestCreator: RequestCreator
public let requestBodyCreator: RequestBodyCreator

public let autoPersistQueries: Bool
public let useGETForQueries: Bool
Expand All @@ -25,7 +25,7 @@ open class JSONRequest<Operation: GraphQLOperation>: HTTPRequest<Operation> {
/// - autoPersistQueries: `true` if Auto-Persisted Queries should be used. Defaults to `false`.
/// - useGETForQueries: `true` if Queries should use `GET` instead of `POST` for HTTP requests. Defaults to `false`.
/// - useGETForPersistedQueryRetry: `true` if when an Auto-Persisted query is retried, it should use `GET` instead of `POST` to send the query. Defaults to `false`.
/// - requestCreator: An object conforming to the `RequestCreator` protocol to assist with creating the request body. Defaults to the provided `ApolloRequestCreator` implementation.
/// - requestBodyCreator: An object conforming to the `RequestBodyCreator` protocol to assist with creating the request body. Defaults to the provided `ApolloRequestBodyCreator` implementation.
public init(operation: Operation,
graphQLEndpoint: URL,
contextIdentifier: UUID? = nil,
Expand All @@ -36,11 +36,11 @@ open class JSONRequest<Operation: GraphQLOperation>: HTTPRequest<Operation> {
autoPersistQueries: Bool = false,
useGETForQueries: Bool = false,
useGETForPersistedQueryRetry: Bool = false,
requestCreator: RequestCreator = ApolloRequestCreator()) {
requestBodyCreator: RequestBodyCreator = ApolloRequestBodyCreator()) {
self.autoPersistQueries = autoPersistQueries
self.useGETForQueries = useGETForQueries
self.useGETForPersistedQueryRetry = useGETForPersistedQueryRetry
self.requestCreator = requestCreator
self.requestBodyCreator = requestBodyCreator

super.init(graphQLEndpoint: graphQLEndpoint,
operation: operation,
Expand Down Expand Up @@ -88,7 +88,7 @@ open class JSONRequest<Operation: GraphQLOperation>: HTTPRequest<Operation> {
autoPersistQueries = false
}

let body = self.requestCreator.requestBody(for: operation,
let body = self.requestBodyCreator.requestBody(for: operation,
sendOperationIdentifiers: self.sendOperationIdentifier,
sendQueryDocument: sendQueryDocument,
autoPersistQuery: autoPersistQueries)
Expand Down
67 changes: 67 additions & 0 deletions Sources/Apollo/RequestBodyCreator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Foundation
#if !COCOAPODS
import ApolloCore
#endif

public protocol RequestBodyCreator {
/// Creates a `GraphQLMap` out of the passed-in operation
///
/// - Parameters:
/// - operation: The operation to use
/// - sendOperationIdentifiers: Whether or not to send operation identifiers. Defaults to false.
/// - Returns: The created `GraphQLMap`
func requestBody<Operation: GraphQLOperation>(for operation: Operation,
sendOperationIdentifiers: Bool,
sendQueryDocument: Bool,
autoPersistQuery: Bool) -> GraphQLMap
}

extension RequestBodyCreator {
/// Creates a `GraphQLMap` out of the passed-in operation
///
/// - Parameters:
/// - operation: The operation to use
/// - sendOperationIdentifiers: Whether or not to send operation identifiers. Defaults to false.
/// - sendQueryDocument: Whether or not to send the full query document. Defaults to true.
/// - autoPersistQuery: Whether to use auto-persisted query information. Defaults to false.
/// - Returns: The created `GraphQLMap`
public func requestBody<Operation: GraphQLOperation>(for operation: Operation,
sendOperationIdentifiers: Bool = false,
sendQueryDocument: Bool = true,
autoPersistQuery: Bool = false) -> GraphQLMap {
var body: GraphQLMap = [
"variables": operation.variables,
"operationName": operation.operationName,
]

if sendOperationIdentifiers {
guard let operationIdentifier = operation.operationIdentifier else {
preconditionFailure("To send operation identifiers, Apollo types must be generated with operationIdentifiers")
}

body["id"] = operationIdentifier
}

if sendQueryDocument {
body["query"] = operation.queryDocument
}

if autoPersistQuery {
guard let operationIdentifier = operation.operationIdentifier else {
preconditionFailure("To enable `autoPersistQueries`, Apollo types must be generated with operationIdentifiers")
}

body["extensions"] = [
"persistedQuery" : ["sha256Hash": operationIdentifier, "version": 1]
]
}

return body
}
}

// Helper struct to create requests independently of HTTP operations.
public struct ApolloRequestBodyCreator: RequestBodyCreator {
// Internal init methods cannot be used in public methods
public init() { }
}
Loading