Focus architecture for Payments micro-frontend.

Goal

Scope of this story is to:

  • Introduce an element of multi-tenancy architecture to allow companies’ users to manage their unconfirmed company payments.
End result user flow.

Prerequisites

If you are just interested to multi-tenancy and Amplify’s AppSync PoC, just continue. If you want to check how we ended up here, you can check Part 1 and Part 2 of this mini series.

Introduce APIs to Payments

In order to expose our Payments API, we will use Amplify to leverage AWS AppSync, which combines data into a single GraphQL endpoint. Let’s add APIs by executing the below command:

cd mfe-payments
amplify add api
amplify push
  • a new api folder got created under path amplify/backend/api.
  • a CloudFormation template which will provision AppSync configurations, IAM roles and lambdas to support the infrastructure for the GraphQL endpoint.
  • a dummy schema.graphql containing an annotated Todo model, which we will update shortly.
Generated code by add command.
  • created an AppSync configuration with a Datasource to access the above mentioned table. This also uses a number of resources (S3 deployment buckets, IAM roles, Lambdas, Cognito user pools) to glue our API with authorization mechanisms and store artifacts such as the GraphQL schema.
  • exposed a GraphQL endpoint which can be POSTed to perform any CRUD actions.
  • generated up to 8 GraphQL resolvers handling queries, mutations, and subscriptions on the type annotated with the @model directive.
Part of resources generated by CloudFormation stack.
The Payment model.

Supporting multi-tenancy

As simple as that: you do not want to build applications (or even PoCs) where independent companies can access each others’ private data. A multi-tenancy architecture is one of the foundations of the Saas model, where an application supports multiple customers via a single instance of a software and infrastructure.

Saas model with multi-tenancy.
  • tenancy isolation. As data is shared to the same database instance, tenant related data should be isolated from other data and accessed securely.
Create custom attributes in Cognito Users Pools.

Magic @nnotations

AppSync supports a bunch of annotations available, but to keep it simple, I decided to focus only @modeland @auth.

Auth annotation with defined rule.
amplify import auth
amplify push
CRUD operations on payment model.
Unauthorized mutation.

UI frontend changes

We will not go into details about frontend changes which you can check in great details in the Github repo. Simply, I introduce a dependency towards angular material components which I have used to beautify our app from our first blog part. The biggest changes introduced in frontend are:

  • Introduced paged table in payments to show off CRUD by using angular component forms for forms, table and validations.

Access tokens vs ID tokens

As mentioned earlier, access tokens are typically the default approach for GraphQL to authenticate requests, but as we have introduced custom fields in order to handle multi tenancy, we need some tweak in order to use the IDToken information instead. IDTokens differs from Access tokens as they contain claims about the identity of the authenticated user, our tenantId in our case. To make GraphQL to authenticate requests via IDToken rather than access token you need to add the below snippet to the main.ts Payments class.

amplify publish 

Demo time!

We made it! You can visit demo here by using the 2 users I previously created fit tenants A and B (userTenantA/passwordA & userTenantB/passwordB).

Frontend Limitations & Improvements

  • When I tried to publish the angular bundle, you may need to update the budget limit (do not worry, no money involved here :P) in the angular.json
  • Lack of global object not defined. I just needed to add a few lines here
  • Add creation of tenants in UI, rather than programmatically. This could imply rewriting the signing flow by dropping the withAuthentication HOC in fa out of programmatic use of Auth APIs. Can be fun to try that out!
  • Sharing styles in micro-frontend will be tricky at scale: make sure you invest some time into a strategy on how to share common style guide and shared code from parent to child components unless you just will reference all child styles into parent html (as I did fit the demo).

Backend Limitations & Improvements

  • To protect your GraphQL endpoints from XSS attacks and company, leverage AWS WAF to protect network access.
  • Integration with Leading keys check on Dynamo DB with Amplify workflow, to increase security and tenancy isolation at IAM level.
  • Multitenancy: more granular use cases and more deep dive into annotations.
  • Evolve and or

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store