Fear and Loathing with the Bubble API

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 POSTand 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:

  1. WhenPOSTing 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:.
  2. Conversely, a POST to the Bubble file upload API with the Private flag, and a thing’s unique id to attach to will return a URL in the app’s home domain with the protocol prefix https:.
  3. Frustratingly, POSTing to the Bubble file upload API with only the Private flag set, or only a thing to attach to seems to result in an inaccessible URL. Perhaps because the privacy rules cannot be resolved?
  4. Most troubling, POSTing to the Bubble file upload API is fully exposed to the public. It does not need the Bearer Token to be set in the Authorization Header. Although passing the Bearer Token in the Authorization Header does not result in a rejected request.
  5. 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:.
  6. A file NOT marked as private and attached to is directly accessible on AWS S3 with a GET request.
  7. 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 prefix https:.
  8. A file marked as private and attached to can only be indirectly accessed with a GET request to the URL in the app’s home domain. Bubble will respond with a redirect to a temporary signed URL on AWS S3. DO NOT set any headers, even content type, when accessing the redirected URL on AWS S3. This will result in a rejected request; likely because of a conflict with the URL 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 the Bearer Token in the Authorization Header of the initial GET request will cause Bubble to invoke the request as an administrator. We suspect this might NOT be the case. Buyer beware!
  9. In POSTs to workflow APIs Bubble will truncate empty and null fields from the POSTed JSON, before validating the content length header. This means that if you specify the content length header on a mostly empty JSON string your POST request will be rejected. The safest solution is to simply not set the content length header.
Recommendations
  1. 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.
  2. 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.
21 Likes

Thanks for sharing this with the community!

1 Like

Bookmarked! thanks @aaronsheldon likely to save a tonne of time sometime in the future, kudos :+1: :+1: :+1:

1 Like