aws-amplify / aws-amplify/amplify-cli
RFC: Amplify api pull command
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 825
- Avg merge
- 11d 23h
- Merged PRs (30d)
- 2
Description
**Overview**
Currently, if a GraphQL API is updated outside of the Amplify CLI, such as in the AppSync console or service API calls, there is no convenient way for the customers to pull down those updates to their local development environments.
Based on customer feedbacks, such as these feature requests for a “pull” command,
https://github.com/aws-amplify/amplify-cli/issues/174
https://github.com/aws-amplify/amplify-cli/issues/293
https://github.com/aws-amplify/amplify-cli/issues/1190
we are evaluating the “amplify api pull” command that aims to bridge this disconnection between the local development and the AppSync’s web console.
This RFC defines the use case, analyzes the problems and options, and asks the community to give us feedback and suggestions on this command.
**The use cases**
The following are the steps of the most common workflow for the `amplify api pull` command:
1. Customer adds a new GraphQL API to his project (or updates an existing API) in the local development environment and pushes local development to the cloud
$ amplify api add / update
$ amplify push
2. Customer goes to the AppSync console and makes modifications on the GraphQL API, such as adding a new type, adding/removing a field from a type, or changing some of the resolver mappings.
$ amplify api console
3. Customer comes back to the local development environment, pulls down the developments that happened in the AppSync console, and continues his local development.
$ amplify api pull
There’s another use case that is associated with a “pull” command, team member collaborations using the Amplify CLI: Developer A pushes his local development to the cloud, and developer B needs to pull down the changes to his local development environment. This use case is addressed by the amplify env pull (https://aws-amplify.github.io/docs/cli/multienv#team-members-sharing-the-same-dev-backend) command, which is already implemented, and out of the scope of this document.
The `amplify api pull` command focuses on giving the customer the ability to combine local developments using Amplify CLI with the developments in the AppSync’s web console or any other methods outside of the Amplify CLI management.
**Conversion between schemas**
In developing a GraphQL API, the developer’s input to the Amplify CLI is not a regular graphql schema, but a schema annotated with graphql transformer directives. The annotated schema is called the “input schema document”.
The Graphql Transformer first builds the annotated schema locally, transforms it into the API’s regular graphql schema, resolver mapping templates, and CloudFormation templates, etc.. Those build artifacts are the actual items used by the `amplilfy push` command to construct and update the GraphQL API in the cloud.
When retrieving the latest updates from the he AppSync’s web console, the AppSync's public API methods, such as 'getIntrospectionSchema', ‘listTypes’ and ‘listResolvers’ etc., return the regular schema, the resolver mapping templates and other resources. They are equivalent to the above mentioned build artifacts. And currently there is no tool to reverse engineer, and re-construct the annotated “input schema document” from the build artifacts.
To summarize, the AppSync console and the local development are represented by two different formats:
* Local: annotated schema
* AppSync console: regular schema and other resources:
The hard problem is how to diff them and represent the diffs in the local development’s input format: the annotated schema.
**The options**
1. *Reverse GraphQL Transformer’s build operation:*
Implement a full-fledged tool that reverses the GraphQL Transformer’s build operation; use it to construct the annotated schema from items retrieved from the AppSync service; and then use the constructed annotated schema to diff, resolve conflict and merge with the developer’s local “input schema document”.
This would be the ideal solution _*if it is possible*_. However, it does not seem to be a trivial problem upon examining the current operations, and we would first need to refactor the GraphQL Transformer to make sure all its operations have reverse operations.
2. *Best effort approach*:
Set the goal a little differently, from providing the pull command's functionalities in full, to that the cli will use its best effort to pull from the AppSync console. And if the cli cannot handle the situation, it will guide the customer to restore the project locally and in the cloud, so that she/he can continue to use the CLI in the project’s development. The ability of the “best effort” can be iteratively improved to include more and more use cases.
_*Pro*_: Although the scope is limited, the partial implementation can be useful in certain scenarios, and it preserves the input format: annotated schema.
_*Con*_: Can be confusing because “sometimes it works, sometimes it does not”; it can also be complicated to use when the cli tries to restore the project if it can not handle the discrepancies between the AppSync console and the local development.
3. *Use regular schema*
The pull command will replace the annotated schema with the regular schema. Developments after the pull command will be directly on the regular schema, the resolver mapping templates and the CloudFormation templates, etc.
New resources can still be set up by the GraphQL Transformer, for example, adding a new @model annotated type into the regular schema will set up the DynamoDB table etc.. Of course, the schema is now an annotated schema again.
_*Pro*_: Easier to implement than the other options. Can pull down all the developments happened in the AppSync console, it is a full implementation of the pull functionalities.
_*Con*_: If the customer starts with annotated schema, the execution of the pull command will change it to regular schema, it can be confusing. Development will involve both annotated schema and direct resource specifications, such as datasources and resolve mappings etc.. And there can be discrepancies and conflicts between themselves as the combined input documents, which introduces more complexities in the development.
Please comment with your thoughts and suggestions.
Contributor guide
Research direction
Start with the RFC's use cases and the conversion-between-schemas section, then review the existing amplify api and amplify env pull entry points mentioned in the issue. Compare the three proposed approaches for handling annotated local schemas versus AppSync's regular schemas, and treat a chosen, implementable direction with resolved trade-offs as the outcome.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, graphql, typescript
- Domain
- api, backend-api-design, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 15/100