2
votes

How would you deal with interfaces and using them for connections in a data model using the AWS Amplify Model Transforms?

interface User @model {
  id: ID
  email: String
  created: AWSTimestamp
}

type ActiveUser implements User {
  id: ID
  first: String
  last: String
  email: String
  created: AWSTimestamp
}

type InvitedUser implements User {
  id: ID
  email: String
  created: AWSTimestamp
  invitedBy: String
}

type Team @model {
  users: [User] @connection
}

It seems like my choices are to put @model on the types but then I get separate Dynamo tables and queries on the Query once amplify update api is run.

Can the transformer support interfaces as documented here: https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html

I also found some support tickets, but was wondering if there was anything out there that enabled this feature. Here are the support tickets I found:

https://github.com/aws-amplify/amplify-cli/issues/1037

https://github.com/aws-amplify/amplify-cli/issues/202

2

2 Answers

1
votes

You only use @connection to link two databases together (which must be made from type and not interface), so if you don't want to do that then just get rid of the @connection and the Team database will simply have users be of type [User]. I am not entirely what you want to do but I would do something like:

type User @model {
  id: ID
  first: String!
  last: String!
  email: String!
  created: AWSTimestamp
  isActive: boolean
  invitedBy: String
  team: Team @connection(name: "UserTeamLink")
}

type Team @model {
  users: [User!] @connection(name: "UserTeamLink")
}

Where the fields first, last, and email are required when creating a new user, and you can distinguish between an active user with a boolean, and when you query the User database it returns the Team item from the Team database as well (I am guessing you want other fields like team name, etc.?), so when you create a Team object you pass in the teamUserId (not shown below but created when using amplify) that will allow you to attach a newly created Team to an existing user or group of users.

0
votes

I think you could keep the common fields in User, and extra info in separate type. Not sure if this is the best practice, but it should work for this scenario

enum UserType {
  ACTIVE
  INVITED
}

type User @model @key(name:"byTeam", fields:["teamID"]){
  id: ID!
  teamID: ID!
  email: String
  created: AWSTimestamp
  type: UserType
  activeUserInfo: ActiveUserInfo @connection(fields:["id"])
  invitedUserInfo: InvitedUserInfo @connection(fields:["id"])

}

type ActiveUserInfo @key(fields:["userID"]){
  userID: ID!
  first: String
  last: String
}

type InvitedUserInfo @key(fields:["userID"]){
  userID: ID!
  invitedBy: String
}

type Team @model {
  id:ID!
  users: [User!] @connection(keyName:"byTeam", fields:["id"])
}