aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 79 forks source link

Unable to filter on scalar field backed by Lambda Resolver #761

Open SaileshKumar opened 3 years ago

SaileshKumar commented 3 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

GraphQL API

Amplify Categories

function, api

Environment information

``` # Put output below this line saileshkumar@Saileshs-MacBook-Pro ruso % npx envinfo --system --binaries --browsers --npmPackages --duplicates --npmGlobalPackages System: OS: macOS 11.3.1 CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz Memory: 351.20 MB / 32.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.6.0 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.21.0 - /usr/local/bin/npm Browsers: Chrome: 93.0.4577.82 Safari: 14.1 npmPackages: @aws-amplify/ui-react: ^1.0.6 => 1.0.6 @daily-co/daily-js: ^0.18.0 => 0.18.0 @date-io/date-fns: ^1.3.13 => 1.3.13 @material-ui/core: ^4.11.4 => 4.11.4 @material-ui/icons: ^4.11.2 => 4.11.2 @material-ui/pickers: ^3.3.10 => 3.3.10 @material-ui/styles: ^4.11.4 => 4.11.4 @reduxjs/toolkit: ^1.5.1 => 1.5.1 @testing-library/jest-dom: ^5.11.4 => 5.11.10 @testing-library/react: ^11.1.0 => 11.2.6 @testing-library/user-event: ^12.1.10 => 12.8.3 HelloWorld: 0.0.1 antd: ^4.16.13 => 4.16.13 aws-amplify: ^3.3.26 => 3.3.26 cypress: ^8.3.1 => 8.3.1 date-fns: ^2.23.0 => 2.23.0 flow-bin: ^0.148.0 => 0.148.0 hermes-inspector-msggen: 1.0.0 mixpanel-browser: ^2.41.0 => 2.41.0 moment: ^2.29.1 => 2.29.1 moment-timezone: ^0.5.33 => 0.5.33 react: ^17.0.2 => 17.0.2 react-dom: ^17.0.2 => 17.0.2 react-easy-crop: ^3.5.2 => 3.5.2 react-google-button: ^0.7.2 => 0.7.2 react-google-calendar-api: ^1.4.0 => 1.4.0 react-native: ^0.64.0 => 0.64.0 react-player: ^2.9.0 => 2.9.0 react-redux: ^7.2.4 => 7.2.4 react-router-dom: ^5.2.0 => 5.2.0 react-scripts: 4.0.3 => 4.0.3 react-social-icons: ^5.5.0 => 5.5.1 stream-chat: ^4.2.0 => 4.2.0 stream-chat-react: ^6.7.2 => 6.7.2 styled-components: ^5.3.1 => 5.3.1 styled-components/macro: undefined () styled-components/native: undefined () styled-components/primitives: undefined () web-vitals: ^1.0.1 => 1.1.1 npmGlobalPackages: @aws-amplify/cli: 5.2.1 npm: 7.21.0 ```

Describe the bug

I'm unable to filter on a scalar field that is backed by a resolver. if there is no resolver, it performs as expected. Example:

Here, liveStatus is backed by a resolver that is a lambda:

Query:
query MyQuery {
  listClasses {
    items {
      liveStatus
    }
  }
}

Response:
{
  "data": {
    "listClasses": {
      "items": [
        {
          "liveStatus": "UPCOMING_ONLY",
        },
        {
          "liveStatus": "PAST",
        },
        {
          "liveStatus": "LIVE_ONLY",
        },
        {
          "liveStatus": "PAST",
        }
      ]
    }
  }
}

But then:

query MyQuery {
  listClasses(filter: {liveStatus: {eq: "LIVE_ONLY"}}) {
    items {
      liveStatus
    }
  }
}

Yields:

{
  "data": {
    "listClasses": {
      "items": []
    }
  }
}

Expected behavior

Filtering on liveStatus should filter the items with their liveStatus, not return an empty list.

Reproduction steps

  1. Install + setup Amplify
  2. Add API with a model with some scalar field on it
  3. Go to AppSync, and attach scalar field to resolver that is a Lambda function
  4. Return any string in said Lambda Function
  5. Now when you query for your model, you'll see the field populated. But when you try to filter on the field, see that it doesn't work.

Code Snippet

// Put your code below this line. schema.graphql:

type Class
  @model {
  id: ID!
  liveStatus: String
}

Then Lambda Function:

exports.handler = async(event, context) => {
    return "TEST";
};

And query:

query MyQuery {
  listClasses(filter: {liveStatus: {eq: "TEST"}}) {
    items {
      liveStatus
    }
  }
}

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

iartemiev commented 2 years ago

Hey @SaileshKumar, please see this section of the docs for information on how to configure a Custom Lambda Resolver. You need to pass through the event object in your Lambda return statement.

josefaidt commented 2 years ago

Hey @SaileshKumar just wanted to follow up on this one to see if you're still experiencing this?

SaileshKumar commented 2 years ago

Hey @josefaidt , we are. Not sure I understand the suggestion from @iartemiev .

Our setup is as follows:

Schema:

type Class @model {
  live_status: String @function(name: "computeClassLiveStatus-${env}")
}

where computeClassLiveStatus is a lambda that looks something (simplified) like:

exports.handler = async (event, context) => {
  if ({SOMETHING}) { return "LIVE"}
  else { return "PAST" }
}

when I call getClass or listClasses and query for live_status, I'll correctly see either PAST or LIVE as a value.

However

query MyQuery {
  listClasses(filter: {liveStatus: {eq: "TEST"}}) {
    items {
      liveStatus
    }
  }
}

will return an empty array.

Is the suggestion to add a different return to the JS lambda computeClassLiveStatus?

josefaidt commented 1 year ago

Hey @SaileshKumar apologies for the delay here. I'm able to reproduce this, marking as a bug