I have been exchanging emails and opinions with a co-worker located literally in the other side of the planet (I am in Spain, he is Sydney) around the problems of modern SPAs and RESTful APIs. Here is the thing, I’ll try to be brief.
With the proliferation of the Microservices architectural approach, we are witnessing a trend in designing our systems based on fine-grained, conversational RESTful APIs. This is, building API-driven SPAs.
- These APIs do not meet UI needs. Full stop. They are designed to expose business processes and data. This is all what API developers care about, and believe me, UX is not part of the design process of RESTful APIs.
- This means that we might end up having many APIs for one single UI feature, and, what is worse, no APIs or no resource representation for many UI features.
- We can’t build up a new API or design a new resource representation because that takes too long. So frontend developers end up building a super-custom solution, orchestrating too many API calls to mimic the resource representation they need. This results in underperforming or insecure code.
As a consequence, UI developers need to do a lot of juggling to factor in User Experience and Functional requirements within the API-driven application they are building. And of course, it is supposed to be them because they understand both worlds: UI and APIs. No worries, an extra of agility is always supposed to be a skill in these teams.
So where we all understand the problem statement, we might disagree with the solution. One can think “hey don try to boil the ocean, there are problems you can’t fix at the frontend” or “this is an organizational issue”. And I tend to agree. When building a Digital Platform, this means many things, and one of them is that everybody needs to shift mindset to digital: Marketing needs to enable a digital product where minimal interactions from final user are required; Architecture needs to provide digital microservices; Business Analysts need to shift to digital thinking; and Designers need to realize we are not in 2002 anymore and having a frontend with 50 fields may not fit well with the digital product and architecture.
So taking a stab to the solution from the organizational standpoint, some companies are making up a new role: the Digital Engineer. It is a role that acts as a liaison between all the stakeholders described earlier. In this particular use case, it would be the person who is telling the Designers and the Business Analyst that there are some constraints to their work, given by the palette of microservices and resource representations available in the architecture. This way we ensure the UX fits the API specifications, but I am unsure if ring-fencing creativity like this is a good approach. Especially by promoting constraints that are coming from a very process-oriented, even bureaucratic world (i.e the way data is represented and then exposed)
On the other hand, my coworker in Sydney was pushing for something more pragmatic. He was like “hey, I know, we can’t fix the world, but we can do something at the frontend that at least is making our lives easier”. My fear was that we over-design the frontend by building a one-size-fits-all super-solution. But his points started to made sense:
- Availability. 80% of the times, when we start building frontend, APIs are not ready. We need to find a mechanism that helps us start without waiting.
- Stability. We can’t tell the business that the UI and UX they are expecting is not possible because there is a limitation in the way the data is represented and exposed.
Then he proposed something that, after some time, I discovered is labeled under the name of Backend for Frontend pattern. In essence, it means we can create a facade of the RESTful APIs in the UI, to be consumed by the UI, that mimics an ad-hoc backend for that particular UI.
- Availability. The data interface is available while we are building frontend, because this component is implemented in the frontend by the UI developers. This man-in-the-middle will offer a new representation of the data and the resources to the UI. Data will also be exposed through a new GraphQL interface. This way we don't need to hit multiple endpoints to get the data we need, as the UI developers will now select only the fields that are needed from the new schema.
- Stability. BFF provides the resource model and data we are looking for the UI needs. This facade component will fetch REST resources from API (SoR Data), adapt them to an intermediate representation more in line with UI needs, and expose them through a new GraphQL interface to be finally mapped to the View Model (UI Components). And all this happens in the frontend, so in a sense, this is like having UX APIs. Yes, we are talking about Frontend APIs here. This also means that there is no need to implement a complex and underperforming logic in the UI to gather the data needed in the display from the unmatching RESTful APIs.
Of course, this is our interpretation of the pattern. One may think that BFF is yet another server-side component or middleware, but this is the magic of patterns: we give it the implementation we want.
We are probably going to give this pattern a go. If only because, as Ian Robinson mentions in this post from 2006 (damn, these things always age well), the success of an API depends on its consumers:
"The derivative nature of consumer-driven provider contracts adds a heteronomous aspect to the relationship between service provider and consumer. That is, providers are subject to an obligation that originates from outside their boundaries. This in no way impacts on the fundamentally autonomous nature of their implementations; it simply makes explicit the fact that services depend for success on their being consumed".
That was well put Ian, thanks.
Of course, this is not a silver bullet, and every solution depends on the problem space and context, so for others, it might be easier to take an organizational approach. As Martin Fowler says, this is a general post and as such, is subject of the limitations of the general advice fallacy.