Fetch by multiple contract keys

Let’s say you have a contract template

template Thing
  with
    description: Text
    smallThingKeys: [SmallThingKey]
...

where SmallThingKey is a contract key to a SmallThing. Thing and SmallThing contain data that is to be shown in the user interface. When fetching the SmallThings, is it possible to submit a single query (containing all the smallThingKeys) and receive the SmallThings in one result? I know this can be done by making multiple separate queries, but this would not be ideal given that I am trying to render a table of many Things.

Thanks again for the help.

Alex

(Ideal solution would use the @daml/ledger JS library. That being said, I am considering writing some Java middleware.)

2 Likes

Hi @alex_m !

Multiple contract keys per request are not supported in the fetchByKey function.

@daml/ledger JS library uses JSON API.

JSON API does not support multiple keys in the Fetch Contract by Key request (/v1/fetch):
https://docs.daml.com/json-api/index.html#fetch-contract-by-key

Please submit a JSON API feature request in here: HTTP JSON API Maintenance Milestone · GitHub

@alex_m,

Have you considered using Streaming API?

See the docs:

Streaming API (/v1/stream/fetch) lets you specify multiple keys per request:

[
    {"templateId": "Account:Account", "key": {"_1": "Alice", "_2": "abc123"}},
    {"templateId": "Account:Account", "key": {"_1": "Alice", "_2": "def345"}}
]
1 Like

Cheers @Leonid_Shlyapnikov, I’ll give this a try tomorrow!

Here’s an idea! Try this: write a choice like so

controller c can LookupMany : Update [ (ContractId SmallThing, SmallThing) ] with smallThingKeys = 
  do mapA fetchByKey smallThingKeys

(n.b. untested)

This uses mapA from Traversable. It allows you to sequence a [ Update ] (i.e. your key lookups) into an Update []. This means, that the transaction will fail in whole if one of the lookups fail; otherwise it will return all the results in a list.

I hope I’ve understood your question correctly.

Let me know if this helps!

Something like that would work, but requires a ledger round-trip. A fetch from the JSON API is much faster, probably an order of magnitude.

1 Like

@Leonid_Shlyapnikov I have submitted a feature request: Fetch API - Fetch by multiple contract keys · Issue #7047 · digital-asset/daml · GitHub

Thanks for the help everyone, I take it there is no way to do this by standard fetch ATM.

@Luciano so execute a choice when wanting to view all the SmallThings? Looks interesting.

TBH ideal solution would be a fetch by multiple contract keys; not stream because I don’t think it’d be good to open many web sockets for a table of many Things.

2 Likes