Transcript
This transcript was autogenerated. To make changes, submit a PR.
Jamaica make a real
time feedback into the behavior of your distributed systems
and observing changes exceptions errors in
real time allows you to not only experiment with confidence,
but respond instantly to get things working again.
Close hello
everyone, my name is Roman Boycker and I work as senior,
senior specialist solutions architect serverless AWS.
Today I'm going to talk a little bit how to implement
backend for frontend pattern with different
AWS serverless services.
Let's together remember what it means
and what it is about this backend for frontend
pattern. Essentially it was invented
and suggested by Sam Newman several
years ago, and the idea behind
this pattern is to
provide a certain layer of abstraction
which allows you to build and to consume
data from downstream microservices and
to present it for the frontend how
it looks like. So usually different teams
will develop different types of front ends. It could be
web applications, it could be mobile clients and
those different types of applications. They sometimes
will need different types of data, or they will
need different variations of data depending on different
requirements. If we imagine the situation
that we produce different front
ends, so there probably will be different teams doing
that. So there will be a team producing a
web frontend and a team producing different mobile front ends.
And if we don't implement this back end for front end pattern,
essentially that will mean that those teams will
go directly to different microservices to consume that data.
And this means that those services will
be tightly coupled to the implementation
of those microservices. And if you will need
additional data, probably you will need to write
additional logic on your front end. And essentially it
may mean that you will spend
more time integrating your frontend with different
back end services. And the idea came
here is to implement a simple
layer which we called back end for
frontend on the back end, which will be
responsible for implementing these integrations
and consuming data from different microservices
and then presenting that data to the
front ends. And this brings a lot of benefits
because now the front end team will own this
back end service and they can easily
change it, implement different logic and implement
different presentation for different front ends.
But on the other hand, the frontend
itself will have like one particular endpoint
to connect to and to consume all the necessary
data and to have all the necessary interactions.
It will decouple your frontend from the
back end services and it will allow you to modernize
front ends and change them quickly and
also depending on different requirements,
this web back end for frontend and
mobile back end for frontend may communicate with different
services and store different set of data,
but how you can use and build those backend
for frontend implementations with AWS
and specifically I'm going to talk today more
about serverless implementations because I believe
this is in many cases the most suitable
way of implementing backends for front ends
pattern. First of all,
what does serverless mean to you and
why it breedens additional benefits when you start implementing,
for example, back end for front end solutions
on it. First of all, as it implies,
you don't need to spend a lot of time on managing the
infrastructure to provision it, to patch it,
and to do all the things it is done for you by AWS.
So you can focus more on writing some code
tests, implementing data
storage, and in the
end producing the necessary
functionality faster. Another very important characteristic
of serverless is that of automatic scaling. That means
that essentially you don't need to
think a lot about how your service will scale
under the load, and if you have different spikes
of traffic, how you should implement additional
resources and provision them. It will in many
cases done automatically. And if then
the traffic goes down, the serverless
services will scale down automatically as well.
Another very important thing here is highly
available and secure configurations. Again, because we
as AWS built those services, we already
implement them in a well architected way. We implement
a lot of availability and security best practices
within those services. Of course you will need to think about availability
and security, but at a much higher level.
So you won't be thinking about how to patch, for example
operating system, how to implement
some security controls on the network traffic.
So these things will be done automatically.
And the last but not the least important characteristic
of serverless is that you pay for what you use. So if
you don't consume any serverless services at a given period of
time, you will pay nothing. But again,
it is very important, especially for development and test
environments. So you can have dev environments for
each developer to try things out,
or you can run different tests at a fraction of costs compared
with traditional infrastructure where you will need to provision and
have serverless or containers infrastructure.
But let's look how you can implement.
And essentially we have a big serverless
portfolio which allow you to implement
business logic, to store the data, to implement synchronous
and asynchronous communication between different services,
and implement security and development
features. But let's look how we
can start implementing our backend for frontend with
this set of services. Probably the simplest
and the easiest way of doing that is
to have an API gateway as a frontend door.
Implementing and exposing restful
API for your front end then having a
lambda function or a set of lambda functions,
implementing business logic, implementing different
transformations and a dynamodb
table where you will store all the data necessary
for your particular frontend. But what
is missing here for sure, AWS you remember
you will need to interact with downstream microservices and
get some data out of there. How you can
do that we can have different microservices
running in our back end owned by different teams,
but then we will need a set of event
consumers which will either get the events
in event driven architecture from those microservices,
or going explicitly to
those microservices, querying them and
storing that data into a dynamodB table.
Let's look in the details how you can
approach implementing those event consumers with again
AWS services. The first pattern
we will look into is event driven pattern.
So if your downstream and back
end microservices already using
event driven architectures and producing different events,
probably you will be using Amazon Eventbridge as
event router and those events from
those backend services will be
sent to the event bridge. And in the event bridge
you can define different rules to match a
particular set of the events you are interested in.
And then if those events match those
rules they will be for example directed to a lambda
function. Or again we have different destinations
and for those destinations you can
store those events, process them, change them,
and in the end again store in a dynamodb
table another scenario
you can think of how to populate your dynamodB
table with data from backend services is
to implement a webhook. Again,
when you implement a webhook, usually a webhook is a
quite simple web endpoint
which responds to get or post requests
with some data in them. And the simplest
way how you can do that on AWS is to implement
those endpoint with a lambda function.
But lambda functions, they have additional functionality
added quite recently which is called function URLs.
And this functionality allows you to expose your lambda
function directly via an HTTP endpoint
so you won't be needing an
API gateway here to create such webhooks.
And then you can send that
HTTP endpoint to the teams implementing
this or that microservice and then they will
send HTTP requests, get post
put or whatever you implement and how
you agree with
those teams and send the data to your lambda functions
directly with HTTP requests. And then
again in your lambda functions you can implement additional business logic.
Maybe you will transform those events to another
view, or you can again enrich them by
going to and querying additional microservices in
the back end and then in the end you will again store that
data in a dynamodb table,
another pattern which is quite common.
If the downstream services can't produce events
or can't send HTTP requests in the form of
webhooks, probably they still have some kind of
APIs or interfaces you can query to get
the data for your frontend, but here you
will need some kind of a polling mechanism how
you will initiate connections and query those services
the simplest way to do that is to utilize
Amazon Eventbridge scheduler.
So with a scheduler you can schedule
producing some events and those events will trigger a lambda
function. And again with scheduler you can schedule
events to run periodically, maybe each minute,
each day. You can even create a cron job expressions
and identify how often
those events should trigger. And then
once they trigger they will invoke
a lambda function. And again in that lambda function you can
implement a business logic, a connection to the downstream microservices,
to different APIs. It could be again a rest API,
it could be a GRPC API, it could
be maybe going to a particular queue and
get some messages out of that queue.
Again, depending on the contracts exposed by those
microservices, you will consume that data into a
lambda function and then you will again transform it
or save as it is or in reach by
making additional calls to the additional endpoints and
store that data into a dynamodb table.
So now we already have
quite capable implementation for our backend
for frontend pattern. And yeah, we can
consume and get interesting data
and necessary data for our front end from different
resources from different microservices,
either by schedule or by the webhook,
or implemented an event driven architecture and
all that data is accumulated in our dynamodB table and
then can be consumed through a rest API by
our front ends. But if
we want to go into production for sure we need to think about
additional things like security and observability and
add those features before we
make our service publicly available.
For security. For sure you will need to implement
authentication and authorization in many cases,
and we have a service which is called Amazon Cognita and
your frontend can go there and
present a login form and
your users will log in via Amazon
Cognito. The frontend will get a JIt token
and then you can use that Jit talking to
authenticate into Amazon API gateway.
And API Gateway will check the token
and either provide or deny access to
the endpoint. Another very
important thing, especially when we're talking about
different types of integrations, is that probably
if you go in to query this or that microservice,
you will need to store maybe an API key or some
credentials or other secrets to
interact with those services. And for sure it's
a bad practice to hard code that things.
And you will need some kind of mechanism where you will
securely store all that secrets and
get those secrets only when you issue particular
calls to the downstream services. And for that you
can use AWS secrets manager
service. And another
very important thing when you go into production
is of course observability. Because we want to know
how our service works and
whether there are some issues or not, and we want to
act upon any kind of
problems or things happening with
our services. And for that for sure we need to implement observability.
And again, the simplest way doing that
is to use Cloudwatch and x ray services
and all services like API, Gateway,
Lambda and Dynamodb. They send logs
and metrics to Cloudwatch where you can then go
and look for logs and metrics. And also you can
enable integration between API Gateway and
lambda with x ray. And x ray
allows you to make traces.
So if the request comes to the
API gateway, it will generate a new trace id and
send that information to the x ray and pass that trace
id to a lambda function. Then a lambda function will
make some calls to a dynamodb table or make
some other things, and all that information will
be recorded in an x ray. And then you can get
a trace that this particular request went through,
API gateway lambda function and a dynamodb
table for example. And you can look whether there
were some bottlenecks issues with that request or not.
Another thing I wanted to present you
a little bit in terms of serverless services and
backends for front ends is service called
AWS step functions and how
it can also help you to implement your
back end for front end pattern and
in what scenarios it can be useful,
but at first what step function does.
It is a state meshing which consists
of different states and transitions between those
states and allows you to implement different workflows and
orchestration patterns in your application.
And it has a number of benefits
because it has a visual representation
you can quite easily and fast
build prototypes and integrate with different
services. Again, it has a lot
of built in integrations and you won't
be writing a lot of code for
maybe simple transformations.
For example, if you want to run some actions in parallel,
for example querying different APIs at
the same time. If you want for example have
some scheduled actions timeouts,
it is already built in into step functions, so you
can write much, much less code to
implement those interactions.
And you can use a visual editor
to model your workflows.
And then there's monitoring
features which allows you to see how
those workflows behave.
And let's look at an example how you can utilize
step functions to implement
different workflows for your back ends. For front end applications.
Let's imagine an example case
where we are building a booking service,
and in that booking service we will need to,
for example, book a flight,
hotel, maybe rent a car and
add maybe some additional things.
And we want to
book this travel as a whole.
Because for example, if I can't book a car,
probably I'm not interested in going to Grand Canyon
or I'm not interested in a flight
if I can't book a hotel. But if
I already booked a flight and can't book
a hotel, there should be a mechanism to revert all
the previous steps,
and usually it is implemented with
a saga pattern which
allows you to roll back different actions
and use this sequence
diagram to implement some kind
of a distributed transaction when you
need to interact with different
services. For example, book hotel, flight and
rent a car. And if something goes
wrong at each step of this sequence,
you will need to have a way to revert everything
back. And the sega pattern is an implementation of
such approach. So for
example, if in my workflow book flight
fails, I already booked a hotel, but I
also implemented a cancellation
logic, so rollback
logic to cancel hotel. So once my
book flight call fails, for some reasons,
I can go and cancel hotel
booking. And these workflows you
can easily implement with step functions. And a good thing here
is that step functions can be even integrated
with API gateway, and you can integrate them directly.
So for example, if you want to build some kind of
a workflow for your backend, for frontend
and present some data, accumulated data
from different microservices or orchestrate calls to
different microservices, aggregate some
data and then send it to the front end. You can
do that easily with step functions.
So you can make different calls. Again, you can make
those calls sequentially, or you can make them in parallel.
For example, if you want to just query several
endpoints simultaneously, you can use
parallel execution and then you can get all the
responses back and aggregate them and via
API gateway send the response back to the customer.
So it is quite powerful service and you
can implement different workflows with step functions.
And the good thing, as I mentioned, there's synchronous
invoke mode, so you can use it
for real time or close to real time interaction.
So I make a call step function state mesh and start executing,
get some data and return those data via
API gateway. Or you can also use them asynchronously
so a query comes asynchronous, invocation starts
maybe doing some updates and things
and the response is sent immediately
back to the caller that yeah, we got
your request, we start processing that.
So here you have different ways of
implementing such interactions.
Also, to conclude my talk, I wanted to share a
couple of interesting and useful resources and
links if you want to learn more
about microservices, about different
patterns, well architected
framework and also some sample code
how to implement business logic in a form of
lambda functions with for example typescript which
is quite common language for the front end
developers. There are tons of samples and
things you can utilize to start
developing your serverless back end for front end
applications. And again, you're not limited only
for implementing back end for frontend pattern.
You can use serverless services to
implement any other microservices and even
you can use them to implement back end
for your micro
front end applications. So we have a set
of new articles and examples produced
by my colleagues how to deal with
and how to build micro front ends on AWS as
well. With that thank you very much and again,
if you will have any questions you can reach me on Twitter. Her and
I will be happy to discuss any kind of projects
you have in mind to build on serverless.