How to filter an AWS Amplify GraphQL query to pull data and fields from two tables?

Viewed 539

I am very new to AWS Amplify's GraphQL, and am struggling to get the correct data returned to me when I execute the GraphQL query I created.

Starting at the top, I have 3 tables or models: UserTB, UserRoleTB, and RoleTB.

  • UserTB holds a list of all created users. One to many relationship with UserRoleTB
  • UserRoleTB holds a list of all Users and their assigned Roles
  • RoleTB holds a list of all roles. One to Many relationship with UserRoleTB

GraphQL Schemas:

type UserRoleTB @model @auth(rules: [{allow: public}]) {
  id: ID!
  roletbID: ID! @index(name: "byRoleTB")
  usertbID: ID! @index(name: "byUserTB")
}

type RoleTB @model @auth(rules: [{allow: public}]) {
  id: ID!
  roleName: String
  roleDescription: String
  UserRoleTBS: [UserRoleTB] @hasMany(indexName: "byRoleTB", fields: ["id"])
}

type UserTB @model @auth(rules: [{allow: public}]) {
  id: ID!
  username: String
  name: String
  email: String
  password: String
  lastLogin: String
  UserRoleTBS: [UserRoleTB] @hasMany(indexName: "byUserTB", fields: ["id"])
}

I created two queries that will return all data from the UserRoleTB and the UserTB.

Queries:

export const listUserTBS = /* GraphQL */ `
  query ListUserTBS(
    $filter: ModelUserTBFilterInput
    $limit: Int
    $nextToken: String
  ) {
    listUserTBS(filter: $filter, limit: $limit, nextToken: $nextToken) {
      items {
        id
        username
        name
        email
        password
        lastLogin
        createdAt
        updatedAt
        _version
        _deleted
        _lastChangedAt
      }
      nextToken
      startedAt
    }
  }
`;
export const listUserRoleTBS = /* GraphQL */ `
  query ListUserRoleTBS(
    $filter: ModelUserRoleTBFilterInput
    $limit: Int
    $nextToken: String
  ) {
    listUserRoleTBS(filter: $filter, limit: $limit, nextToken: $nextToken) {
      items {
        id
        roletbID
        createdAt
        updatedAt
        _version
        _deleted
        _lastChangedAt
      }
      nextToken
      startedAt
    }
  }
`;

I need to apply a filter to these where if users have a specific role assigned to them, it returns that user. For example, I will run the listUserRoleTBS query and apply a filter that does just that:

query Example {
  listUserRoleTBS(filter: {roletbID: {eq: "0f16af1f-007d-4a46-b6c1-799539ac1a0f"}}) {
    items {
      usertbID
    }
  }
}

which returns the following:

{
  "data": {
    "listUserRoleTBS": {
      "items": [
        {
          "usertbID": "b0e294de-32cb-4fa4-8ca8-c42cb191d26f"
        },
        {
          "usertbID": "22bda12a-8399-458d-9b15-0e83864125b5"
        },
        {
          "usertbID": "89f9c1c4-fa5a-44da-b245-e5add7abd436"
        }
      ]
    }
  }
}

In addition to the displaying the usertbID, I also need to display the name field from the UserTB table. However, it doesn't seem possible since it does not belong to the UserRoleTB table. It appears I may only be able to use the PK of the UserTB table (usertbID) as an option for response. Having the name field in the response is important because that field will be used to populate a drop-down list on a front-end GUI

Is there any way I can add the name field from UserTB to this query? If not, what are my options?

Additionally, I tried a different approach where I run the listUserTBS query with the following filter:

query Example {
  listUserTBS {
    items {
      name
      UserRoleTBS(filter: {roletbID: {eq: "0f16af1f-007d-4a46-b6c1-799539ac1a0f"}}) {
        items {
          roletbID
        }
      }
    }
  }
}

and it provided the following result:

{
  "data": {
    "listUserTBS": {
      "items": [
        {
          "name": "Joe",
          "UserRoleTBS": {
            "items": [
              {
                "roletbID": "0f16af1f-007d-4a46-b6c1-799539ac1a0f"
              }
            ]
          }
        },
        {
          "name": "brandon",
          "UserRoleTBS": {
            "items": [
              {
                "roletbID": "0f16af1f-007d-4a46-b6c1-799539ac1a0f"
              }
            ]
          }
        },
        {
          "name": "glen",
          "UserRoleTBS": {
            "items": [
              {
                "roletbID": "0f16af1f-007d-4a46-b6c1-799539ac1a0f"
              }
            ]
          }
        },
        {
          "name": "dave",
          "UserRoleTBS": {
            "items": []
          }
        },
        {
          "name": "stewart",
          "UserRoleTBS": {
            "items": []
          }
        }
      ]
    }
  }

As you can see, it will give me every user within the system, and if a user has the specified role, it will display the role. However, the downside is it will fetch literally ever user even if they don't have the role. I don't need every user, just a subset.

0 Answers
Related