Ultimately it’s about splitting your app into a server and client with a clear API bounday. Decoupling the client and server means they can be separate teams with clearly definied roles and responsibilities. This may be worse for small teams but is significantly better for large teams (like Facebook and Google who started these trends).
One example is your iOS app can hit the same API as your web app, since your server is no longer tightly coupled to html views. You can version your backend and upgrade your clients on their own timelines.
I’ve worked in two kinds of organizations. In one of them when there is a ‘small’ ticket from the viewpoint of management, one programmer is responsible for implementation but might get some help from a specialist (DBA, CSS god, …)
In the other a small ticket gets partitioned to two, three or more sub teams and productivity is usually reduced by a factor more than the concurrency you might get because of overhead with meetings, documentation, tickets that take 3 sprints to finish because subtasks that were one day late caused the team to lose a whole sprint, etc.
People will defend #2 by saying thar’s how Google does it or that’s how Facebook does it, but those monopolists get monopoly rents that subsidize wasteful practices and if wall street ever asks for “M0R M0NEY!” they can just jack up the ad load. People think they want to work there but you’ll just get a masterclass in “How to kill your startup.”
Tech orgs and those standards exist because:
- tech generally doesn't understand business - the business struggles to express it's needs to tech
Embedding worked for you, but how big was your team? Could that scale?
I'm not questioning your success or your frustrations, but how unique was the situation for your success?
As far as iterations go it’s very rapid. Our work teams are split into 1 backend and 1 frontend developer. They agree on an API spec for the project. This the contract between them and the frontend starts working immediately against a mock or very minimal version of the API. Iterate from there.
Company forced us to type 2 using Angular. projects thar used to take a couple of days for one person became multi month efforts for a dozen developers across three teams.
</s>
And just because you serve HTML doesn’t necessary mean that you backend code is tightly coupled with the view code, HTML is just one adapter of many.
A boundary doesn’t get better just because you slip a HTTP barrier in between, this is the same type of misconception that has driven the microservice hysteria.
third time I've heard this thing and the reasoning still escapes me.
First there's ownership. Backend team owns API. Frontend teams own clients (web/android/ios/cli) etc. Do you now have a BFF for each client type? Who owns it then ? Don't you now need more fullstacks ?
there's confusion. Now you have 2 sets of contracts (API-BFF, BFF-clientIOS, BFF-clientAndroid, ...). You now have more human synchronization overhead. Changes take longer to percolate throughout. More scope for inconsistencies.
And there's performance. Adding more hops isn't making it faster, simpler or cheaper.
Isn't is better to have the API team own the single source of ownership ?
> Do you now have a BFF for each client type? Who owns it then ? Don't you now need more fullstacks ?
everyone has an opinion, but ime ideally you'd have 1 bff for all clients from the start > there's confusion. Now you have 2 sets of contracts (API-BFF, BFF-clientIOS, BFF-clientAndroid, ...). You now have more human synchronization overhead. Changes take longer to percolate throughout. More scope for inconsistencies.
yep, i have literally experienced the chaos this can cause, including the endless buzywork to unify them later (usually its unify behind the web/html bff which breaks all kinds of frontend assumptions) > Isn't is better to have the API team own the single source of ownership ?
it depends on what it means 'api team'... but ideally bff has its ownership separate from 'backend' wether that is in 'api team' or outside i think is less important imebut... ideally this separation of ownership (backend backend, front end for backend) allows each to focus on the domain better without mixing up say localization in the lower level api's et
iow having a bff is sort of like having the view model as a server... that way multiple clients can be dead simple and just map the bff response to a ui and be done with it
(thats the ideal as i understand it anyways)
Yes. I’m generally against specialization and splitting teams. This of course depends on what type of organization you have and how complex the frontend is. iOS and Android is usually complex as it is so they are typically specialized but I would still keep them in the team.
Specialized teams not only creates synchronization issues between teams but also creates different team cultures.
What this does is that it induces a constant time delay for everything the organization does. Because teams no longer can solve an entire feature the organization instead spends more time on moving cards around in the planning tool of choice. The tiniest thing can require massive bureaucratic overhead.
Solutions also has a tendency to become suboptimal because no technician has an general overview of the problem from start to finish. And it also quite common that the same problem is solved multiple times, for each team.
By making BFFs specialized, instead of the teams, you don’t need to spend time to create and design a generalized API. How many hours hasn’t been wasted on API design? It adds nothing to customer satisfaction.
This also means that you separate public and private APIs. External consumers should not use the API as your own web client.
Specialized BFFs is not only to have a good fit for the client consuming it but it also about giving different views of the same underlying data.
E.g assume we have an article with multiple revisions (edits). Handling revisions is important for the Admin API but for the web client that serves the final version of the article not at all, it shouldn’t even be aware of that the concepts of revisions exists.
Creating a new a BFF is as easy as copy&paste an existing one. Then you add and remove what you need.
The differences between BFFs is usually how you view your schema (GET). Writing to your model (POST) is likely shared because of constraints.
What is then different views of the same data? An SQL query (or VIEW). Too many APIs just maps a database table to an endpoint 1:1, those APIs are badly designed because the consequence of that is that the client needs to do an asynchronous HTTP JOIN to get the data it needs, very inefficient.
By writing SQL to fit your BFFs you will then realize that the ORM is the main problem of your architecture, it usually the ORM that creates the idea that you only have one view of the same data, one table to one entity. But SQL is a relationship model, you can’t realistically express that with 1:1 only.
By removing the ORM you will also solve the majority of your performance issues, two birds one stone scenario.
Ownership of a BFF should ideally be by the ones consuming it.
iOS and Android can usually use the same BFF, they don’t differ that much to warrant a new BFF. If there are any differences between the two, give them different endpoints within the same BFF for that specific use case. When designing APIs one should be pragmatic, not religious.
BFF is nothing more than an adapter in hexagonal architecture.
You can't trust it to actually save changes you've made, it might just fail without an error message or sometimes it soft-locks until you reload the page. Even on a reliable connection. Error handling in SPAs is just lacking in general, and a big part of that is that they can't automatically fall back to simple browser error pages.
Google seems to be one of the few that do pretty good on that front, but they also seem to be more deliberate for which products they build SPAs.
How desirable this is depends on the UI complexity.
Complex UIs as the ones built by google and facebook will most likely benefit from that.
Small shops building CRUD applications probably won't. On the contrary: the user requirements often cross-cut client and server-side code, and separating these in two teams adds communication overhead, at the best of the hypotheses.
Moreover, experience shows that such separation/specialization leads to bloated UIs in what would otherwise be simple applications -- too many solutions looking for problems in the client-side space.
It sounds a lot more annoying to have to manage one client and many servers instead.