Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only one resolver is allowed per field #128

Open
alextriaca opened this issue Aug 18, 2020 · 6 comments
Open

Only one resolver is allowed per field #128

alextriaca opened this issue Aug 18, 2020 · 6 comments
Labels
bug Something isn't working

Comments

@alextriaca
Copy link

alextriaca commented Aug 18, 2020

AppSync does not seem to detach and attach resolvers when they are removed or renamed in CloudFormation resulting in edge cases that require manual intervention.

Reproduction Steps

The simplest version of this to replicate is to change the name of an AppSync resolver resulting in an error where the old resolver is still attached and the new one fails to attach with the error Only one resolver is allowed per field.

Using CDK for conciseness:

api = aws_appsync.GraphQLApi(
    self,
    "test_api",
    name="test_api",
    schema_definition=aws_appsync.SchemaDefinition.FILE,
    log_config=aws_appsync.LogConfig(
        exclude_verbose_content=False, field_log_level=aws_appsync.FieldLogLevel.ALL,
    ),
    schema_definition_file="resources/schema.graphql",
    xray_enabled=True,
)

api.add_none_data_source("ping", "Ping").create_resolver(
    type_name="Query",
    field_name="ping",
    request_mapping_template=aws_appsync.MappingTemplate.from_string(
        '{"version": "2018-05-29"}'
    ),
    response_mapping_template=aws_appsync.MappingTemplate.from_string(
        '$util.toJson("pong")'
    ),
)

Schema:

type Query {
    ping: String
}

The above code deploys an AppSync API and attaches a resolver that echos "pong" when the "ping" field is queried. Once deployed simply changing the name of the datasource reproduces this error. Line 12 can be changed to api.add_none_data_source("ping2", "Ping").create_resolver( (note "ping2"). This results in the old datasource being deleted (but not detached) and the new datasource being created and failing to attach due to it clashing with the old datasource.

Other

This issue has also been raised on the Amplify community - aws-amplify/amplify-cli#682


This is 🐛 Bug Report

@jpignata jpignata added the bug Something isn't working label Jun 6, 2021
edwardfoyle pushed a commit to aws-amplify/amplify-cli that referenced this issue Jun 24, 2021
Currently, we’re testing the iterative update by renaming the intial Todo model and updating it to Todos. Previously, this created a resolver called listTodoss (because it incorrectly blindly appended s). With the pluralization fix, it creates a resolver called listTodos - which unfortunately already exists and therefore appsync throws a Only one resolver is allowed per field error (aws/aws-appsync-community#128)
cjihrig pushed a commit to ctjlewis/amplify-cli that referenced this issue Jul 12, 2021
Currently, we’re testing the iterative update by renaming the intial Todo model and updating it to Todos. Previously, this created a resolver called listTodoss (because it incorrectly blindly appended s). With the pluralization fix, it creates a resolver called listTodos - which unfortunately already exists and therefore appsync throws a Only one resolver is allowed per field error (aws/aws-appsync-community#128)
@adamdry
Copy link

adamdry commented Oct 22, 2021

I also see this problem when using Terraform to deploy AppSync.

Update:
I deleted the whole AppSync API from the console, re-run the TF scripts and got the same error!

@p0wl
Copy link

p0wl commented Jan 26, 2022

Hey, there are a lot of similar issues (e.g. in the cdk repository: aws/aws-cdk#13269 (comment)), is there any progress on this issue?

@Rhys-Yakkr
Copy link

Rhys-Yakkr commented Feb 3, 2022

I encountered this issue when I renamed a table (@model), and had an explicitly named secondary index and relation (@hasMany.) It seemed to be a chicken & egg type issue, one that wasn't encountered in local testing. I resolved this by renaming my secondary index and query field, and then redeploying with amplify push. Demo below for illustration. Presumably, after you've completed this once, you could revert back to the original names & won't need to change the rest of your system to support the new naming. Hope the work around for this particular circumstance helps those who don't want to wait for a bug fix.

Child object property:
    example: ID! @index(name: "exampleName", sortKeyFields: ["from"], queryField: "exampleQueryField")
Parent object relation:
    exampleObjects: [Example] @hasMany(indexName: "exampleName", fields: ["id"])

Changed to:
Child object property:
    example: ID! @index(name: "exampleNameNew", sortKeyFields: ["from"], queryField: "exampleQueryFieldNew")
Parent object relation:
    exampleObjects: [Example] @hasMany(indexName: "exampleNameNew", fields: ["id"])```

alharris-at pushed a commit to aws-amplify/amplify-category-api that referenced this issue May 27, 2022
Currently, we’re testing the iterative update by renaming the intial Todo model and updating it to Todos. Previously, this created a resolver called listTodoss (because it incorrectly blindly appended s). With the pluralization fix, it creates a resolver called listTodos - which unfortunately already exists and therefore appsync throws a Only one resolver is allowed per field error (aws/aws-appsync-community#128)
@alextriaca
Copy link
Author

Since this update in CDK this is an even bigger issue now! CDK has standardised naming on resolvers but this causes all existing IDs to change. The suggestion there is to hardcode all of the IDs to the old versions but this isn't practical on any reasonably sized project. Any chance this could get some attention?

@phani-srikar
Copy link

phani-srikar commented Feb 23, 2023

👋 we are experiencing this issue for our customer use-case which can be described as below:
We have several AppSync resolvers that are part of say "TestStack" that is already deployed successfully. Now our use-case is to move some resolvers out to a new stack say "CustomTestStack".
We currently do this like suggested in this thread by keeping the logical ID of the resolvers and attached pipeline functions same in CustomTestStack (I have verified this from the CFN generated).

However, during the deployment it fails with only one resolver is allowed per field error.
The new stack also has a DependsOn relation to the original stack, so we would expect the resolvers to be deleted first before re-attaching them from the new stack.

I have attached the CFN logs below:
image

pic2
image

From the logs for original "Test" stack (pic2), we see that it's waiting in phase "update_complete_cleanup_in_progress" where I would assume the resolvers to be soft deleted and detached. Then it wouldn't cause the subsequent new stack to fail with the error mentioned above.

Please let me know if you need any other information.

@jackvial
Copy link

I ran into this issue yesterday. This is how I resolved it:

  1. List the resolvers for the model in question aws appsync list-resolvers --api-id yourappsncapid --type-name YourModelTypeName
    This will give you a JSON list of resolvers, the first one will likely have a source of DYNAMODB, this is the main model resolver. You should also see a second resolver with a fieldName that matches the field you are getting the only one reolver is allowed per field error
{
    "resolvers": [
        {
            "typeName": "YourModelTypeName",
            "fieldName": "foo",
            "resolverArn": "arn:aws:appsync:us-east-1:1234456789:apis/someid/types/YourModelTypeName/resolvers/foo",
            "requestMappingTemplate": "$util.qr......",
            "responseMappingTemplate": "$util.toJson($ctx.prev.result)",
            "kind": "PIPELINE",
            "pipelineConfig": {
                "functions": [
                    "....",
                    "..."
                ]
            }
        },
        {
            "typeName": "YourModelTypeName",
            "fieldName": "bar",
            "resolverArn": "arn:aws:appsync:us-east-1:1234456789:apis/someid/types/YourModelTypeName/resolvers/bar",
            "requestMappingTemplate": "...",
            "responseMappingTemplate": "$util.toJson($ctx.prev.result)",
            "kind": "PIPELINE",
            "pipelineConfig": {
                "functions": [
                    "ksdflsjfklsdfjsdfjlksdfj"
                ]
            }
        }
    ]
}
  1. Delete the existing field resolver
    aws appsync delete-resolver --api-id yourappsncapid --type-name YourModelTypeName --field-name bar

  2. Run the list command from step one again to confirm the field resolver has been deleted.

  3. Redeploy the same build and pray

In my case the build hit the error again but for a different model & field. I had to run the same procedure above for that model & field.

But then!!! My build succeeded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants