Backend for the Frontend, and incentives
I work for Attest, we split our engineers largely down the seam of Backend and Frontend. We have java and go apps that run server-side, developed by our Backend engineers. We have typescript and vue apps that run in browser/on the client, developed by our Frontend engineers.
By splitting down this seam, we are also splitting on the goals and incentives of the two disciplines.
“Clean and reusable”, they said..
Our Backend engineers are motivated to provide ‘clean’ and ‘reusable’ (in quotes, because we can argue over the definition of those words) APIs. APIs that – are supposed to – expose the core concepts of our system. APIs that don’t make too many judgements on how the data will be consumed and displayed.
Our Frontend engineers are motivated to deliver the feature. But in many cases, they are working with Backend APIs that are lower level than they might like.
Take the example of a market research application. We might have two APIs
Answers API
|
|
Respondents API
We might also have an API that describes the demographic profile of that person, or their interests
|
|
Here our Backend is exposing the ‘reusable’ low-level data parts of our system: the Answers and the Respondents.
But it falls to the Frontend engineers to join those two datasets together and work out what the demographic profile of the person who gave any set of answers. It’s easy for this pattern to extend across a lot of different APIs; and soon the Frontend app is joining together the data from many different requests to render the page.
I think it’s fair to assume that we engineers are striving to make ‘good’ systems; but is this ‘good’?
Maybe Backends for Frontends
I’ve been thinking about Backends-for-the-Frontend, which are an extra layer you might build between the Frontend browser/client applications and the ‘clean’ Backend APIs. This layer still runs server side, but is responsible for much of that data-joining-and-processing that’s needed to build the datamodels that the client actually wants to consume.
Now when we fetch Answers, we might find that they come bundled with the demographic profile of the Respondents, because we joined those two lower-level Backend APIs in our Backend-for-the-Frontend. Or we can fetch the Respondents for a survey, and they will come bundled with the Answers.
This would simplify the code that runs on the client.
But is this ‘good’?
We still have to build and maintain the part that joins the low level APIs. Someone, Backend or Frontend, will still build the systems that join our data together. And who does that responsibility fall to?
What would change your mind?
I think it’s hard to weigh up the relative importance of all choices. Is it ‘better’ to have low-level reusable APIs? Or is it ‘better’ to have APIs that serve the Frontend what it needs? Did your ‘clean’ and ‘reusable’ APIs ever actaully get re-used? Or are all the clients doing the same kinds of data-set joins to build the models they need?
I increasingly believe that ‘better’ is based on your frame of reference. What your goals and incentives are, and what you’re trying to achieve.
System design is already a mine-field of difficult tradeoffs; but it seems we might not be making the best trade-off here.
Think about what would change your mind. What would need to change for you to see a ‘cost’ as a ‘benefit’?
Take this thought experiment;
Lets start with ‘cost’..
Right now, the ‘benefit’ (clean and reusable APIs) is felt by the Backend engineers. They likely have to do less, because they are providing lower level APIs. The ‘cost’ is felt by the consumer, clients, Frontend engineers. They have to join the data sets together to make them into something usable.
So, if we change the thought experiment from a Backend-vs-Frontend split, and instead assume that we had full-stack engineers (let’s suspend our various views on the rights-or-wrongs of fullstack development).
How would the cost-benefit equation change?
Our fullstack engineers would be responsible for both exposing the API (Backend) and consuming it (Frontend). The same person would feel the cost and the benefit of the decisions they made. And maybe, we might end up with differently designed APIs.
This takes me back to the question of ‘what is good?’. If we make a situation where we are ‘minimising the cost’ of some decision, but we also aren’t the ones who feel that cost, can we realistically achieve ‘good’ on that decision/metric?
As Backend engineers, we are optimising for ‘good’ APIs, and trying to lecture our consumers on how they should be using those APIs, without actually using them ourselves. Is this ‘good’?