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

Custom query input invalid value #3471

Closed
evan1108 opened this issue Jan 13, 2024 · 7 comments
Closed

Custom query input invalid value #3471

evan1108 opened this issue Jan 13, 2024 · 7 comments
Labels
api Issues related to the API category bug Something isn't working

Comments

@evan1108
Copy link

evan1108 commented Jan 13, 2024

Describe the bug

I'm trying to use an input type I defined in my scheam.graphql file, productFilterInput, as the input to a custom query that is using a lambda resolver. None of the values I use in the put for the query are valid and I continually get the error from GraphQL, "Amplify.GraphQLError(message: "Variable \'filter\' has an invalid value.", locations: Optional([Amplify.GraphQLError.Location(line: 1, column: 16)]), path: nil, extensions: nil)"

I'm able to pass a JSON query variable in the AppSync console and successfully execute my queries, e.g.

{"filter":{
  "brand":"test",
  "retailer":"test"
}}

Here's the type and input I've defined in my schema.graphql file:

type Query {
  products(filter: productFilterInput): [ProductData] @function(name: "siftAuroraDbLambda")
}

type ProductData
{
  id: String! # product ID
  name: String! # name
  description: String! # description
  price: String! # price
  brand: String! # brand
  retailer: String! # retailer
}

input productFilterInput {
  brand: String # brand
  retailer: String # retailer
}

And here's my custom GraphQL Request:

extension GraphQLRequest {
    static func products(filter: ProductFilterInput) -> GraphQLRequest<[ProductData]> {
        let operationName = "products"
        // I also tried encoding the `filter` argument to a JSON
        // let filterJSON = try? JSONEncoder().encode(filter)
        // let filterString = String(data: filterJSON ?? Data(), encoding: .utf8)
        let document = """
        query products($filter: productFilterInput!) {
          \(operationName)(filter: $filter) {
            id
            name
            description
            price
            brand
            retailer
          }
        }
        """
        return GraphQLRequest<[ProductData]>(
            document: document,
            variables: ["filter": filter],
            responseType: [ProductData].self,
            decodePath: operationName
        )
    }
struct ProductFilterInput: Codable, Identifiable {
    var id: String?
    var brand: String?
    var retailer: String?
}

And this is how I execute the request.

let request = GraphQLRequest<[ProductData]>.products(filter: filter)
let result = try await Amplify.API.query(request: request)

In the GraphQL extension, if I attempt to pass in the filter ProductInputFilter object directly, I get the error, "error APIError: Variables is a not a valid JSON object". If I try to serialize the filter object into a JSON String, I get the error I mentioned at the beginning, "Variable \'filter\' has an invalid value."

How am I supposed to pass an input type into my Swift GraphQL request? The documentation in the Amplify docs is not clear.

Steps To Reproduce

Steps to reproduce the behavior:
1. Create a custom lambda resolver, query, and input. Create a custom GraphQL Request. Create a custom Swift struct to represent the input type defined in the GraphQL.schema file.
2. Attempt to create an input object and request.
3. Build and run the app to execute the query.
4. See error

Expected behavior

A response is returned with the data from my DB (I'm using a custom lambda resolver that queries a PostgreSQL backend).

Amplify Framework Version

2.15.3

Amplify Categories

API

Dependency manager

Swift PM

Swift version

5.8

CLI version

12.8.2

Xcode version

15.0.1

Relevant log output

<details>
<summary>Log Messages</summary>


INSERT LOG MESSAGES HERE
```

Is this a regression?

Yes

Regression additional context

No response

Platforms

No response

OS Version

16.4

Device

iPhone 13 Pro, iPhone 14 Pro

Specific to simulators

No response

Additional context

No response

@harsh62 harsh62 added bug Something isn't working api Issues related to the API category labels Jan 15, 2024
@harsh62
Copy link
Member

harsh62 commented Jan 15, 2024

Thanks for opening the issue.. Our team will invetigate and provide and update.

@phantumcode
Copy link
Member

@evan1108 Can you enable verbose logging and provide the output logs when your attempting the request?

To enable verbose logging, add the following statement as part of your app startup sequence when you're initializing Amplify:

Amplify.Logging.logLevel = .verbose

Also, this code snippet seems to be imcomplete as the Identifiable protocol is not implemented.

struct ProductFilterInput: Codable, Identifiable {
    var brand: String?
    var retailer: String?
}

@phantumcode phantumcode added the pending-community-response Issue is pending response from the issue requestor label Jan 18, 2024
@evan1108
Copy link
Author

Here are the verbose logs for when I pass in a JSON String to variables in the GraphQL query. You're correct - I have more fields on ProductFilterInput but only included two for brevity. ProductFilterInput also has a field defined as var id: String?. I'll update the struct in my original post.

2024-01-18 11:43:58.692133-0600 siftapp[21358:501323] [AuthenticationFetchAuthSessionOperationHelper] Fetching current state
2024-01-18 11:43:58.692203-0600 siftapp[21358:501323] [AuthenticationFetchAuthSessionOperationHelper] Session exists, checking validity
GraphQLRequest<Array<ProductData>>(apiName: nil, document: "query products($filter: ProductFilterInput!) {\n  products(filter: $filter) {\n    id\n    brand\n    retailer\n  }\n}", variables: Optional(["filter": Optional("{\"retailer\":\"SSENSE\"}")]), responseType: Swift.Array<siftapp.ProductData>, decodePath: Optional("products"), options: nil)

....authentication logs....

2024-01-18 11:43:58.697231-0600 siftapp[21358:501322] [APIAPICategory] Starting query FDF07B95-C7BA-412B-B10B-7D8AF963DE12
2024-01-18 11:43:58.697377-0600 siftapp[21358:501322] [APIAPICategory] {
  "query" : "query products($filter: ProductFilterInput!) {\n  products(filter: $filter) {\n    id\n    brand\n    retailer\n    }\n}",
  "variables" : {
    "filter" : "{\"retailer\":\"SSENSE\"}"
  }
}

....authentication logs.... 

2024-01-18 11:43:59.170040-0600 siftapp[21358:501323] [APIAPICategory] Starting network task for query FDF07B95-C7BA-412B-B10B-7D8AF963DE12
Can not retrieve result : error  GraphQL service returned a successful response containing errors: [Amplify.GraphQLError(message: "Variable \'filter\' has an invalid value.", locations: Optional([Amplify.GraphQLError.Location(line: 1, column: 16)]), path: nil, extensions: nil)]

@github-actions github-actions bot removed the pending-community-response Issue is pending response from the issue requestor label Jan 18, 2024
@phantumcode
Copy link
Member

@evan1108 This code snippet seems to be working for me from the client side:

  let data = try? JSONEncoder().encode(filter)
  let jsonObject = try? JSONSerialization.jsonObject(with: data!, options: [])
  return GraphQLRequest<[ProductData]>(
      document: document,
      variables: ["filter": jsonObject],
      responseType: [ProductData].self,
      decodePath: operationName
  )

The output log for variables is:

  "variables" : {
    "filter" : {
      "retailer" : "SSENSE"
    }
  },

@evan1108
Copy link
Author

Thanks, @phantumcode, that works for me as well!

It would be great to see the Advanced Workflows Amplify documentation include examples where the parameters of the query are an object, like I have here, instead of just a couple string fields. Same for including an example of a schema.graphql file where a custom query uses an input type as a parameter instead of just primitive types.

Thank you for your response and help!

@phantumcode
Copy link
Member

Thanks @evan1108 for the feedback. I've submitted a PR to improve the documentation for the Advanced Workflow section for this use case. Closing this issue as you've been able to get your request working.

Copy link
Contributor

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

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

No branches or pull requests

3 participants