Search code examples
amazon-web-servicesgraphqlamazon-dynamodbaws-amplifyaws-appsync

Filter one to many exact data in appsync graphql


I have modeled this:

type FreightDriver
  @model
  @key(
    name: "byCityByState"
    fields: ["state", "city"]
    queryField: "freightDriversByStateByCity"
  ) {
  id: ID!
  name: String!
  state: String!
  city: String!
  trucks: [Truck] @connection(keyName: "byFreightDriver", fields: ["id"])
}

type Truck
  @model
  @key(name: "byFreightDriver", fields: ["freightDriverId", "tons"]) {
  id: ID!
  freightDriverId: ID!
  boxId: ID!
  brand: String!
  model: String!
  tons: Float!
  box: Box @connection(fields: ["boxId"])
}

type Box @model {
  id: ID!
  type: String!
  width: Float!
  height: Float!
  depth: Float!
}

And I'm querying the data like this:

query {
  freightDriversByStateByCity(state: "Jalisco", city: { eq: "Guadalajara" }) {
    items {
      id
      name
      city
      state
      trucks(tons: { eq: 12 }) {
        items {
          brand
          model
          box {
            type
          }
        }
      }
    }
  }
}

And I'm getting as a response this:

{
  "data": {
    "freightDriversByStateByCity": {
      "items": [
        {
          "id": "aebb6696-573d-41ed-894e-22b69264cace",
          "name": "Diey",
          "city": "Guadalajara",
          "state": "Jalisco",
          "trucks": {
            "items": [
              {
                "brand": "chevrolet",
                "model": "12",
                "box": {
                  "type": "Refrigerada"
                }
              }
            ]
          }
        },
        {
          "id": "6e8e6772-61e7-47d6-b134-d615a3c65f62",
          "name": "Roberto Mendez",
          "city": "Guadalajara",
          "state": "Jalisco",
          "trucks": {
            "items": []
          }
        },
        {
          "id": "d314808c-64e7-421d-b83b-008177ab6b25",
          "name": "Roberto Mendez",
          "city": "Guadalajara",
          "state": "Jalisco",
          "trucks": {
            "items": []
          }
        },
        {
          "id": "19847d0c-185c-48f6-9e5c-435e3907133a",
          "name": "Andrés",
          "city": "Guadalajara",
          "state": "Jalisco",
          "trucks": {
            "items": [
              {
                "brand": "chevrolet",
                "model": "1234",
                "box": {
                  "type": "Refrigerada"
                }
              },
              {
                "brand": "chevrolet",
                "model": "1234",
                "box": {
                  "type": "Grúa"
                }
              },
              {
                "brand": "chevrolet",
                "model": "12",
                "box": {
                  "type": "Refrigerada"
                }
              }
            ]
          }
        },
        {
          "id": "2c4c9e3a-bfe5-4d4e-bee7-3eddb1b8ef1b",
          "name": "Roberto Mendez ",
          "city": "Guadalajara",
          "state": "Jalisco",
          "trucks": {
            "items": []
          }
        },
        {
          "id": "cb4eb22c-aa54-416e-aecc-305a18bc9c83",
          "name": "Roberto Mendez",
          "city": "Guadalajara",
          "state": "Jalisco",
          "trucks": {
            "items": []
          }
        }
      ]
    }
  }
}

If you check, there are some with this:

"trucks": {
  "items": []
}

How can I avoid them? Is my model wrongly model? Thank you!


Solution

  • You can use mapping templates to modify the response data before it is returned to the client:

    The response mapping template is written with the Apache Velocity templating language (VTL) and translates the results of the resolver back into GraphQL.

    In this case you could check if trucks.items is empty and, if so, remove the items array from trucks before it's returned.

    More details here: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html