Skip to content

feat: add overriden and extended resolver support#14795

Open
dgandhi62 wants to merge 29 commits intogen2-migrationfrom
extend-default-resolvers
Open

feat: add overriden and extended resolver support#14795
dgandhi62 wants to merge 29 commits intogen2-migrationfrom
extend-default-resolvers

Conversation

@dgandhi62
Copy link
Copy Markdown
Contributor

@dgandhi62 dgandhi62 commented Apr 22, 2026

How extended resolvers work

In Gen1, extended resolvers are VTL files with 6-segment filenames like Mutation.createBoard.init.2.req.vtl. The segments encode the target resolver (Mutation.createBoard), the pipeline slot (init), the execution order within that slot (2), and the template type (req). Gen1 places these as separate pipeline functions at the appropriate slot position.

In Gen2, we recreate this by generating AppsyncFunction constructs with a NoneDataSource and splicing them into the existing pipeline resolver's function array at the correct position.

Type-specific slot mapping

Different GraphQL operation types have different valid slots and different default pipeline structures:

  • Query: [auth0, postAuth0, DataResolverFn] — slots include preDataLoad/postDataLoad
  • Create/Update Mutation: [init0, auth0, postAuth0, DataResolverFn] — slots include preUpdate/postUpdate
  • Delete Mutation: [auth0, postAuth0, DataResolverFn] — same slots as create/update but shorter default pipeline
  • Subscription: [auth0, postAuth0, DataResolverFn] — slots include preSubscribe

The splice index computation accounts for these differences by selecting the correct base index mapping based on the operation type and field name prefix.

Override resolver filter fix

The generated override resolver loop previously matched all .req.vtl/.res.vtl files regardless of segment count. This caused 6-segment extended resolver files to be incorrectly applied as DataResolverFn template overrides. The filter now includes a f.split(".").length === 4 guard to only process 4-segment override files.

Splice index computation algorithm

The algorithm places custom functions into the Gen2 pipeline at positions that match their Gen1 slot behavior. It works in three steps:

1. Determine the default pipeline shape. The base indexes depend on which default functions exist:

Create/Update Mutation: [init0(0), auth0(1), postAuth0(2), DataResolverFn(3)]
Query / Delete Mutation / Subscription: [auth0(0), postAuth0(1), DataResolverFn(2)]

Each slot maps to a base index — the position after the last default function for that slot:

                        With init0    Without init0
init:                      1              0
preAuth:                   1              0
auth:                      2              1
postAuth:                  3              2
preDataLoad/preUpdate:     3              2
postDataLoad/postUpdate:   4              3
finish:                    4              3

2. Sort custom functions. Functions are sorted by slot (pipeline execution order), then by numeric order within the same slot. The order number in the filename only determines relative ordering among custom functions in the same slot — it does not map to an absolute pipeline position.

3. Compute splice indexes with a running offset. Walk through the sorted functions in order. For each function:

spliceIndex = baseIndex[slot] + offset
offset += 1

The offset accounts for prior insertions shifting subsequent positions. Example with init.2 and finish.1 on a create mutation:

Start:    [init0, auth0, postAuth0, DataResolverFn]

init.2  → base=1, offset=0 → splice(1)
Result:   [init0, init2, auth0, postAuth0, DataResolverFn]

finish.1 → base=4, offset=1 → splice(5)
Result:   [init0, init2, auth0, postAuth0, DataResolverFn, finish1]

Checklist

  • PR description included
  • yarn test passes
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)
  • New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies
  • Pull request labels are added

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@dgandhi62 dgandhi62 requested a review from a team as a code owner April 22, 2026 16:44
@dgandhi62 dgandhi62 changed the title feat: add extended resolver support feat: add overriden and extended resolver support Apr 22, 2026
…lvers

When a Gen1 project has custom VTL resolver files in
amplify/backend/api/<name>/resolvers/, the DataGenerator now:

- Detects .vtl files in the local resolvers directory
- Copies them to amplify/data/resolvers/ in the Gen2 output
- Generates backend.ts code that reads the VTL files at runtime
  and overrides pipeline function request/response mapping
  templates, replacing S3-based templates with inline content

Supports both .req.vtl (request) and .res.vtl (response)
resolver overrides. The generated for-of loop determines the
resolver type from the filename suffix and overrides the
corresponding mapping template properties.
…lvers

When a Gen1 project has custom VTL resolver files in
amplify/backend/api/<name>/resolvers/, the DataGenerator now:

- Detects .vtl files in the local resolvers directory
- Copies them to amplify/data/resolvers/ in the Gen2 output
- Generates backend.ts code that reads the VTL files at runtime
  and overrides pipeline function request/response mapping
  templates, replacing S3-based templates with inline content

Supports both .req.vtl (request) and .res.vtl (response)
resolver overrides. The generated for-of loop determines the
resolver type from the filename suffix and overrides the
corresponding mapping template properties.

Added 6 unit tests covering: no resolvers directory, empty
directory, VTL file detection, file copying, backend.ts
contributions, and mixed req/res file handling. All 20 tests
pass.
---
Prompt: A while ago, we refactored our gen2-migration code to a
new structure. The following is a pr from the old structure. I
need to replicate the same functionality - 14624
@dgandhi62 dgandhi62 force-pushed the extend-default-resolvers branch from 38d30a8 to b11c053 Compare April 22, 2026 18:56
@dgandhi62 dgandhi62 force-pushed the extend-default-resolvers branch from d6aedf0 to 62fe0b4 Compare April 23, 2026 19:54
@dgandhi62 dgandhi62 force-pushed the extend-default-resolvers branch from d89daad to 62fe0b4 Compare April 23, 2026 21:24
…fy-cli into extend-default-resolvers

# Conflicts:
#	amplify-migration-apps/mood-board/_snapshot.post.generate/amplify/backend.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants