Creating the Equipment Management App BFF¶
So far we have created the Equipments
microservice with its own Equipment
entity, including a GraphQL query to get them. However our service cannot be
accessed from outside the ecosystem. This is by design, microservices live in an
isolated ecosystem, where they can communicate with each other using the message
bus, but they cannot receive nor send any message or call to the outside world.
All external communication must be handled by a Backend For Frontend (BFF)
service.
We do not create a BFF for each microservice, instead, we create one for each
Application
or Frontend
that we have (hence the Frontend
on the name). For
example we have the Admin Center BFF
.
The responsibility of the BFF are:
- Cohesively integrate multiple services to create an API surface suited for a given Frontend
- Handle the transport layer security (certifications, etc.)
- Handle Authentication/Authorization
We are going to create an Equipment Management BFF
so we can later create a
Frontend application for managing Equipments.
Creating the Backend for Frontend Project¶
To begin with the BFF creation we are going to use a template. As we mentioned before, the BFF is for the frontend, hence it is named after the UI application instead of any services it wraps.
For the purpose of this tutorial, our app will be called Equipments Management App (EMA).
Lets run the following on a bash compatible console, on the dotnet
directory:
Important
Don't forget to activate the console with the source activate.sh
command.
Bash | |
---|---|
- bff: this is the name of the BFF template.
- -n: the name for our BFF.
- --BoundedContext: the bounded context for our BFF. We create a new one for the EMA (Equipment Management App). We do this, because usually applications include other services to implement the features the frontend needs.
- --EntityName: an entity name to be use to setup some sample code on the newly created BFF.
Lets check what the template has created for us by running:
Bash | |
---|---|
The solution should look like this:
As you can see we have an executable project for our service, the
ITsynch.Suite.EMA.Bff
and an Suite Module for UI Localization, this one
includes the localization resources that our UI application will use.
Note
We try to configure the BFF and let the BFF provide the config to the UI, so that the UI has no configuration at all: we configure "the app" (both bff and UI) through the BFF's appsettings.json Check the SpaConfiguration module if you wanna learn more about this.
Our microservice is not included as it belongs to another Bounded Context. But
since we are going to be working on both the microservice and the BFF it is a
good idea to include the microservice on the .tvproj
file of our EMA bounded
context so that we can work on them both in the same VS instance.
To do so, open the /dotnet/src/services/EMA/ITsynch.Suite.EMA.tvproj
and add
the following project references below the existing ones:
XML | |
---|---|
Now close and re-open the EMA Bounded Context with ./slngen.sh
and we should
see de Equipments
projects included on our solution.
Exposing the Equipments query to the outside world¶
As we mentioned, the equipments
query from the Equipments
microservice
cannot be access directly form outside the ecosystem. The BFF is in charge of
acting as a proxy for it. To achieve this the BFF uses a concept called
Schema Federation. To setup
federation we need 2 configurations:
- On the microservice, publish its schema to a federation.
- On the BFF, declare the name of the federation it represents.
Publishing the Equipments schema to the EMA federation¶
To publish the Equipments
schema we need to add a new file called
federations.json
on the ITsynch.Suite.Equipments.Application
project. Inside
the file we should write the following configuration:
Important
The name is important as it is read by convention.
JSON | |
---|---|
- Federations: is a list, because a microservice can publish its schema to many federations.
- SchemaName: the name the schema will have on the federation. We can use the name of the microservices, or we can change it, for example, to avoid collisions.
- FederationName: the name of the federation where we want to register to. This name will be used by the BFF to search for the published schemas. We generally used the same as the frontend, when possible.
- IgnoreRootTypes: this tells the microservice not to publish all the GraphQL fields. We want to explicitly control what fields are published. See this.
- SchemaExtensionFiles: the list of file where we define what is going to be published.
Now we need to create a new file called EMA.extensions.graphql
on the root of
our microservice project. Inside it we need to extend the Query
type and add
the equipments
field. The easiest way is to run our microservice and access
the playground. There we can check the schema definition, we need to fine the
equipments
query definition and copy it and paste it on the
EMA.extensions.graphql
. After doing so we need to apply 2 changes:
-
Add the
extend
keyword. -
Add the
@delegate()
directive.
GraphQL | |
---|---|
With this setup we are telling the federation that we want to publish a field
called equipments
on the BFF that when call will be redirected to the
equipments
field on the microservice. Please read
this article
for a more thorough explanation.
Consuming the Schema on the BFF¶
Now that the microservice is ready to publish the schema, we need to setup our
BFF to consume it. On the appsettings.json
file of our BFF we are going to
find the following:
JSON | |
---|---|
The template has left some placeholder for us. The FederationName
is already
set, but we need to change the backend-for-frontend
text with the actual name
for our microservice, and also set a correct address for it. We are going to use
equipments-service
for the name, and 22009
for the port. Also we need to set
the correct schema name in the RemoteSchemas
list, in this case equipments
.
Important
When creating a real service, discuss with the Suite Framework team what name and port to be used.
JSON | |
---|---|
We need to tell the BFF to register the default root types so the microservice
can extend them. Fortunately this is already included by the template, you can
check the EMABffModule
, it should contain the following:
C# | |
---|---|
Finally we need to go back to our ITsynch.Suite.Equipments.Application
project
and change the launch settings on the launchSettings.json
file so our
microservice start on the assigned port 22009
.
JSON | |
---|---|
Now we should be able to run the service and the BFF. First we need to start the
Equipments
microservice and then the EMA BFF
. We should see the equipments
query on the GraphQL playground of the BFF.
You can start both projects at the same time by using right clicking on the Solution, Run Multiple Projects, and choosing both the BFF and the Equipments.Application.
If we now browse to http://localhost:22009/graphql we should see our BFF's GQL
endpoint with our equipments
query.