When you use low code tools like bubble.io, you sometimes feel like you are lacking the possibility to use custom software or code together with those tools. In this short article I want to show you how you can extend your bubble.io low code application with AWS Amplify.
Why would you want to extend bubble.io with a secure AWS Amplify API?
There is a simple answer to that: Focus on your core competency. Let me explain what I mean by that. Let’s assume you are a startup or young company focusing on a heavy data processing algorithm. That knowledge on how to process data is your core competence. However, to sell that competence, you need a decent web application. It should include a login, user profile, a payment option and should be responsive.
Consequently, you would need to develop a frontend application only to sell your data processing knowledge. That’s probably not what you wanted to do in the first place. Furthermore, you’ll have to take care of your deployment process as well as hosting. This can be quite cumbersome.
That’s why I want to show you how to concentrate on your core competence. While integrating bubble.io and an AWS Amplify API you can significantly lower the amount of custom code you have to write. By using an authenticator lambda function, you can make sure that your API is not exposed to the public internet.
How bubble.io and AWS Amplify are integrated
First things first. Let’s quickly recap what bubble.io and AWS Amplify can do for us.
Bubble.io is a low code platform that allows us to build complete web applications. It uses a visual editor to arrange UI components. Those components can be linked to database objects like users or booking. The actions that happen in bubble.io are defined by workflows.
AWS Amplify is Amazons low code framework. It helps us to develop and deploy custom applications on Amazons Web Services. Included in AWS Amplify is hosting (for example of a React single page application), APIs, database, storage for files and authentication. In contrast to bubble.io, for AWS Amplify you have to be a software developer to write the code that is needed to glue everything together. AWS Amplify gives you speed, but does require custom code.
For our example company (in data processing) we want to get the best of both worlds. That means, we can use AWS Amplify to develop and deploy the custom code that does the data processing. We will need to add a custom AWS lambda authorizer to secure our API. On the other hand we can leverage bubble.io to create our frontend application with login, database and payment.
The following diagram shows the high-level architecture of such a solution. You can see that we can develop our custom data processing as a docker image, that will be deployed with AWS Amplify (bottom right). The docker image will be deployed to AWS Fargate, which is managed for us by AWS Amplify. Furthermore, we have got an HTTP API Gateway, which is secured by a custom lambda authorizer. That authorizer secures our API and helps to integrate with bubble.io (blue dashed box). The frontend as well as data storage is done with bubble.io. The for the integration with Amplify we use the bubble.io API Connector plugin.
How to create secure connection from bubble.io to API Gateway
In order to keep this article concise and readable, I will focus on how to connect bubble.io API connector to a secure API Gateway. There are plenty of articles on how to create bubble.io apps as well as how to use AWS Amplify with docker containers. I will list some of them as references below.
1. Create Amplify API and bubble.io App
The first thing(s) you have to do, is to create the basic infrastructure. The frontend application should be built with bubble.io. A simple app with a single page is enough to follow this article. Furthermore, you need an AWS Amplify project to be set up. The only functional component needed from Amplify is a REST API in container mode. Therefore, you need to enable serverless containers in your project. The links in the references section below show you how to do all that.
2. Add custom authorizer lambda to HTTP API Gateway
If you use AWS Amplify with serverless containers (docker containers in AWS Fargate), then the framework will create an HTTP API Gateway for you. As opposed to the REST API Gateway, the HTTP API Gateway does not offer the possibility to create an API Key. However, if you want to protect your API, you need some kind of authorization.
In order to create that authorization, we will use an Authorization Header, which is sent by the bubble.io API Connector and checked by a custom lambda authorizer function. You can create that lambda function in the AWS console. The following snippet shows such a lambda function that runs on the Node.js 14 runtime. It gets the API Key as a secret from the AWS Secrets Manager and checks that the API Key is included in the request authorization header.
Make sure that you create an IAM Role while creating the lambda function. You will need that IAM Role ARN (the unique identifier of that role) later in order to allow the lambda function to get the API Key from the Secret Manager.
The next thing we want to do, is to create the secret API Key using the AWS CLI (see references). Furthermore, we will make sure that the lambda function can read that Secret by passing the secrets ARN as an environment variable to the lambda function.
This will return an ARN for the secret, which will be used below as YOUR_SECRET_ARN. The placeholder YOUR_AUTHORIZER_LAMBDA_FUNCTION_NAME needs to be replaced with your lambda function name.
As a next step you will create the lambda authorizer for the HTTP API Gateway that was deployed by Amplify. You need to replace YOUR_API_ID with the API ID, which you can look up in the AWS console.
The command above will create an authorizer. You need to look up the Authorizer ID in the AWS console and use it to replay YOUR_ATHORIZER_ID in the next command. It will add permissions for the lambda to be invoked by the API Gateway.
So far, the lambda function is not allowed to access the API Key. We allow the lambda function to access it by putting a resource policy (policy document as JSON in secretPolicy.json) on the secret itself.
The last thing we have to do, is to assign our new lambda authorizer to the routes in the API Gateway. The ID of the route has to be looked up in the AWS console to replace XXXX. Amplify only creates one default route, that routes all requests to the docker container.
3. Use the secure API in bubble.io
Our custom HTTP API Gateway is now deployed and secured. Now, we want to access it through the bubble.io API Connector plugin. To do so, we need to install the plugin in the bubble app. Since that is super easy (see references below), I won’t explain how this is done.
The API Connector Plugin needs to be configured correctly. It needs to send our API Key as an authorization header. There are three important configurations in the API Connector plugin, that we need to set.
- Authentication: Private key in header
- Key name: Authorization
- Key value: [Your secret API Key goes in here]
- (Optional) Development key value: If you have got a development environment, your second key goes here.
In the lower section of the plugin configuration, you can see a sample API call. That sample call requests a list of S3 buckets in the AWS Account. That simple GET call will include the secretToken in the Authorization header. The custom lambda authorizer will read and verify that this value matches the one that is passed as a secret by the AWS Secrets Manager.
We have seen how you can use AWS Amplify to develop and deploy your custom backend code. Since that code reflects your companies core competence, you want it secured by authentication. That can be achieved by using a custom lambda authorizer. This authorizer is the only piece of code that you need to put in between your secure integration of a bubble.io application and AWS Amplify.
While using bubble.io as a web application and deploying your custom backend code with AWS Amplify you leverage low code solutions that can speed up your development significantly. Moreover, you don’t have to take care of code deployment or other development activities that take away your precious time.
- Working with AWS Lambda authorizers
- Deploying a single container with Amplify Serverless Containers
- REST APIs in AWS Amplify
- bubble.io API Connector
- bubble.io – Getting started
- Configuring the AWS CLI
I'm Marco and my career is all about software. From development to support and coaching I have seen it all. I've worked at IBM as a consultant managing large customer projects and experienced globally distributed software development. As a software developer, I have built cloud-based infrastructures, programmed mobile apps, and assisted my teams in the role of Scrum Master.
I do believe that balance is an important part of life. Therefore, for me, mountain biking means not only downhill, but also uphill - no pleasure without work.