Hacker News new | ask | show | jobs
by malwrar 506 days ago
I don’t understand the benefit of adding this intermediate component vs just writing frontend code to interact with the APIs you’d otherwise already be calling. An HTTP server with sessions placed between clients and internal systems makes sense and is standard, but the weird callback-style “remote control” system seems completely unnecessary and inefficient to me. I don’t think client logic being married to some backend vs the client itself makes any real guarantees about functionality being maintained either, it just adds a new location where code needs to be changed when something upstream changes.
3 comments

The article imo misuses the term BFF a bit, but perhaps its meaning has evolved over time. I was at SoundCloud when BFF was being introduced as an important piece of the microservice architecture--this post explains the purpose well[0]. BFFs can enable you to build more general-purpose and domain-specific services with few assumptions as to how they are used and their callers. BFFs then provide a composition layer you can use to, e.g., call one service to get a list of tracks, then call an authorization service w/ the list of track IDs to get geo-specific distribution rules for them, and compose that together in one materialized presentation view for the clients of the BFF.

Eventually I think there was some work to move to GraphQL, which can solve some of the same problems. But GraphQL is a technology, and BFF is more of a pattern. There is a later reflection on that blog that makes this distinction, which I only read today.[1] It makes another observation that I kind of forgot about, because it was hiding right in front of my face as a worker there:

"The defining characteristic of a BFF is that the API used by a client application is part of said application, owned by the same team that owns it, and it is not meant to be used by any other applications or clients."

The ownership model is indeed a big deal. In practice, it helped in many ways to have a sort of intermediate layer between the client applications and the rest of the architecture. For example, in the SoundCloud web application, when you load a page of playlists, only the first 5 tracks in the playlist are visible to the end-user. So the web BFF application had special logic to only partially load all the track metadata past track 5, which had significant impact on scalability and latency, especially when rendering a lot of playlists that had lots of tracks!

[0]: https://philcalcado.com/2015/09/18/the_back_end_for_front_en... [1]: https://philcalcado.com/2019/07/12/some_thoughts_graphql_bff...

If you have lots of backend services, building a gateway API (aka BFF) using GraphQL is really nice. Your GQL handles composition of all the resources into exactly what the client needs for something, without having to define a REST endpoint for every single use case.

On the frontend you compose the various schemas that each component needs (fragments) and can in one request pull exactly the data needed with one request to the gateway which will use the minimum required calls to the upstream services, and execute them in the most efficient order.

> gateway API (aka BFF)

A gateway API is an API that gates other APIs. A BFF is a gateway API used for a particular purpose, clearly identified by the name ("backend for frontend").

Thus, they are not the same: one is a wider term, another is a focused implementation of that concept.

And you can have multiple Backeds for Frontends different types of clients (i.e. browser, mobile)
This is very true! In practice I have seen that it is exceedingly difficult to write the GraphQL "sinks" (I don't recall the exact term) that can intelligently handle things like batching and understanding things like pre filtering, where one service in the composed call could and should be performed first to limit the result set. YMMV, in my experience it can be simpler to be more explicit about these things, especially when in "true" BFF the client team is also responsible for their immediate backend, which can give them that flexibility, at the cost, perhaps, of more boilerplate.
This is a really interesting reply, thanks for taking the time to compose it. As a soundcloud user, I actually noticed little things like how difficult the playlist loading problem might be and wondered precisely about how the client was getting updates as I scrolled. Interesting to know a bit more about the backend design.

I suppose I’m wondering still, in your example, why georestrictions couldn’t have just been an api feature in the list service vs both pieces of data needed to be fetched and reduced by a third service (and duplicate that logic across clients). I also work at a large company though, so I can see how “backends owned directly by client teams” is a path one might prefer when dealing with other teams with e.g. other priorities.

Looking forward to enlightening replies to your question, I don't get it either. Keycloak APIs are already hardened, how is security provably increased by creating a new, far less tested access layer for the browser to use?
I think the main attack vector they are trying to protect against is XSS attacks. If a malicious actor manages to inject client side code, there’s nothing preventing them from exfiltrating tokens and gaining persistent user access. This because there is no Secure Enclave to store tokens in in browsers. The bff pattern can solve this by using HTTP only cookies, keeping all session tokens on the server. For high security scenarios like banks and health it makes sense, but there are so many more attack vectors that it’s not gonna cover it all.
With an XSS exploit it is game over, you control the browser. Adding more complexity and opening up the possibility of CSRF exploits with BFF does not look like a good trade off to me.
You don’t open up for CSRF attacks if you use same site cookies, which I guess is part of why this pattern is seeing more use now.