8

I am using AppSync for my APP. Here is a quick look of my Schema.graphql file

type Item @model
  @auth(rules: [
    { allow: public, provider: apiKey, operations: [read] },
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  name: String!
  soldUnits: String!
  soldAs: [Float!]
  price: Float!
  isAvailable: Boolean!
  availableAmount: Float!
  category: String!
  isVeg: Boolean!
  offer: [String!]
  about: String
  storage: String
  benifits: String
  otherInfo: String
  rating: Int
  keywords: [String!]
  reviews: [String]
  images: [String]
  updatedBy: String
  addedBy: String
  qty: Int
  inventroy: Inventory @connection(name: "ItemInventory")
}

type User @model {
  id: ID!
  firstName: String!
  lastName: String!
  about: String
  phoneNumber: String
  email: String
  countryCode: String
  addresses: [Address] @connection
  orders: [Order] @connection(name: "OwnOrder")
}

type CartItem {
    id: ID!
    count: Int!
    name: String!
    price: Float
}

type Address @model {
  id: ID!
  lat: Float!
  long: Float!
  fullAddress: String!
  apartment: String!
  street: String
  area: String!
  district: String!
  city: String
  state: String!
  zip: Int!
  country: String!
  phoneNumber: String!
}

type InventoryAddress @model {
  id: ID!
  address: Address @connection
  inventroy: Inventory! @connection(name: "InventoryAddress")
}

type Order @model {
  id: ID!
  orderdate: AWSDate!
  ordertime: AWSTime!
  deliverySlot: String!
  deliveryDate: AWSDate!
  deliveryInput: String!
  deliveryPhoneNumber: String!
  deliveryPhoneCountryCode: String!
  deliveryAddress: String!
  deliveredTime: AWSDate
  deliveredDate: AWSDate
  deliveryCharges: Float!
  totalAmount: Float!
  paidAmount: Float!
  discount: Float!
  unpaidAmount: Float!
  status: String!
  paymentMethod: String!
  paymentId: String!
  itemsCount: Int!
  items: [CartItem]
  deliverAssignedTo: Patron @connection(name: "PatronOrder")
  owner: User @connection(name: "OwnOrder")
  inventroyDetails: Inventory @connection(name: "InventoryOrder")
}

type Patron @model {
  id: ID!
  age: Int!
  firstName: String!
  lastName: String!
  about: String
  workTime: String
  rating: Int!
  reviews: [String]
  addressProof: String!
  role: String
  workArea: Address @connection
  address: Address @connection
  deliveries: [Order] @connection(name: "PatronOrder")
  inventroyDetails: Inventory! @connection(name: "PatronInventory")
  addedItems: [Item] @connection
}

type Inventory @model {
  id: ID!
  address: InventoryAddress @connection(name: "InventoryAddress")
  patron: [Patron] @connection(name: "PatronInventory")
  items: [Item] @connection(name: "ItemInventory")
  orders: [Order] @connection(name: "InventoryOrder")
  manager: Patron @connection
  admins: [Patron] @connection
}

This is my GraphQL Schema generated in AppSync. I am able to query the data and do create mutation, but update and delete mutation is not working.

mutation UpdateAddressInput {
  updateAddress(input:{
    id:"af5cd7e6-8213-48b6-aa8e-9d2d6999742c",
   area:"New Delhi"
  }){
    id,
    area
  }
}

This is an example query , as you can see the return data below, it's not reflecting in dynamoDB

{
  "data": {
    "updateAddress": {
      "id": "af5cd7e6-8213-48b6-aa8e-9d2d6999742c",
      "area": "Electronic City"
    }
  }
}
Subhendu Kundu
  • 3,618
  • 6
  • 26
  • 57
  • 1
    Did you figure this out? I'm in the same boat. I can create a record, then after that I can't update it, only the version increments. – Mark Jan 10 '21 at 19:46

2 Answers2

14

Even working with AWS Amplify, I prefer to go to the AppSync console and select the queries, and mutations this way you'll see what's happening and what's needed behind the scenes to do your mutations.

An update mutation sample bellow, extracted from the AppSync console - instead of using codegen from Amplify.

input UpdateRuralAddressInput {
    id: ID!
    latitude: String
    longitude: String
    stateCity: String
    status: Int
    _version: Int
}

Note that field version is required to do the update.

I'm just pointing it out to help others with this issue, that's how I'm working with Amplify + Appsync client in Lambdas

So, before applying any update mutation execute a "get by id" query, plus update the model that comes from the request body accordingly. This way not only the field version will remains Ok, but other aspects as well.

A sample of updating in the Lambda handler function. Note: You'll need to delete the property __typename

    const updateRuralAddressRequest = JSON.parse(event.body);
    
    const client = await appsyncClient.hydrated();

    const ruralAddressQuery = await client.query({ query: gql(queryRuralAddress), variables: { id: updateRuralAddressRequest.id } });
    const ruralAddressFromDb = ruralAddressQuery.data.getRuralAddress;


    const updateRuralAddressInput = { ...ruralAddressFromDb, ...updateRuralAddressRequest };
    delete updateRuralAddressInput.__typename;

    const data = await client.mutate({ mutation: gql(updateRuralAddressMutation), variables: { updateRuralAddressInput } });

Notice that both my query and my update mutation must contains the version field.

export const queryRuralAddress = `
  query GetRuralAddressByID($id: ID!) {
    getRuralAddress(id: $id) {
      id,
      latitude,
      longitude,
      stateCity,
      status,
      _version
    }
  }
`;

export const updateRuralAddressMutation = `
    mutation UpdateRuralAddress($updateRuralAddressInput:UpdateRuralAddressInput!) {
      updateRuralAddress(input: $updateRuralAddressInput) {
        id
        latitude
        longitude
        stateCity
        status,
        _version
      }
    }`;
Richard Lee
  • 2,136
  • 2
  • 25
  • 33
6

You’ll see an auto generated field “_version” in your dynamoDB Table. See the value of _version for the ID you want to update area field.when you fetch address,you'll get a field "_version". Try Something like this

mutation UpdateAddressInput {  
    updateAddress(input:{
     id:"af5cd7e6-8213-48b6-aa8e-9d2d6999742c",
     area:"New Delhi",

     _version:variable name // _version value in dynamoDB table for                                
                            //  the desired row.

    }){
    id, 
    area   
  }
}
  • I'm having this same issue, the version gets incremented but none of the data I set changes. – Mark Jan 10 '21 at 19:36
  • 1
    At the time of updating , are you passing the version ? For example , if version in database is 11 than when you want to update dataset you'll have to pass _version : 11. – Jaishil Bhavsar Jan 12 '21 at 05:01
  • 3
    Including version worked for me...also pointing out how ridiculous this is. Instead of a single update based on an ID, now you have to query to get current version and then update. – Sean Aug 01 '21 at 20:27
  • 3
    Running `amplify update api` and answering "NO" to the question => "enable conflict detection" + `amplify push` helped me, to get rid of the _version issue. For me it is ridiculous to can't find something in the docs of amplify. – Herr_Hansen Sep 29 '21 at 14:40
  • 2
    I can confirm that updating the api and answering "NO" to "enable conflict detection" does the trick. Thanks @Herr_Hansen – carlosbvz Oct 21 '21 at 03:17
  • I see this when I try to do `amplify update api`: The selected resource is not managed using AWS Cloudformation. Please use the AWS AppSync Console to make updates to your API. Is there another way to disable this? – Boris Mitioglov Dec 15 '21 at 04:19
  • 2
    Thank you. +1000 for the "Disable conflict detection" secret. Absolutely lame. – Ryan Mar 07 '22 at 22:22