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

feat: API.swift compatibility with AWSAPIPlugin #630

Merged
merged 3 commits into from
Aug 3, 2023
Merged

Conversation

lawmicha
Copy link
Member

@lawmicha lawmicha commented Jul 14, 2023

Description of changes

Currently developers that have an AppSync backend that was not provisioned with Amplify CLI can still generate the API.swift file from the introspection schema. This file has a hard dependency on iOS AppSync SDK client.. The top of API.swift contains imports AWSAppSync.

This file is pretty useful as it contains all the different operations available and components to successfully make a request, but cannot be used with Amplify's APIPlugin. This PR makes the API.swift file compatible with Amplify AWSAPIPlugin, removing the dependency on AppSync SDK.

  1. If can import AWSAPIPlugin, declare the types required to compile API.swift in-line. The required types were extracted out of AWSAppSync SDK codebase. Additionally, the Data types were made decodable, to allow them to be passed to Amplify.GraphQLRequest as the type to decode to.
  2. Fallback to importing AWSAppSync. This is to allow backwards compatibility with existing app clients. Developers may continue to their existing workflow in updating their schema, and regenerate the API.swift file, while not having to change their code to use AWSAPIPlugin.

We considered that if the developer has AppSync SDK and Amplify already in the same app, and API.swift was compilng due to AppSync SDK. The developer is most likely using AppSync SDK to interact with the backend, while the rest of Amplify (excluding AWSAPIPlugin) for the remaining plugins. If they did not add AWSAPIPlugin, there's no impact and they can upgrade to use AWSAPIPlugin when they are ready to.

if AWSAPIPlugin was added, it may have been

  1. Added accidentally and unused, developer may have to remove the AWSPIPlugin so it continues to compile with AWSAppSync import, or upgrade to AWSAPIPlugin call pattern in their code.
  2. The developer is using AWSAPIPlugin's REST APIs and AWSAppSync SDK. We believe the number of customers in this use case is near zero. Because we think this is an edge case, the path to unblock the customer is that they will have to upgrade to use AWSAPIPlugin, or modify the API.swift to reverse the changes to import AWSAppSync instead.
  3. The developer is using AWSAPIPlugin's GraphQL requests already, and included AppSync SDK to compile the API.swift successfully. The developer can now remove AppSync SDK as it is an unused dependency.

The upgrade guide is meant for both existing customers to move to AWSAPIPlugin and new customers that have built AppSync backends without using the Amplify's provisioning, see upgrade guide PR for more details: aws-amplify/docs#5649

Issue #, if available

Description of how you validated changes

Local testing:

nvm use v14 && yarn clean && rm -rf node_modules && yarn && yarn build && yarn test

amplify-dev testing

nvm use 16.14.0 && yarn setup-dev

We validate the new API.swift file compiles and works during runtime by the integration tests in the following PRs:

Tagged release

@aws-amplify/[email protected]

example of CLI required changes to create CLI tagged release: aws-amplify/amplify-cli@3e4d27a

Checklist

  • PR description included
  • yarn test passes
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)
  • Breaking changes to existing customers are released behind a feature flag or major version update
  • Changes are tested using sample applications for all relevant platforms (iOS/android/flutter/Javascript) that use the feature added/modified

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@lawmicha lawmicha force-pushed the lawmicha.swift-codegen branch 4 times, most recently from fe0e112 to 8b46ccf Compare July 20, 2023 15:01
@codecov-commenter
Copy link

Codecov Report

Merging #630 (8b46ccf) into main (ffd7cf7) will increase coverage by 1.45%.
The diff coverage is 33.33%.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

@@            Coverage Diff             @@
##             main     #630      +/-   ##
==========================================
+ Coverage   84.44%   85.89%   +1.45%     
==========================================
  Files         152      153       +1     
  Lines        6435     7495    +1060     
  Branches     1383     1956     +573     
==========================================
+ Hits         5434     6438    +1004     
- Misses        901      964      +63     
+ Partials      100       93       -7     
Impacted Files Coverage Δ
...raphql-types-generator/src/swift/codeGeneration.ts 82.91% <20.00%> (-0.77%) ⬇️
...s-generator/src/swift/appSyncCompatibilityTypes.ts 100.00% <100.00%> (ø)

... and 116 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@lawmicha lawmicha marked this pull request as ready for review July 20, 2023 16:13
@lawmicha lawmicha requested a review from a team as a code owner July 20, 2023 16:13
@lawmicha lawmicha changed the title feat: swift codegen updates for API.swift feat: API.swift compatibility with AWSAPIPlugin Jul 20, 2023
@amplify-data-ci amplify-data-ci dismissed their stale review July 21, 2023 00:18

wrong account

AaronZyLee
AaronZyLee previously approved these changes Jul 21, 2023
@lawmicha lawmicha force-pushed the lawmicha.swift-codegen branch 3 times, most recently from 209646f to 114ce84 Compare July 21, 2023 15:40
Comment on lines +95 to +108
extension GraphQLSelectionSet {
public init(from decoder: Decoder) throws {
if let jsonObject = try? APISwiftJSONValue(from: decoder) {
let encoder = JSONEncoder()
let jsonData = try encoder.encode(jsonObject)
let decodedDictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: Any]
let optionalDictionary = decodedDictionary.mapValues { $0 as Any? }

self.init(snapshot: optionalDictionary)
} else {
self.init(snapshot: [:])
}
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This is where the custom decoder was added. It uses an internally defined JSON value type called APISwiftJSONValue (to avoid developer defined "JSONValue" type) to get the data into an JSON object before serializing and deserializing back to the expected output a Snapshot (typealias for [String:Any?]))

@dpilch
Copy link
Member

dpilch commented Jul 21, 2023

Are there any unit tests covering this change?

5d
5d previously approved these changes Jul 22, 2023
@lawmicha
Copy link
Member Author

Are there any unit tests covering this change?

good point, @dpilch just added one to verify the fileHeader function!

dpilch
dpilch previously approved these changes Jul 24, 2023
@dpilch dpilch merged commit 9fe2e32 into main Aug 3, 2023
4 checks passed
@dpilch dpilch deleted the lawmicha.swift-codegen branch August 3, 2023 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants