Yasas Nanayakkara
Yasas Nanayakkara

Reputation: 105

Creating a resolver to update dynamoDB item through AppSync - AWS CDK

So I created a resolver to create an item in the table using the below code.

const configSettingsDS = api.addDynamoDbDataSource('configSettingsDynamoTable', configurationSettingsTable);

    configSettingsDS.createResolver({
        typeName:'Mutation',
        fieldName: 'createConfigSettings',
        requestMappingTemplate: appsync.MappingTemplate.dynamoDbPutItem(
            appsync.PrimaryKey.partition('id').auto(),
            appsync.Values.projecting('configSettings')),
        responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
    });

I can't seem to find one to replicate the same thing on an update operation. Any help is appreciated. Thanks

Upvotes: 1

Views: 1534

Answers (2)

Andy Brunner
Andy Brunner

Reputation: 3

Actually, DynamoDB provides an operation UpdateItem. But CDK has not implemented it (at least what it seems to me). My problem with appsync.Values.projecting is, if I don't know all fields in the table when executing a PutItem, I lose exsiting fields.

Upvotes: 0

tom van green
tom van green

Reputation: 1734

The update resolver works almost the same as the create resolver. In DynamoDB the operation for both is PutItem, so the same mapping template applies. You need to change the first parameter from appsync.PrimaryKey.partion('id').auto() to appsync.PrimaryKey.partion('id').is('<PATH_TO_YOUR_ID>').

The id can be part of the object you pass as input. Though I prefer to have it separate, so the id is not part of the input object. Here is a very basic example for both variants.

graphql schema:

// Input A includes ID
input InputA {
    id: ID!
    name: String!
}

// Input B does not include an ID
input InputB {
    name: String!
}

type Mutation {
    // Id is part of input
    updateA(input: InputA)

    // Id needs to be provided seperately
    updateB(id: ID!, InputB)
}

resolver code:

// Configure the resolver where ID is part of the input
const resolverA = datasource.createResolver({
    typeName: `Mutation`,
    fieldName: `updateA`,
    requestMappingTemplate: appsync.MappingTemplate.dynamoDbPutItem(
        appsync.PrimaryKey.partition('id').is('input.id'),
        appsync.Values.projecting('input'),
    ),
    responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});

// Configure the resolver where ID is provided as a separate input parameter.
const resolverB = datasource.createResolver({
    typeName: `Mutation`,
    fieldName: `updateB`,
    requestMappingTemplate: appsync.MappingTemplate.dynamoDbPutItem(
        appsync.PrimaryKey.partition('id').is('id'),
        appsync.Values.projecting('input'),
    ),
    responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});

I just had to solve the same problem for my project. Here are some snippets on how I have set it up:

Part of the graphql schema:

input Label {
    id: ID!
    name: String!
    imageUrl: String
}

input LabelInput {
    name: String!
    imageUrl: String
}

type Mutation {
    createLabel(input: LabelInput!): Label
    updateLabel(id: ID!, input: LabelInput!): Label
}

Corresponding resolvers in cdk:

datasource.createResolver({
    typeName: `Mutation`,
    fieldName: `createLabel`,
    requestMappingTemplate: appsync.MappingTemplate.dynamoDbPutItem(
        appsync.PrimaryKey.partition('id').auto(),
        appsync.Values.projecting('input'),
    ),
    responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});

datasource.createResolver({
    typeName: 'Mutation',
    fieldName: `updateLabel`,
    requestMappingTemplate: appsync.MappingTemplate.dynamoDbPutItem(
        appsync.PrimaryKey.partition('id').is('id'),
        appsync.Values.projecting('input'),
    ),
    responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});

Upvotes: 5

Related Questions