Say an API returns the following pieces of data:
- daily_price
- number_of_days
- total_price
Assume that the API will always have the number_of_days
and at least daily_price
or total_price
.
In cases when the API only has the daily_price
or total_price
, should the API compute the missing value (e.g. daily_price
* number_of_days
= total_price
) - or should it leave it to the consumer to calculate? And if the API did compute the missing value, should it indicate which of the two values (if any) was computed?
-
Try to model the domain (don't just make stuff up as the programmer). If the domain shows receipts with quantity * price = subtotal, then do that, but consult not other programmers, but the domain experts. Inspect the positioning of the API to see who the clients are and how this information ought to be communicated between the business roles involved (API consumer(s), API provider(s)), so as to mimic a business/domain interaction. If the API is internal to the business, then perhaps it doesn't matter, but even internally we can be sharing information between business roles/departments.Erik Eidt– Erik Eidt02/02/2020 15:22:06Commented Feb 2, 2020 at 15:22
-
I'd be more interesting in whatever or not there is an appropiate way for the API to express that a value is missing. Consumer code should create an adapter anyway, and there it can deal with the missing value with whatever logic is prefered. Thus, arguebly expressing a missing value, if possible, is more flexible. The flip side is that abstracting this away from consumers could be part of the requirements for the system. Is it?Theraot– Theraot02/02/2020 15:27:47Commented Feb 2, 2020 at 15:27
2 Answers 2
The mistake is mixing them together.
If the api provides totals it shouldn't provide what it used to arrive at that total.
If the api provides the dependencies used to calculate the total it shouldn't also calculate the total.
The reason why is because these are two different levels of abstraction. You can provide both api's but they should be separate beasts. You should be able to use one without getting the other in the bargain.
Look at your using code when making these decisions. Don't just look at the data and try to imagine all of it's uses. Start from the real uses you have now.
Should an API return calculated values that the consumer can calculate themselves?
Short answer:
Yes.
Long answer:
What are the advantages for letting the client compute the missing information? Are you saving bandwidth because there is less bytes transmitted over the network? Do you have a cleaner API by not returning derived data from the core data? What's the reason to not just compute this field?
Even if you have a reason. What you are doing is increase the coupling between your server API and your clients. If, for example, you return daily_price
and number_of_days
then the client needs to compute total_price
. Always.
What if at some point this is no longer a multiplication? But some other other rules start to apply? Maybe new regulations introduced? I'm speculating here but what if taxes apply beyond a certain total amount? What if you want to apply discounts for certain total amounts? And a bunch of any other cases that changes the rules of the game?
If the rules change at some point, are you going to contact all your clients and have them change their code to now handle the new rule? This is your API, thus your responsibility. Don't put part of the responsibility for your API on your clients. Just add the derived/redundant data to your responses. You are not gaining anything if you don't.
-
One advantage of having client the compute the missing information is reducing the error space. Any redundancy is a possible inconsistency; you may actually make the client's life harder by providing additional information which can be logically derived from the basic information, because now in order to validate the API responses, a robust client will have to verify that the computed value is correct and will have to decide what to do if the information is inconsistent.Christian Hackl– Christian Hackl02/02/2020 19:08:04Commented Feb 2, 2020 at 19:08
-
1@ChristianHackl: Getting the computation wrong on the client is just as easy as getting it wrong on the server. Besides, this can easily be cought by the unit tests of the API. Having this field tested by the client might make it robust, as you say, but it also opens up a can of worms. If the client doesn't trust this field in the response, what else doesn't it trust? How far are you willing to go to complicate the client code just to check that the API does what it's supposed to do?Bogdan– Bogdan02/02/2020 21:10:05Commented Feb 2, 2020 at 21:10
-
Whether the client or the API is more likely to get the computation wrong depends on many things. It is also not true in my experience that testing an API means that clients need not perform any error handling, unless you are dealing with an extremely stable and robust API, e.g. something provided by your own operating system. Additionally, you may eventually have no control over how the API is developed and tested, anyway.Christian Hackl– Christian Hackl02/02/2020 23:51:36Commented Feb 2, 2020 at 23:51
-
@ChristianHackl: Error handling is one thing, not trusting the API you are calling and deciding to add code to double check for stuff is another.Bogdan– Bogdan02/03/2020 09:25:28Commented Feb 3, 2020 at 9:25
-
1Example new rule: Buy 3 weeks and get your 4th week free! Daily price = 10,ドル number of days = 28, total price = 210ドル.Stack Exchange Broke The Law– Stack Exchange Broke The Law02/03/2020 12:56:48Commented Feb 3, 2020 at 12:56