amplify-category-api
amplify-category-api copied to clipboard
Support for SQL based SDL in Gen 2.
Environment information
System:
OS: macOS 14.5
CPU: (10) arm64 Apple M1 Max
Memory: 176.88 MB / 32.00 GB
Shell: /bin/zsh
Binaries:
Node: 20.14.0 - ~/.nvm/versions/node/v20.14.0/bin/node
Yarn: 1.22.17 - /opt/homebrew/bin/yarn
npm: 10.7.0 - ~/.nvm/versions/node/v20.14.0/bin/npm
pnpm: 8.15.6 - /opt/homebrew/bin/pnpm
NPM Packages:
@aws-amplify/backend: 1.0.4
@aws-amplify/backend-cli: 1.1.0
aws-amplify: 6.3.8
aws-cdk: 2.147.2
aws-cdk-lib: 2.147.2
typescript: 5.5.2
AWS environment variables:
AWS_SDK_LOAD_CONFIG = 1
AWS_STS_REGIONAL_ENDPOINTS = regional
AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
No CDK environment variables
Description
I appreciate the direction and development experience that Amplify Gen 2 offers. Features like personal sandboxes, TypeScript support, and CDK extensibility are excellent. However, the current Data Schema Builder in Amplify Gen 2 limits the options available to developers when defining their GraphQL APIs.
By introducing support for GraphQL SDL for SQL based schemas, Amplify can offer a familiar, more flexible and developer-friendly approach to schema design. I've detailed the challenges I've encountered while working with data schemas coupled to a relational database in this Discord discussion.
Key Issues with the Current Data Schema Builder:
-
Verbose Configuration: Configuring authentication, relationships, and renaming fields is excessively verbose compared to using AppSync directives. The configurations are split into different callbacks, making it difficult to get a comprehensive overview of a model's setup.
-
Limited API Surface Control: The Model Schema automatically exposes all database tables and columns without offering control over the API surface. This results in an unnecessary 1-to-1 mapping of DB rows to the GraphQL API. I prefer a tailored API that meets the specific needs of the client, allowing for custom naming conventions (e.g., snake_case to camelCase). The lack of flexibility in controlling the exposed API surface is a significant limitation.
-
Lack of Custom Field Resolvers: One of GraphQL's strengths is its ability to map each field to a resolver, enabling the client to request specific data. The Model Schema's approach of merely returning DB rows turns GraphQL into a glorified REST API. Custom field resolvers, such as the example below, are not possible:
type Post { id: String! title: String! localizedTitle(locale: String): String content: String! }
-
Limitations of Custom Types: Custom types cannot be used in arguments, preventing the creation of queries with the same structure as generated ones. Additionally, custom types that reference models are not supported, hindering the creation of custom list queries. For example, defining
ModelPostConnection
orModelPostFilterInput
is not possible:type ModelPostConnection { items: [Post]! nextToken: String } type Query { listPosts( id: ID, filter: ModelPostFilterInput, limit: Int, nextToken: String, sortDirection: ModelSortDirection ): ModelPostConnection }
Proposed Solution
Currently, defineData
supports SDL for DynamoDB-backed schemas, as outlined in this GitHub pull request. However, attempting to pass in a SQL-based schema results in errors because defineData
defaults to a DYNAMO_DATA_SOURCE_STRATEGY
. The DataProps
interface lacks the necessary API surface to override this default behavior.
Introducing support for SQL-based schemas and allowing developers to specify the data source strategy would greatly enhance the flexibility and usability of Amplify Gen 2 for a broader range of applications.
I'm aware that this will result in the loss of end-to-end typing. However, this is not much of an issue for customers who prefers to not use the data client, but instead use GraphQL clients (TanStack, Apollo, URQ etc) on the frontend, and a bespoke SQL Query Builder on the backend.