
Pattern: Back ends for front ends - r4um
http://samnewman.io/patterns/architectural/bff/
======
jtmarmon
This is how netflix approached api gateways.
[http://techblog.netflix.com/2012/07/embracing-differences-
in...](http://techblog.netflix.com/2012/07/embracing-differences-inside-
netflix.html)

However, this approach is a giant pain in the ass and technologies like Falcor
(netflix cannabilizing its own pattern) and (my preference) GraphQL will come
to replace.

With a generic client side query language, you don't need to deal with
versioning APIs, lots of concurrent development, overhead of deploying a new
API for each client, the list goes on. GraphQL in front of a set of services
is how we're approaching our next project and it's working really well so far.

~~~
igammarays
GraphQL/Falcor seem like a very elegant abstraction for "fetching" data. But I
see a performance problem arising - all data queries are not created equal,
and so it may turn out that there is a significant speed difference between
requesting {Object: [field1]} and {Object: [field1, field2]} as a consequence
of some particular implementation detail at the persistence layer (SQL joins
perhaps). A well designed BFF would abstract away this problem by providing a
set of individually optimized endpoints, presumably crafted in a way that
reflects the underlying persistence layer (like any good REST API) as well as
gathering data together for a particular client's needs, so that the front-end
designer can decide which calls to make, and whether requesting [field2] is
worth the cost.

The alternative in a GraphQL world would be to have a set of best-practices
which annotate the data model. So a backend engineer would write a piece of
documentation saying : "Warning: consider avoiding [field2] for significant
performance gains".

~~~
jtmarmon
> so that the front-end designer can decide which calls to make, and whether
> requesting [field2] is worth the cost.

How is this different in essence from an annotation?

It's also worth noting if you want to have guarantees that your front end
engineer doesn't fuck up your performance terribly by making bad queries
without them being analyzed or whatever, you can take the stored query
approach (this is what facebook does - also good for preventing accidental
data leaks) where you store each usable graphql query in a database, and
hardcode the query's ID into your application rather than the query itself.

------
virmundi
Or for those wanting to use an already defined pattern: API gateway pattern
[1]. Same idea, already identified.

[http://microservices.io/patterns/apigateway.html](http://microservices.io/patterns/apigateway.html)

------
avitzurel
Right now I am working on a talk around this area and an idea came to my mind
that I think is worth a discussion here on HN.

In today's front-end technologies with webpack and webcomponents why wouldn't
you compose application that call different services and compose the UI based
on these services.

For example, you have a login/welcome component that will call the auth
service and will check if the user is logged in or not and show the
appropriate message or login screen. If the Auth service is down you can
simply show a message.

This way, each component is aware of the service it has to use and you can
package it into the application deployment process.

It's worth a thought that if you already have micro-services you should also
break your application apart and not have a monolithic front-end.

I am not an Android/iOS guy so I'm not sure if this is even viable there but
these days, I'm pretty sure we'll start seeing front-ends that are composed
around small single-responsibility services.

One of the biggest advantages of that is that components and services are
independent, you can split the work between teams and the application
deployment will join everything together.

~~~
CuriousSkeptic
You should probably checkout some of Udi Dahans writings. During the CQRS-hype
he had some interesting texts on SOA in roughly that direction.

------
zaroth
AKA the BLL or Business Logic Layer? I guess the only reason you would re-
write business logic in the presentation layer is because you can't afford the
extra round-trips, and it's cheaper than writing an aggregation layer on your
backend.

But generally wouldn't you just add the APIs into the core microservice to
return the requested dataset (at the various necessary "levels" of
cardinality) for the various different consumers? Keeps everything in one
place.

Then you use nginx lua script to allow a single HTTP request from the client
to be dispatched to the various microservices and packaged together in the
reply in a singel round-trip. This can be just a few lines of code serving any
combination of possible sub-requests. I don't like the idea at all of building
another service layer on the backend to do the aggregation and expose a
different API... I think you can do something similar in the development
branch of HAProxy.

------
scotty79
Just remember that each arrow that crosses team boundaries on those graphs
costs a lot. Usually the cost is on the side of the team on receiving end.

------
olalonde
It seems GraphQL would be an alternative solution.

