Introduction
I just had a terrible week with one of my worst testing iteration ratios ever. I did eventually get Bubble to share files with asynchronous server-less functions; while averaging 4 hours of testing to fix 1 line of code. The goal of this project was to migrate our NodeJS code base out of custom Bubble plugin actions running in back-end workflows and into AWS Lambda. While porting our actual code was straightforward, troubleshooting the asynchronous POST
and GET
calls from AWS Lambda to the relative black-box of the Bubble API was a debugging nightmare of tedious old-school trial-and-error console logging.
Lessons Learned
Once we deduced how the Bubble API was handling POST
and GET
requests, the logic behind it made sense. It was just not obvious at all:
- When
POST
ing a file to the Bubble file upload API without setting the Private flag Bubble responds with aURL
directly to AWS S3, but without the protocol prefixhttps:
. - Conversely, a
POST
to the Bubble file upload API with the Private flag, and a thing’s unique id to attach to will return aURL
in the app’s home domain with the protocol prefixhttps:
. - Frustratingly,
POST
ing to the Bubble file upload API with only the Private flag set, or only a thing to attach to seems to result in an inaccessibleURL
. Perhaps because the privacy rules cannot be resolved? - Most troubling,
POST
ing to the Bubble file upload API is fully exposed to the public. It does not need theBearer Token
to be set in theAuthorization Header
. Although passing theBearer Token
in theAuthorization Header
does not result in a rejected request. - A file NOT marked as private and attached to when passed as a plugin parameter will have a
URL
directly to AWS S3, but without the protocol prefixhttps:
. - A file NOT marked as private and attached to is directly accessible on AWS S3 with a
GET
request. - A file marked as private and attached to when passed as a plugin parameter will have a
URL
in the app’s home domain with the protocol prefixhttps:
. - A file marked as private and attached to can only be indirectly accessed with a
GET
request to theURL
in the app’s home domain. Bubble will respond with a redirect to a temporary signedURL
on AWS S3. DO NOT set any headers, evencontent type
, when accessing the redirectedURL
on AWS S3. This will result in a rejected request; likely because of a conflict with theURL
signature. This redirection occurs because Bubble checks to see if the requested file can be released according to the security rules on the thing the file has been attached to. We are still investigating whether including theBearer Token
in theAuthorization Header
of the initialGET
request will cause Bubble to invoke the request as an administrator. We suspect this might NOT be the case. Buyer beware! - In
POST
s to workflow APIs Bubble will truncate empty and null fields from thePOST
edJSON
, before validating thecontent length
header. This means that if you specify thecontent length
header on a mostly emptyJSON
string yourPOST
request will be rejected. The safest solution is to simply not set thecontent length
header.
Recommendations
- Our biggest wish is for Bubble to add formal developer API documentation so that we can more productively support integrating our Bubble applications with external asynchronous services. Much of my debugging last week could have been avoided with clear documentation.
- It would be a big step forward for Bubble integration if they could publish a NodeJS SDK in the NPM ecosystem that provides a uniform interface to the Bubble API. Instead, I spent part of last week copy-pasting NodeJS Request boiler plate.