Amplify GraphQL Relational Schema Transformer

raw JSON →
2.21.34 verified Thu Apr 23 auth: no javascript

The `graphql-relational-schema-transformer` package is a foundational component within the AWS Amplify ecosystem, designed to facilitate the creation of GraphQL APIs from existing relational databases for use with AWS AppSync. As of version 2.21.34, it plays a crucial role in enabling developers to connect their AppSync GraphQL APIs to data sources like Amazon RDS (MySQL, PostgreSQL) and Aurora Serverless. This transformer inspects relational database schemas and automatically generates corresponding GraphQL types, along with the necessary AppSync resolvers and underlying AWS Lambda functions, to perform CRUD (Create, Read, Update, Delete) operations. While direct programmatic interaction with this specific package name might be less common for end-users, it underpins the functionality exposed through higher-level tools like the Amplify CLI's `amplify import api` command and the `@aws-amplify/graphql-api-construct` for AWS CDK deployments. It integrates with GraphQL Transformer v2's directive system, allowing the definition of relational models using `@model`, `@hasOne`, `@hasMany`, `@belongsTo`, and `@manyToMany` directives. This package is actively maintained as part of the broader AWS Amplify API category, with frequent updates often bundled within `@aws-amplify/amplify-category-api` releases.

error Failed to connect to RDS. Please ensure the database credentials and connection string are correct and accessible.
cause The Amplify CLI or transformer could not establish a connection to the specified relational database using the provided credentials or connection details.
fix
Verify database hostname, port, username, and password. Ensure the database is publicly accessible or that your VPC, security groups, and NACLs allow inbound traffic from the Amplify deployment environment (e.g., Lambda functions' VPCs) to the RDS instance.
error GraphQL schema validation failed. Unknown directive "@connection".
cause Attempting to use an older GraphQL Transformer v1 directive (`@connection`) in a GraphQL Transformer v2 (or later) schema, which has deprecated this directive.
fix
Update your GraphQL schema to use the new relational directives introduced in GraphQL Transformer v2, such as @hasOne, @hasMany, @belongsTo, and @manyToMany, to define relationships between models. Consult the Amplify GraphQL Transformer v2 documentation for updated syntax.
error Error: Table 'my_database.my_table' not found or inaccessible during schema inference.
cause The `graphql-relational-schema-transformer` attempted to infer the schema from a specified table, but the table either does not exist, or the provided database user lacks the necessary permissions to read its schema.
fix
Confirm the table name spelling and case sensitivity. Grant the database user SELECT privileges on the table and SHOW TABLES, SHOW COLUMNS (or equivalent metadata access) permissions on the database to allow schema inspection.
error Function invocation failed: Lambda couldn't find your 'index.handler' file. Please check your 'entry.py' or 'index.js' file in your custom resolver.
cause After `amplify push` or updates, the generated Lambda function for relational resolvers cannot locate the handler file, often due to changes in runtime versions or build processes.
fix
Check the CloudWatch logs for the specific Lambda function for detailed errors. Verify the configured Lambda runtime version (e.g., Python 3.12) and ensure your custom resolver code (if any) or the generated code is compatible and correctly packaged for that runtime. Re-run amplify push to ensure correct deployment artifacts.
breaking Migration from GraphQL Transformer v1 to v2 introduced significant breaking changes in how relational models and connections are defined. Older `@connection` directives were replaced by explicit `@hasOne`, `@hasMany`, `@belongsTo`, and `@manyToMany` directives. If you are upgrading an existing Amplify project, expect manual schema adjustments.
fix Review the AWS Amplify documentation for GraphQL Transformer v1 to v2 migration guides. Manually update your `schema.graphql` or `schema.sql.graphql` to use the new relational directives.
gotcha Incorrect or incomplete database connection details (hostname, port, database name, username, password, VPC configuration) are a frequent cause of deployment failures. The transformer needs secure and correct access to inspect the schema and generate resolvers.
fix Ensure all database connection parameters are correct and securely stored (e.g., in AWS Systems Manager Parameter Store or Secrets Manager). Verify VPC, security group, and network ACL configurations allow AppSync/Lambda to reach your RDS instance, especially if it's in a private subnet.
gotcha Schema evolution, particularly renaming GraphQL types that map to relational tables, can lead to unexpected behavior or data access issues. Amplify has specific mechanisms like `@mapsTo` for DynamoDB-backed models, but similar care is needed for relational sources to maintain consistency.
fix Plan schema changes carefully. For relational models, consider using a database migration tool to manage actual table renames. If a GraphQL type name changes, ensure any generated code or manual mappings account for the underlying relational table name, potentially using custom resolver overrides.
gotcha The generated Lambda resolvers often run on specific Python runtimes (e.g., Python 3.8, 3.9, 3.12). Recent Amplify updates have enforced newer Python versions (e.g., 3.8 -> 3.12 for searchable Lambda functions). If you have custom resolvers or rely on a specific runtime, ensure compatibility.
fix Regularly update your Amplify CLI and dependencies. If deploying custom Lambda functions, ensure their runtime environments are compatible with the latest Amplify-generated Lambda runtimes or specify a compatible version explicitly.
gotcha Upgrades within parent Amplify packages (like `amplify-category-api`) are migrating AWS SDK dependencies from v2 to v3. Custom Lambda resolvers or other custom code interacting with AWS services might require updates to use the AWS SDK for JavaScript v3 if they were written for v2.
fix When `amplify push` generates new resolvers, check the deployed Lambda code for SDK version. If you have custom Lambda functions, review the AWS SDK v3 migration guide to update your code if necessary. Leverage the AWS SDK v3's modular design for smaller bundles.
npm install graphql-relational-schema-transformer
yarn add graphql-relational-schema-transformer
pnpm add graphql-relational-schema-transformer

This quickstart demonstrates how to define a simple GraphQL schema with relational directives (`@model`, `@hasMany`, `@belongsTo`) and deploy it using the `@aws-amplify/graphql-api-construct` for AWS CDK, which internally leverages transformers like `graphql-relational-schema-transformer`. It also illustrates how to specify database connection parameters for an existing relational database.

import { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';
import { App, Stack } from 'aws-cdk-lib';
import { CfnParameter } from 'aws-cdk-lib';

const app = new App();
const stack = new Stack(app, 'MyAmplifyRelationalApiStack');

// Define your database connection details using CDK parameters or environment variables.
// In a real application, retrieve these securely (e.g., from AWS Secrets Manager).
const dbHost = new CfnParameter(stack, 'DbHost', { type: 'String', description: 'Database Hostname' }).valueAsString;
const dbName = new CfnParameter(stack, 'DbName', { type: 'String', description: 'Database Name' }).valueAsString;
const dbUser = new CfnParameter(stack, 'DbUser', { type: 'String', description: 'Database User' }).valueAsString;
const dbPassword = new CfnParameter(stack, 'DbPassword', { type: 'String', description: 'Database Password', noEcho: true }).valueAsString;

// A simplified GraphQL schema for a relational model.
// In a typical Amplify CLI workflow, this would be in `amplify/backend/api/<api-name>/schema.sql.graphql`
const relationalSchema = `
  type Post @model @hasMany(references: "Author") {
    id: ID!
    title: String!
    content: String
    authorId: ID
    author: Author @belongsTo(references: "Post")
  }

  type Author @model {
    id: ID!
    name: String!
    email: String!
    posts: [Post]
  }

  # Example of how to connect to an existing database table (e.g., in schema.sql.graphql)
  # Note: The actual connection parameters are provided at deployment time,
  # not directly in the GraphQL schema directives for relational sources.
`;

new AmplifyGraphqlApi(stack, 'MyRelationalApi', {
  apiName: 'myRelationalApi',
  definition: AmplifyGraphqlDefinition.fromString(relationalSchema, {
    // These are example settings; actual implementation varies by database and security setup.
    // The transformer would infer schema from the live database during 'amplify push'
    // or when using `amplify import api` via Amplify CLI.
    // For CDK, you might define the RDS data source and connect it.
    // This part is highly dependent on how your RDS instance is managed and exposed.
    database: {
      engine: 'MYSQL',
      vpcConfig: {
        vpcId: 'vpc-xxxxxxxxxxxxx', // Replace with your VPC ID
        securityGroupIds: ['sg-xxxxxxxxxxxxx'], // Replace with your Security Group ID
        subnetIds: ['subnet-xxxxxxxxxxxxx', 'subnet-yyyyyyyyyyyyy'], // Replace with your Subnet IDs
      },
      clusterIdentifier: 'my-rds-cluster',
      secretArn: 'arn:aws:secretsmanager:REGION:ACCOUNT:secret:rds-credentials-xxxxxx' // Example
    }
  })
});

app.synth();