amplify-category-api icon indicating copy to clipboard operation
amplify-category-api copied to clipboard

Is there a simple way to get a list of items by a set of ids?

Open chrisco512 opened this issue 6 years ago • 11 comments

** Which Category is your question related to? ** API

** What AWS Services are you utilizing? ** AppSync, Amplify

** Provide additional details e.g. code snippets ** Is there a simple way to write a resolver to get a list of items from a table by passing in a set of ids?

I'm currently solving this problem by building a filter expression string rather manually (this is a function for a pipeline resolver):

#set( $expValues = {} )
#set( $expression = "#id IN (" )
#set( $ids = $ctx.stash.get("ids"))

#set( $index = 0 )

#foreach( $id in $ids )
    #set( $index = $index + 1 )
    #if( $ids.size() == $index )
        #set( $expression = "${expression} :id${index})" )
    #else
        #set( $expression = "${expression} :id${index}, " )
    #end
    $util.qr( $expValues.put(":id${index}", { "S" : "${id}" }) )
#end

{
  "operation" : "Scan",
  "filter" : {
      "expression" : "${expression}",
      "expressionNames": {
        "#id" : "id"
      },
      "expressionValues" : $util.toJson($expValues)
  }
}

Is this the best way? For example, I noticed there was a utility, $util.transform.toDynamoDBFilterExpression and tried implementing it as suggested from @mikeparisstuff 's answer on StackOverflow: https://stackoverflow.com/questions/52046495/util-transform-todynamodbfilterexpression

But I kept getting errors in the response about $util and expecting 'null', 'true', or 'false'. So I had to resort to the above approach.

It would be nice to have a better way to build complex queries as DynamoDB-JSON is a bit painful to write. I was hoping to be able to use similar filters (with OR: [{ id: "123" }, {id: "124"}] -type constructs that AppSync/Amplify already provides at the API level, but at the resolver level.

chrisco512 avatar Apr 01 '19 09:04 chrisco512

To get a set of values based on id, you should use the BatchGetItem resolver operation as outlined here https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-batch.html. This is currently a bit tough to use when using multiple environments because you need to know the table name in the resolver and ideally would be encapsulated as a transformer such as @batchGet. We have plans to open up the CLI such that you can run custom transformers and that would be the best way to get this working in a reproducible manner.

mikeparisstuff avatar Apr 19 '19 20:04 mikeparisstuff

@mikeparisstuff, have there been any recent developments into making this work with multiple environments?

andreialecu avatar Apr 20 '20 14:04 andreialecu

+1, is there any way to do this more easily now?

tomhirschfeld avatar Jun 21 '20 06:06 tomhirschfeld

The batchGet is actually the best shot at doing this, although you will be limited to 100 items (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html). The sole problem at the moment, however, is that as far as I know, we are not able to inject any environment variables such as the table name - which is required for the BatchGetItem - into the custom resolver.

This is supposedly tracked in aws-amplify/amplify-category-api#408. Maybe somebody in the near future will find some time to dig deep into it and find a way to make this work.

Other than that, I think, you can pretty much only run the expensive scan with the filter expression.

Or instead, in case you are using GraphQL, you can run the list query with a filter. This should already be a scan with the filter, depending on where you want to have your logic for building the filter.

crolly avatar Sep 03 '20 10:09 crolly

Oh, aws-amplify/amplify-category-api#415 ist also talking about this. I don't know, what the pricing implications are, but if you really need a batchGet you can of course always lean back to a lambda for the resolver. Lambdas can be added with amplify add function and detailed configuration which other resources access is required to.

crolly avatar Sep 07 '20 15:09 crolly

any updates on this?

yaquawa avatar Feb 07 '21 09:02 yaquawa

any updates on this?

Lorenzohidalgo avatar Oct 19 '21 11:10 Lorenzohidalgo

It’s 2023 already, any updates on this?

mandrelbrotset avatar Feb 20 '23 02:02 mandrelbrotset

the future called and is asking for updates?

emiltorlen avatar May 23 '23 10:05 emiltorlen

Yeah this is still needed

NairiAreg avatar Oct 31 '23 07:10 NairiAreg

Hello from the future of 2025!

foobarnes avatar Mar 05 '25 17:03 foobarnes