Ask HN: Who should handle UI logic?

3 pointsposted 4 days ago
by zero_kool

Item id: 41496982

5 Comments

RayFrankenstein

3 days ago

I worked on a mobile app dev team that tried to Ui logic with the backend. With many of the justifications you mentioned being justifications for doing it that way. White labelling, A/B testing, avoiding redeploying, etc.

The result was a mess, with many of the possible concerns and drawbacks you’ve cited ending up manifesting themselves. It was an unmaintainable mess that tried to re-invent the web browser wheel badly, except using json instead of HTML. Maintaining the abstraction framework became a full-time job for people already just trying to barely deliver features on time.

And with the backend people already being busy and tied up with other stuff, the mobile app developers ended up having to become impromptu full stack developers, have to code PHP on backend to complete features in addition to the code they had to write in Objective-C/Java for their native app level portion of the feature.

The backend approach was so resented and hated by the mobile app devs that the business eventually got rid of it.

re-thc

4 days ago

This is what gives rise to backend-for-frontend services. You have good reasons to keep the frontend as it is and the backend team as well. So there is a requirement for a middleman to provide additional services.

As to who should handle it? The argument isn't about the "backend" is it? It's the API. The API should be kept clean. The frontend doesn't have to use the public API though.

efortis

4 days ago

Let the backend send what's convenient to them. In the frontend, create Models that transform to what's convenient to the FE. Sometimes, the FE needs two models for the same data. For example, a Table View and a Nested Card View of the same collection.

Model Example:

  const UF = { // User Fields
    id: 'user_id',
    name: 'name',
    balance: 'remaining_dollars',
    balanceFormatted: 'balanceFormatted' // @ClientSideOnly
  }

  function UserModel(data) {
    const model = Object.create(null)
    Object.assign(model, data)
    model[UF.id] ??= ''
    model[UF.id] = String(model[UF.id]) 
    model[UF.name] ??= ''
    model[UF.balance] ?? = 0
    model[UF.balanceFormatted] = toDollars(model[UF.balance])
    return model
  }
In that example:

1. You are protecting from prototype pollution. `model` doesn't have a `__proto__`

2. Initialized the fields with sane defaults. So if the backend missed that field, it doesn't crash the UI. By the same token, they are handy for prototyping while the backend is written.

3. Your views a free of formatting, and in some cases of many conditionals.

4. You don't have to worry about int ids. Not because they are often changed to GUIDs, but because when you use the ID, let's say in a checkbox, `this.value` is a string regardless. So you saved 30 minutes of debugging a silly bug.

5. Backend wants to rename a field. You just have to rename the UF, without having to look all over the app.

6. The model is easy and fast to unit test, while the testing the UI is…

7. You saved 3 meetings.

--

My personal project is data-driven and even there I pass the backend data through model constructors. One example is that in the frontend I use a Linked-List for convenience, while the backend sends and receives an Array.

codingdave

3 days ago

Why not make the front-end configurable? So neither front-end or back-end code has to change, but the UI can re-group and place data different based on changes to config files?

It adds complexity to your stack to go this way, and often results in a complex implementation/configuration process for new customers, so I truly do not recommend it as a standard practice... but when I have worked on multi-tenant products where each tenant has unique data display requirements, it definitely reduces the churn of re-deployment to meet some one-off need.

Of course, you'd still need to decide where those config files live, but it now is a content change, not a code change, to alter the UX.

solardev

3 days ago

As a frontend dev with some full stack experience, I don't think this should really be a matter of "we want vs they want", but of your underlying resource constraints and UX needs (UI performance, database indexing or write performance, caching layers, app store limitations, etc.). It's not a game of hot potato, but how it impacts the overall data flow, both ingestion (from data sources) and serving (to the end user). Ideally you'd choose what's best for the project and company overall, not any particular team's microscopic preferences.

But in this particular case it doesn't seem like there's much to debate. It's like a single line of code for the frontend to map or reduce that simple JSON into whatever they want. It shouldn't require a rebuild (or how do you do any sort of dynamic data?).

If this is a common problem though, then yeah a BFF can help with the political side of things, if both groups can co-maintain it. It's really just a codified API layer. Backend sends data to it, frontend can choose how they want to present it through simple transformations.