Correct API architecture for building AngularJS apps

I've been talking a lot with mid-level developers lately about how to structure APIs to better use the two-way binding that AngularJS offers. We were trying to decide if the APIs should be very explanatory with their definitions that would work better w / Angular but cause a bit more work for the middle tier or are more implicit and have additional logic in Angular to "mass" the data into a good Angular model.

Let's start with an example. Let's say we are talking about some kind of data backup service. The service allows you to back up and store data for X years or without any limitation. The user interface has 2 elements to control this logic. There is <select>

one that allows the user to choose whether they want to delete the data "Never" or "After" X years. If "Never" is selected, then we hide the input for the year, but if "After" is selected, we show the input for the year and allow them to enter a number between 1-99.

Having done this, I introduced two different item controls, each controlling a different property in the model $scope

.

However, in the API, my middle guy wants to control all of this using one property called "YearsRetention". If YearsRetention == 0

, then this "implicitly" means we want unlimited retention, but if it is set to anything> 0, then the retention is kept at that value.

So basically he wants to manage storage settings using that single value, which would force me to write some sort of transform function to set the values ​​on $ scope to achieve the same effect in the UI. This transformation would have to happen on both inbound and outbound data.

At the end of the day, I want to know if the API should be defined implicitly (the API sends a single value, and Angular will need to convert the data to a usable view model) or explicitly (the API sends all the values ​​it needs to bind directly to the UI and minify need to convert JSON)?

+3


source to share


1 answer


I think in designs you describe 2 bad ideas.

  • Define data structures based on user interface convenience. This is a bad idea because you want your API to be clear, feature-rich (potentially supporting different clients with different user interfaces), and durable (API refactoring is operationally expensive). Instead, try to present your data accurately and concisely in the cleanest, most accurate, most generalized form, and leave presentation issues like formatting, truncation, localization, units, page layout, etc. in the UI.
  • Overloading a single data field to express a concept that is naturally not modeled with a "magic value". An example of this is assigning an additional semantic meaning to a zero number, and this is usually seen as error prone and obfuscation, as well as a fuzzy abstraction. Each client will have to code magic semantics that are zero forever. Of course, there is an egregious cognitive dissonance that the true meaning of zero will be "not at all." I would simulate this as 2 fields, an enumeration titled retentionPeriod

    allowing exactly 2 values: "PERMANENT" and "YEARS" and a separate field perhapsretentionValue

    to store an integer representing years. If you end up losing an argument with the help of your third party developer, I would at least argue that the magic value should be -1 forever instead of 0. (I also think it null

    matches "not at all" more than "forever" "here why I think -1 is the least bad of bad magic options. At least there is a precedent for that, at least)


In your particular case, I am arguing that one of your UI dropdowns will control retentionPeriod

and the other will control retentionValue

. But my arguments for this are not related to the fact that it happens to a simple implementation of the current UI implementation (which is a happier coincidence), because it is a clearer representation of the data.

However, in my experience, this particular example is rather bland at this bad thing. I am much more concerned about wrong array versus object selection, undefined or confusing naming, giant data structures, overly chunky APIs, etc.

+1


source







All Articles