digital-asset / daml

The Daml smart contract language
https://www.digitalasset.com/developers
797 stars 199 forks source link

Expose exercise results in the HTTP JSON API #3314

Closed cocreature closed 4 years ago

cocreature commented 4 years ago

It would be nice if the result of a DAML choice would be exposed via the HTTP JSON API. In case people are worried about feature creep on the API, I want to give some arguments for why I think this makes sense:

  1. It is the value that users have direct control over so it makes sense to expose it.
  2. If you want to write a query as a nonconsuming choice, the exercise result is the value you care about.
  3. It fits in nicely with the synchronous nature of the HTTP JSON API

cc @gerolf-da @bame-da @hurryabit

leo-da commented 4 years ago

@bame-da how about I add a new /command/exercise-with-result end-point that returns only the result/return value from the exercised choice and nothing else (no creates nor archives)?

The existing /command/exercise will not change and continue returning "archived" and "created" contracts. We can drop it later, I believe @da-tanabe and @lima-da are relying on it as part of DABL.

lima-da commented 4 years ago

new /command/exercise-with-result end-point for that sounds good to me. Especially in case any existing user application relying on command/exercise, we have some level of backwards compatibility

garyverhaegen-da commented 4 years ago

If the return result of /command/exercise already is a map with two keys created and archived, adding a key result should be backwards compatible; existing clients should just ignore the additional key.

cocreature commented 4 years ago

The only argument that I could see for having separate end points is that you need a different gRPC API call to get the results which might be less efficient. But I don’t know how big the difference there actually is so without benchmarks, I don’t see that as a valid argument.

leo-da commented 4 years ago

I had a chat with @hurryabit, he wanted to have an exercise endpoint that returns ONLY the choice result/return value and nothing else. That is why a separate endpoint, the existing one that returns "archived" and "created" is already being used. It is also possible to add result/return value to the "archived".

garyverhaegen-da commented 4 years ago

If you're worried about backwards compatibility (even though this is an experimental component) to the point that you would rather make a new endpoint rather than add keys to an existing one (which should be a safe, backwards-compatible change for most clients), please make the new endpoint fully functional and have it return an object with the full set of keys, rather than forcing clients to choose between getting the return value and the side effects. People will want to do both in one call.

leo-da commented 4 years ago

I don't really worry about the backward compatibility at this point. Just bringing this up with a product owner (cc @bame-da) and asking if it makes any sense to introduce a new endpoint that only returns choice result and nothing else.

garyverhaegen-da commented 4 years ago

I had a chat with @hurryabit, he wanted to have an exercise endpoint that returns ONLY the choice result/return value and nothing else.

Clients are free to ignore additional keys; unless you can prevent them from successfully calling that endpoint for choices that do create or archive contracts, I don't see the point. Query/command separation is an architectural choice some clients may want to make, but I don't think we can dictate that it is the best choice for every possible scenario.

leo-da commented 4 years ago

@garyverhaegen-da the thing that @hurryabit is asking for, will remove a bunch of keys and add a new one, that is why all the fuss :)

end-point that returns only the result/return value from the exercised choice and nothing else (no creates nor archives)

garyverhaegen-da commented 4 years ago

@hurryabit what's the reasoning for that? It seems easy enough for clients to ignore the keys they don't care about.

hurryabit commented 4 years ago

I suppose I was prematurely optimizing here. The transaction you trigger might be quite big. If you don't care about the side effects or consume them via the future streaming API, sending the transaction over the wire would be a huge waste of traffic and might impact the responsiveness of the UI.

leo-da commented 4 years ago

@hurryabit BTW when choice result is a contract ID you would only get the ID without any corresponding template ID. So, you will need to know the expected type ahead of time, if you plan to do anything with the choice result.

leo-da commented 4 years ago

for references:

Question: in the DA sync you mentioned that choice results will be returned from the json API.

  1. If I create n contracts in the body of the choice but only return the last will I get all of them or the last? (edited)

  2. If I do not return a contract id from the choice by just a boolean or a text is that going to be available? (In the response) (edited)

  1. exerciseResult will contain exactly what contract choice returned, you control it in your choice implementation. Keep in mind exerciseResult can be a Contract ID, a List of Contract IDs, a primitive, an empty record, etc.
  2. yes

and if you have a non-consuming choice that calculates some value and returns it, you will get that value in exerciseResult, contracts element will be empty, because nothing got archived or created.