awslabs / aws-mobile-appsync-sdk-ios

iOS SDK for AWS AppSync.
https://awslabs.github.io/aws-mobile-appsync-sdk-ios/
Other
262 stars 130 forks source link

Omitted optional values are converted to null when using lambda resolver #302

Closed munibrahman closed 11 months ago

munibrahman commented 5 years ago

Describe the bug Given that GraphQL arguments without ! are treated as optional values. If one is to use the sdk, and pass a nil value to the argument that allows optional values, it gets converted to null in the resolver.

If the same endpoint is called via the web console, and that argument is omitted completely, the value is never passed via resolver at all.

I am using a lambda datasource

To Reproduce

  1. Create a query or mutation with optional arguments. For example.

    listCars(limit: int, numWheels: int): [Car]

  2. Add a lambda resolver that simply prints the events as they are received.

  3. Call the endpoint using the Query Editor with the query listCars(limit: 10). The arguments passed to the lambda function will be.

    "arguments": { "limit": 10 }

  4. Call the same endpoint via the ios sdk, and only pass values for the limit and nil for numWheels or only set the value for limit, post ListCarsQuery.init().

    "arguments": { "limit": 10, "numWheels": null }

No matter how the query is instantiated using swift, either by passing the nil arguments in init or by calling init() and then setting the values later on, the output is the same regardless..

Expected behavior If an argument's value is omitted from a graphQL query or mutation. It shouldn't be null in the arguments passed to the lambda via resolvers.

munibrahman commented 4 years ago

For now, one can basically go around this bug by including this at the beginning of the appsync lambda resolver.

#foreach ($arg in $ctx.arguments.entrySet())
    #if( $util.isNull($arg.value))
        $util.qr($ctx.arguments.remove($arg.key))
    #end
#end
allisoninouye commented 4 years ago

Also having this issue. The above doesn't work because we sometimes will be setting things to null.

munibrahman commented 4 years ago

@allisoninouye If you just starting out with Appsync and you are having issues. I assure you, this is just the beginning. If you plan on taking your idea/product to production. I would highly recommend you consider some other solution. Appsync is really nice, but it has a long way to go to become a production ready microservice.

dinnerdeal commented 4 years ago

This is a huge issue, that's also apparently non-existent in the Android SDK. Really hoping there's plans on addressing this. This foundational.

gnemtsov commented 3 years ago

Probably the devil is hidden in the details. :thinking:
If we take a closer look at the docs we might notice the difference between arguments

arguments A map that contains all GraphQL arguments for this field.

and variables

variables A map which holds all variables that are passed into the GraphQL request.

Probably, we should just use variables if we don't want optional arguments to be injected with the null values. Really, the variables property contains only those variables that were provided by the client while arguments contains all of them according to the schema.

munibrahman commented 3 years ago

It's been ages since I worked with appsync, so if you think this is a solution, i'd be happy to close this issue :)

gnemtsov commented 3 years ago

Well, at least it works for me. I am not sure if it's "best practices" or if there are some downsides in using variables instead of arguments. :man_shrugging:

z-u-a commented 2 years ago

Probably, we should just use variables if we don't want optional arguments to be injected with the null values. Really, the variables property contains only those variables that were provided by the client while arguments contains all of them according to the schema.

Hi @gnemtsov , Encountered this thread while having same problem.

Variables work if the optional field does not present at all in the client's request payload but if it is present even with the empty value, AppSync allows it to be passed in context.info.variables.

atierian commented 11 months ago

Thank you for opening this issue. AWS AppSync SDK for iOS entered maintenance mode in September 2023 and will receive no further updates as of September 2024.

Please use Amplify Swift going forward. For information on upgrading to Amplify Swift, refer to the Upgrade from AppSync SDK documentation.