3

Lately I have been talking with a lot of my mid-tier developers about how to structure the APIs in order to better accommodate the 2-way binding that AngularJS offers. We have been trying to decide whether or not the APIs should be very explicity with their definitions which would work better w/Angular but cause a little more work for the mid-tier or be more implicit and have extra logic in Angular to "massage" the data into a good Angular model.

Lets start with an example. Suppose we are talking about some sort of data backup service. The service allows you to backup data and retain the data for X number of years OR indefinitely. The UI has 2 elements to control this logic. There is a <select> that allows the user to select whether or not they want to delete the data "Never" or "After" X years. If "Never" is selected then we hide the years input, but if "After" is selected, then we show the years input and allow them to input a number between 1-99.

Doing this I have introduced 2 different element controls, each controlling a different property on the $scope model.

However, on the API my mid-tier guy wants to control all of this using a single property called "YearsRetention". If YearsRetention == 0 then that "implicitly" means that we want unlimited retention, but if it is set to anything> 0 then retention is set to that value.

So basically he wants to control the retention settings using this single value, which would force me to write some sort of transformation function in order to set values on the $scope to acheive the same effect in the UI. This transformation would have to happen on both incoming and outgoing data.

In the end, I want to know if the API should be defined implicitly (API sends a single value and Angular will then have to transform the data into usable view model) or explicitly (API sends all values needed to bind directly to the UI and reduces the need to transform the JSON)?

asked Dec 2, 2014 at 20:18
1
  • Sorry if it is kind of wordy.. it is hard to summarize my question in a concise manner. I can re-iterate on something if need be Commented Dec 2, 2014 at 20:21

1 Answer 1

1

I think there are 2 bad ideas in the designs you describe.

  1. Defining the data structures based on UI convenience. This is a bad idea because you want your API to be clear, multipurpose (supporting different clients with different UIs potentially), and long-lived (API refactoring is operationally expensive). Instead, try to accurately and concisely represent your data in the purest, most accurate, most generalized form, and leave presentation issues such as formatting, truncation, localization, units of measure, page layout, etc to the UI.
  2. Overloading a single data field to express a concept that it doesn't naturally model by way of a "magic value". Assigning extra semantic meaning to the number zero is an example of this, and it's generally regarded as error prone and confusing and a leaky abstraction. Every client will have to encode the magic semantic that zero means forever. Of course, there's the glaring cognitive dissonance that the true meaning of zero would be "not at all". I'd model this as 2 fields, an enumeration called retentionPeriod allowing exactly 2 values: "PERMANENT" and "YEARS" and a separate field perhaps retentionValue to store the integer representing the years. If you end up losing the argument with your back end developer, I'd at least argue that the magic value should be -1 meaning forever instead of 0. (I also think null matches "not at all" more than "forever" which is why I think -1 is the least-bad of the bad magic options. There is some precedent out there for this, at least)

In your specific case I'd argue one of your UI drop-downs would control retentionPeriod and the other would control retentionValue. But my reasoning for this is not because it happens to pair up with your current UI implementation in a straightforward way (that's more of a happy coincidence), it's because it's a clearer representation of the data.

That said, in my experience this specific instance is fairly mild in it's badness. I'd be much more strongly concerned about incorrect choice of array vs object, vague or confusing naming, gigantic data structures, overly chatty APIs, etc.

answered Dec 2, 2014 at 21:03

5 Comments

I agree with everything here except for the "magic" value. I would use null instead of 0 or -1 to mean forever.
I completely understand your reasoning and I agree with the fact that you shouldn't model the API based on the UI, but rather the most generalized/clear representation of the data. In this case it just happens to align with the way the UI is built (a lot of the time the UI is "in sync" with the way the model should naturally be structured)
Yup, exactly. If a new UI design comes out suggesting just a stack of labeled radio buttons ("1 Year", "5 Years", "Permanent"), then you change the UI but continue with the same API and data representation.
@PeterLyons Ah yes that makes sense, however say the API controlled the "Retention" type and the Retention value in 2 seperate properties like we said above. How could you simply change the UI to use all radio buttons that utilize a single ng-model?
I would imagine you should always use a single ng-model value for an entire radio button group, which would force Angular to have to manipulate the ng-model value and seperate this single value into the 2 values on the API

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.