aws-appsyncaws-appsync-resolver

Appsync Intentionally Return Null for Nested Pipeline Giving Error


Essentially we have an optional 'childId' on the parent. The childId is used to get a child element 'Child' from DynamoDB.

If there is no childId present, we return a null value - as expected. The 'Child' is not a mandatory field on the schema so this should be fine.

Schema Snippet

type Parent {
 parentId: String!
 childId: String
 child: Child
}

I have a JS pipeline resolver attached to 'child', which has a DDB Datasource.

JS Pipeline Request Snippet

export function request(ctx) {
  /**
   * As childId is optional on Patent
   * We only want to run this query if childId is present
   */
  if (!ctx.source.childId){
    return
  }
  // DDB Query code here
}

JS Pipeline Response

export function response(ctx) {
  return ctx.result && ctx.result.items && ctx.result.items[0] ? ctx.result.items[0] : null
}

This all works as expected. If the child element is requested during the query, but no childId is present, it returns null.

However, it also attaches this error to the response

{
            "path": [
                "queryParent",
                0,
                "child"
            ],
            "data": null,
            "errorType": "Code",
            "errorInfo": null,
            "locations": [
                {
                    "line": 10,
                    "column": 13,
                    "sourceName": null
                }
            ],
            "message": "Request function code evaluated to null. It must match the data source request configuration."
        }

Anyone know how I can stop this error? All behaviour is as designed so I don't want any error to be appended to the response.


Solution

  • Found out that what works with the VTL resolver (#return) behaves differently when replicated with a JS resolver.

    For the JS resolver, when using return, AppSync would still attempt to run against the datasource, but with the value null - causing an error.

    In order to replicate the VTL #return and bypass the call to DDB (or assumably any datasource) entirely; one must use the 'runtime' util

    import { util, runtime } from '@aws-appsync/utils';
    
      if (!ctx.source.childId){
        runtime.earlyReturn();
      }
    

    See docs: https://docs.aws.amazon.com/appsync/latest/devguide/runtime-utils-js.html

    Typically after searching for a while, I found this thread immediately after posting my question.

    https://github.com/aws/aws-appsync-community/issues/261

    Maybe someone else as bad at reading documentation as myself will find this thread useful.