简体   繁体   中英

How to work with relationships in aws-appsync?

I am new to aws and graphql. I am working on appsync and trying to create relationships between two types. Following is my schema:

type BadCustomer {
    id: ID!
    name: String!
    phone: AWSPhone
    email: AWSEmail
    streetAddress: String
    dob: AWSDate
    passportNumber: String
    driversLicenceNumber: String
    ipAddress: AWSIPAddress
}

type BadCustomerConnection {
    items: [BadCustomer]
    nextToken: String
}

input CreateBadCustomerInput {
    name: String!
    phone: AWSPhone
    email: AWSEmail
    streetAddress: String
    dob: AWSDate
    passportNumber: String
    driversLicenceNumber: String
    ipAddress: AWSIPAddress
}

input CreateDamageInput {
    damage: Float!
    comment: String
}

input CreateIndustryInput {
    name: String!
}

input CreateSubscriberInput {
    name: String!
    email: AWSEmail!
    phone: AWSPhone
    streetAddress: String!
    subscriberIndustryId: ID!
}

type Damage {
    id: ID!
    customer: BadCustomer!
    industry: Industry!
    victim: Subscriber!
    damage: Float!
    comment: String
}

type DamageConnection {
    items: [Damage]
    nextToken: String
}

input DeleteBadCustomerInput {
    id: ID!
}

input DeleteDamageInput {
    id: ID!
}

input DeleteIndustryInput {
    id: ID!
}

input DeleteSubscriberInput {
    id: ID!
}

type Industry {
    id: ID!
    name: String!
    subscribers(
        filter: TableSubscriberFilterInput,
        sortDirection: ModelSortDirection,
        limit: Int,
        nextToken: String
    ): SubscriberConnection
}

type IndustryConnection {
    items: [Industry]
    nextToken: String
}

enum ModelSortDirection {
    ASC
    DESC
}

type Mutation {
    createIndustry(input: CreateIndustryInput!): Industry
    updateIndustry(input: UpdateIndustryInput!): Industry
    deleteIndustry(input: DeleteIndustryInput!): Industry
    createSubscriber(input: CreateSubscriberInput!): Subscriber
    updateSubscriber(input: UpdateSubscriberInput!): Subscriber
    deleteSubscriber(input: DeleteSubscriberInput!): Subscriber
    createBadCustomer(input: CreateBadCustomerInput!): BadCustomer
    updateBadCustomer(input: UpdateBadCustomerInput!): BadCustomer
    deleteBadCustomer(input: DeleteBadCustomerInput!): BadCustomer
    createDamage(input: CreateDamageInput!): Damage
    updateDamage(input: UpdateDamageInput!): Damage
    deleteDamage(input: DeleteDamageInput!): Damage
}

type Query {
    getIndustry(id: ID!): Industry
    listIndustries(filter: TableIndustryFilterInput, limit: Int, nextToken: String): IndustryConnection
    getSubscriber(id: ID!): Subscriber
    listSubscribers(filter: TableSubscriberFilterInput, limit: Int, nextToken: String): SubscriberConnection
    getBadCustomer(id: ID!): BadCustomer
    listBadCustomers(filter: TableBadCustomerFilterInput, limit: Int, nextToken: String): BadCustomerConnection
    getDamage(id: ID!): Damage
    listDamages(filter: TableDamageFilterInput, limit: Int, nextToken: String): DamageConnection
}

type Subscriber {
    id: ID!
    name: String!
    email: AWSEmail!
    phone: AWSPhone
    streetAddress: String!
    industry: Industry!
}

type SubscriberConnection {
    items: [Subscriber]
    nextToken: String
}

type Subscription {
    onCreateIndustry(id: ID, name: String): Industry
        @aws_subscribe(mutations: ["createIndustry"])
    onUpdateIndustry(id: ID, name: String): Industry
        @aws_subscribe(mutations: ["updateIndustry"])
    onDeleteIndustry(id: ID, name: String): Industry
        @aws_subscribe(mutations: ["deleteIndustry"])
    onCreateSubscriber(
        id: ID,
        name: String,
        email: AWSEmail,
        phone: AWSPhone,
        streetAddress: String
    ): Subscriber
        @aws_subscribe(mutations: ["createSubscriber"])
    onUpdateSubscriber(
        id: ID,
        name: String,
        email: AWSEmail,
        phone: AWSPhone,
        streetAddress: String
    ): Subscriber
        @aws_subscribe(mutations: ["updateSubscriber"])
    onDeleteSubscriber(
        id: ID,
        name: String,
        email: AWSEmail,
        phone: AWSPhone,
        streetAddress: String
    ): Subscriber
        @aws_subscribe(mutations: ["deleteSubscriber"])
    onCreateBadCustomer(
        id: ID,
        name: String,
        phone: AWSPhone,
        email: AWSEmail,
        streetAddress: String
    ): BadCustomer
        @aws_subscribe(mutations: ["createBadCustomer"])
    onUpdateBadCustomer(
        id: ID,
        name: String,
        phone: AWSPhone,
        email: AWSEmail,
        streetAddress: String
    ): BadCustomer
        @aws_subscribe(mutations: ["updateBadCustomer"])
    onDeleteBadCustomer(
        id: ID,
        name: String,
        phone: AWSPhone,
        email: AWSEmail,
        streetAddress: String
    ): BadCustomer
        @aws_subscribe(mutations: ["deleteBadCustomer"])
    onCreateDamage(id: ID, damage: Float, comment: String): Damage
        @aws_subscribe(mutations: ["createDamage"])
    onUpdateDamage(id: ID, damage: Float, comment: String): Damage
        @aws_subscribe(mutations: ["updateDamage"])
    onDeleteDamage(id: ID, damage: Float, comment: String): Damage
        @aws_subscribe(mutations: ["deleteDamage"])
}

input TableBadCustomerFilterInput {
    id: TableIDFilterInput
    name: TableStringFilterInput
    phone: TableStringFilterInput
    email: TableStringFilterInput
    streetAddress: TableStringFilterInput
    dob: TableStringFilterInput
    passportNumber: TableStringFilterInput
    driversLicenceNumber: TableStringFilterInput
    ipAddress: TableStringFilterInput
}

input TableBooleanFilterInput {
    ne: Boolean
    eq: Boolean
}

input TableDamageFilterInput {
    id: TableIDFilterInput
    damage: TableFloatFilterInput
    comment: TableStringFilterInput
}

input TableEventFilterInput {
    id: TableIDFilterInput
    name: TableStringFilterInput
    where: TableStringFilterInput
    when: TableStringFilterInput
    description: TableStringFilterInput
}

input TableFloatFilterInput {
    ne: Float
    eq: Float
    le: Float
    lt: Float
    ge: Float
    gt: Float
    contains: Float
    notContains: Float
    between: [Float]
}

input TableIDFilterInput {
    ne: ID
    eq: ID
    le: ID
    lt: ID
    ge: ID
    gt: ID
    contains: ID
    notContains: ID
    between: [ID]
    beginsWith: ID
}

input TableIndustryFilterInput {
    id: TableIDFilterInput
    name: TableStringFilterInput
}

input TableIntFilterInput {
    ne: Int
    eq: Int
    le: Int
    lt: Int
    ge: Int
    gt: Int
    contains: Int
    notContains: Int
    between: [Int]
}

input TableStringFilterInput {
    ne: String
    eq: String
    le: String
    lt: String
    ge: String
    gt: String
    contains: String
    notContains: String
    between: [String]
    beginsWith: String
}

input TableSubscriberFilterInput {
    id: TableIDFilterInput
    name: TableStringFilterInput
    email: TableStringFilterInput
    phone: TableStringFilterInput
    streetAddress: TableStringFilterInput
}

input UpdateBadCustomerInput {
    id: ID!
    name: String
    phone: AWSPhone
    email: AWSEmail
    streetAddress: String
    dob: AWSDate
    passportNumber: String
    driversLicenceNumber: String
    ipAddress: AWSIPAddress
}

input UpdateDamageInput {
    id: ID!
    damage: Float
    comment: String
}

input UpdateIndustryInput {
    id: ID!
    name: String
}

input UpdateSubscriberInput {
    id: ID!
    name: String
    email: AWSEmail
    phone: AWSPhone
    streetAddress: String
    subscriberIndustryId: ID
}

schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}

I want to setup a relationship between Subscribers and Industry . Each subscriber belongs to one industry. I have setup resolvers for Subscriber.industry and Industry.subscribers .

Subscriber.industry Resolver, Datasource Industry table:

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($util.defaultIfNullOrBlank($ctx.source.subscriberIndustryId, "___xamznone____"))
    }
}

Industry.subscribers Resolver, Datasource Subscriber table:

#set( $limit = $util.defaultIfNull($context.args.limit, 10) )
{
  "version": "2017-02-28",
  "operation": "Query",
  "query": {
      "expression": "#connectionAttribute = :connectionAttribute",
      "expressionNames": {
          "#connectionAttribute": "id"
    },
      "expressionValues": {
          ":connectionAttribute": {
              "S": "$context.source.id"
      }
    }
  },
  "scanIndexForward":   #if( $context.args.sortDirection )
    #if( $context.args.sortDirection == "ASC" )
true
    #else
false
    #end
  #else
true
  #end,
  "filter":   #if( $context.args.filter )
$util.transform.toDynamoDBFilterExpression($ctx.args.filter)
  #else
null
  #end,
  "limit": $limit,
  "nextToken":   #if( $context.args.nextToken )
"$context.args.nextToken"
  #else
null
  #end
}

I have following queries:

query ListIndustries {
  listIndustries {
    items {
      id
      name
     subscribers {
      items {
        id
        name
        streetAddress
      }
    }

    }
  }
}


query ListSubscribers {
  listSubscribers{
    items {
      id
      name
      industry {
        name
      }
    }
  }
}

If i run ListSubscribers query on appsync console, it gives me the desired result, like:

{
  "data": {
    "listSubscribers": {
      "items": [
        {
          "id": "d04d6ef4-95bf-4b01-9a6a-13f550dbfa8f",
          "name": "John Doe",
          "industry": {
            "name": "Real Estate"
          }
        },
        {
          "id": "96fa3e60-fdcf-4a6d-a3b6-72ec2c4701d1",
          "name": "Jane Doe",
          "industry": {
            "name": "Ecommerce"
          }
        },
        {
          "id": "413dd506-afd4-474e-a850-54a39eb1eeeb",
          "name": "John Doe",
          "industry": {
            "name": "Real Estate"
          }
        }
      ]
    }
  }
}

But if I run ListIndustries query, it does not give me the list of subscribers in that industry, like:

{
  "data": {
    "listIndustries": {
      "items": [
        {
          "id": "b904d8f3-b504-48e0-b28f-0f9ac1742186",
          "name": "Real Estate",
          "subscribers": {
            "items": []
          }
        },
        {
          "id": "167b87f2-3342-4390-80af-df53ba3c6f73",
          "name": "Ecommerce",
          "subscribers": {
            "items": []
          }
        }
      ]
    }
  }
}

Need someone who can help me out with this.

I will need a bit more information to be sure but it looks like the Industry.subscribers resolver may be misconfigured. Your query expression currently specifies:

"query": {
      "expression": "#connectionAttribute = :connectionAttribute",
      "expressionNames": {
          "#connectionAttribute": "id"
    },
      "expressionValues": {
          ":connectionAttribute": {
              "S": "$context.source.id"
      }
    }
  }
// There is no "index" so this is trying to query the primary index.

Which says, "Query the primary index where the 'id' = $ctx.source.id". Based on the objects you pasted, it looks like your Subscriber objects use $util.autoId() and thus the subscriber 'id' will never equal the industry 'id'. If using the Amplify CLI's @connection directive, a GSI will have been created on the Subscriber table with a hash key called 'subscriberIndustryId' by default. The Industry.subscribers resolver should query that index where the "subscriberIndustryId = $ctx.source.id". If you are not using the CLI and @connection, you can also implement this pattern yourself.

EG this should do the trick:

"query": {
      "expression": "#connectionAttribute = :connectionAttribute",
      "expressionNames": {
          "#connectionAttribute": "subscriberIndustryId"
    },
      "expressionValues": {
          ":connectionAttribute": {
              "S": "$context.source.id"
      }
    }
  },
"index": "gsi-IndustrySubscribers"

I missed index in Industry.subscribers resolver. Adding it fixed the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM