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

Fix request body creator non-default implementations getting hammered by compiler #1450

Merged
merged 4 commits into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions Sources/Apollo/RequestBodyCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,24 @@ public protocol RequestBodyCreator {
///
/// - Parameters:
/// - operation: The operation to use
/// - sendOperationIdentifiers: Whether or not to send operation identifiers. Defaults to false.
/// - sendOperationIdentifiers: Whether or not to send operation identifiers. Should default to `false`.
/// - sendQueryDocument: Whether or not to send the full query document. Should default to `true`.
/// - autoPersistQuery: Whether to use auto-persisted query information. Should default to `false`.
/// - Returns: The created `GraphQLMap`
func requestBody<Operation: GraphQLOperation>(for operation: Operation,
sendOperationIdentifiers: Bool,
sendQueryDocument: Bool,
autoPersistQuery: Bool) -> GraphQLMap
}

// MARK: - Default Implementation

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 {
sendOperationIdentifiers: Bool,
sendQueryDocument: Bool,
autoPersistQuery: Bool) -> GraphQLMap {
var body: GraphQLMap = [
"variables": operation.variables,
"operationName": operation.operationName,
Expand Down
5 changes: 4 additions & 1 deletion Sources/Apollo/UploadRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ open class UploadRequest<Operation: GraphQLOperation>: HTTPRequest<Operation> {
// Make sure all fields for files are set to null, or the server won't look
// for the files in the rest of the form data
let fieldsForFiles = Set(files.map { $0.fieldName }).sorted()
var fields = self.requestBodyCreator.requestBody(for: operation, sendOperationIdentifiers: shouldSendOperationID)
var fields = self.requestBodyCreator.requestBody(for: operation,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to not change this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to change due to the removal of the default values for these parameters

Copy link

@wangjiejacques wangjiejacques Oct 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @designatednerd , although the default values for these parameters has been removed, but I think it's a good idea to add a new extension method like this:

/// Don't override this method, override `requestBody(operation, false, true, false)` 
extension RequestBodyCreator {
    public func requestBody<Operation: GraphQLOperation>(for operation: Operation) {
        requestBody(operation, false, true, false)
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll consider that, but I am concerned that would run a significant risk of reintroducing this same problem.

sendOperationIdentifiers: shouldSendOperationID,
sendQueryDocument: true,
autoPersistQuery: false)
var variables = fields["variables"] as? GraphQLMap ?? GraphQLMap()
for fieldName in fieldsForFiles {
if
Expand Down
5 changes: 4 additions & 1 deletion Sources/ApolloWebSocket/WebSocketTransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,10 @@ public class WebSocketTransport {
}

func sendHelper<Operation: GraphQLOperation>(operation: Operation, resultHandler: @escaping (_ result: Result<JSONObject, Error>) -> Void) -> String? {
let body = requestBodyCreator.requestBody(for: operation, sendOperationIdentifiers: self.sendOperationIdentifiers)
let body = requestBodyCreator.requestBody(for: operation,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not change this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to change due to the removal of the default values for these parameters

sendOperationIdentifiers: self.sendOperationIdentifiers,
sendQueryDocument: true,
autoPersistQuery: false)
let sequenceNumber = "\(sequenceNumberCounter.increment())"

guard let message = OperationMessage(payload: body, id: sequenceNumber).rawMessage else {
Expand Down
15 changes: 12 additions & 3 deletions Tests/ApolloTests/GETTransformerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ class GETTransformerTests: XCTestCase {

func testEncodingQueryWithSingleParameter() {
let operation = HeroNameQuery(episode: .empire)
let body = requestBodyCreator.requestBody(for: operation, sendOperationIdentifiers: false)
let body = requestBodyCreator.requestBody(for: operation,
sendOperationIdentifiers: false,
sendQueryDocument: true,
autoPersistQuery: false)

let transformer = GraphQLGETTransformer(body: body, url: self.url)

Expand All @@ -28,7 +31,10 @@ class GETTransformerTests: XCTestCase {

func testEncodingQueryWithMoreThanOneParameterIncludingNonHashableValue() throws {
let operation = HeroNameTypeSpecificConditionalInclusionQuery(episode: .jedi, includeName: true)
let body = requestBodyCreator.requestBody(for: operation, sendOperationIdentifiers: false)
let body = requestBodyCreator.requestBody(for: operation,
sendOperationIdentifiers: false,
sendQueryDocument: true,
autoPersistQuery: false)

let transformer = GraphQLGETTransformer(body: body, url: self.url)

Expand Down Expand Up @@ -195,7 +201,10 @@ class GETTransformerTests: XCTestCase {

func testEncodingQueryWithNullDefaultParameter() {
let operation = HeroNameQuery()
let body = requestBodyCreator.requestBody(for: operation, sendOperationIdentifiers: false)
let body = requestBodyCreator.requestBody(for: operation,
sendOperationIdentifiers: false,
sendQueryDocument: true,
autoPersistQuery: false)

let transformer = GraphQLGETTransformer(body: body, url: self.url)

Expand Down
11 changes: 9 additions & 2 deletions Tests/ApolloTests/RequestBodyCreatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,25 @@ class RequestBodyCreatorTests: XCTestCase {
private let customRequestBodyCreator = TestCustomRequestBodyCreator()
private let apolloRequestBodyCreator = ApolloRequestBodyCreator()

func create<Operation: GraphQLOperation>(with creator: RequestBodyCreator, for query: Operation) -> GraphQLMap {
creator.requestBody(for: query,
sendOperationIdentifiers: false,
sendQueryDocument: true,
autoPersistQuery: false)
}

// MARK: - Tests

func testRequestBodyWithApolloRequestBodyCreator() {
let query = HeroNameQuery()
let req = apolloRequestBodyCreator.requestBody(for: query, sendOperationIdentifiers: false)
let req = self.create(with: apolloRequestBodyCreator, for: query)

XCTAssertEqual(query.queryDocument, req["query"] as? String)
}

func testRequestBodyWithCustomRequestBodyCreator() {
let query = HeroNameQuery()
let req = customRequestBodyCreator.requestBody(for: query, sendOperationIdentifiers: false)
let req = self.create(with: customRequestBodyCreator, for: query)

XCTAssertEqual(query.queryDocument, req["test_query"] as? String)
}
Expand Down
6 changes: 5 additions & 1 deletion Tests/ApolloTests/TestCustomRequestBodyCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import Apollo

struct TestCustomRequestBodyCreator: RequestBodyCreator {
public func requestBody<Operation: GraphQLOperation>(for operation: Operation, sendOperationIdentifiers: Bool) -> GraphQLMap {
func requestBody<Operation: GraphQLOperation>(
for operation: Operation,
sendOperationIdentifiers: Bool,
sendQueryDocument: Bool, autoPersistQuery: Bool) -> GraphQLMap {

var body: GraphQLMap = [
"test_variables": operation.variables,
"test_operationName": operation.operationName,
Expand Down