As of January 2025, we’ve started adding optional backend functionality for PowerSync that handles writing to a backend database (with initial support for MongoDB) and generating JWTs.

This makes PowerSync easier to implement for developers who prefer not having to maintain their own backend code and infrastructure (PowerSync’s usual architecture is to use your own backend to process writes and generate JWTs).

We are approaching this in phases, and phase 1 allows using the CloudCode feature of JourneyApps Platform, a sibling product of PowerSync. CloudCode is a serverless cloud functions engine based on Node.js and AWS Lambda. It’s provided as a fully-managed service running on the same cloud infrastructure as the rest of PowerSync Cloud. PowerSync and JourneyApps Platform share the same login system, so you don’t need to create a separate account to use CloudCode.

We are currently making JourneyApps Platform CloudCode available for free to all our customers who use PowerSync with MongoDB. It does require a bit of “white glove” onboarding from our team. Contact us if you want to use this functionality.

Phase 2 on our roadmap involves fully integrating CloudCode into the PowerSync Cloud environment. For more details, see this post on our blog.

Using CloudCode in JourneyApps Platform for MongoDB Backend Functionality

There is a MongoDB template available in CloudCode that provides the backend functionality needed for a PowerSync MongoDB implementation. Here is how to use it:

Create a new JourneyApps Platform project

To create a new JourneyApps Platform project in order to use CloudCode:

1

Navigate to the JourneyApps Admin Portal. You should see a list of your projects if you’ve created any.

2

Select Create Project at the top right of the screen.

3

Select JourneyApps Platform Project and click Next.

4

Enter a project name and click Next.

5

There are options available for managing version control for the project. For simplicity we recommend selecting Basic (Revisions) and JourneyApps as the Git provider.

6

Select TypeScript as your template language, and MongoDB CRUD & Auth Backend as your template. Then click Create App.

Overview of the CloudCode tasks created from the template

To view the CloudCode tasks that were created in the new project using this template, select CloudCode at the top of the IDE:

Here you will find four CloudCode tasks:

Here’s the purpose of each task:

  1. generate_keys - This is a task that can be used to generate a private/public key pair which the jwks and token tasks (see below) require.

The generate_keys task does not expose an HTTP endpoint and should only be used for development and getting started.

  1. jwks - This task exposes an HTTP endpoint which has a GET function which returns the public JWKS details.
  2. token - This task exposes an HTTP endpoint which has a GET function. The task is used by a PowerSync client to generate a token to validate against the PowerSync Service. For more information about custom authentication setups for PowerSync, please see here.
  3. upload - This task exposes an HTTP endpoint which has a POST function which is used to process the write events from a PowerSync client and writes it back to the source MongoDB database.

Setup

1. Generate key pair

Before using the CloudCode tasks, you need to generate a public/private key pair. Do the following to generate the key pair:

  1. Open the generate_keys CloudCode task.
  2. Select the Test CloudCode Task button at the top right. This will print the public and private key in the task logs window.
  1. Copy and paste the POWERSYNC_PUBLIC_KEY and POWERSYNC_PRIVATE_KEY to a file — we’ll need this in the next step.

This step is only meant for testing and development because the keys are shown in the log files. For production, generate a key pair locally and move onto step 2 and 3.

2. Configure a deployment

Before using the tasks, we need to configure a “deployment”.

  1. At the top of the IDE, select Deployments.
  2. Create a new deployment by using the + button at the top right, or use the default Testing deployment. You can configure different deployments for different environments (e.g. staging, production)
  3. Now select the Deployment settings button for the instance.
  4. In the Deployment settings - General tab, capture a Domain value in the text field. This domain name determines where the HTTP endpoints exposed by these CloudCode tasks can be accessed. The application will validate the domain name to make sure it’s available.
  5. Select Save.
  6. Deploy the deployment: you can do so by selecting the Deploy app button, which can be found on the far right for each of the deployments you have configured. After the deployment is completed, it will take a few minutes for the domain to be available.
  7. Your new domain will be available at <domain_name>.poweredbyjourney.com. Open the browser and navigate to the new domain. You should be presented with Cannot GET /, because there is no index route.

3. Configure environment variables

To wrap up the deployment, we need to configure some environment variables. The following variables need to be set on the deployment:

  • POWERSYNC_PUBLIC_KEY - This is the POWERSYNC_PUBLIC_KEY from the values generated in step 1.
  • POWERSYNC_PRIVATE_KEY - This is the POWERSYNC_PRIVATE_KEY from the values generated in step 1.
  • MONGO_URI - This is the MongoDB URI e.g. mongodb+srv://<username>:<password>@<database_domain>/<database>
  • POWERSYNC_URL - This is the public PowerSync URL that is provided after creating a new PowerSync instance.

To add environment variables, do the following:

  1. Head over to the Deployment settings option again.
  2. Select the Environment Variables tab.
  1. Capture the variable name in the Name text field.
  2. Capture the variable value in the Value text field.
  3. (Suggested) Check the Masked checkbox to obfuscate the variable value for security purposes.
  4. Repeat until all the variables are added.

To finalize the setup, do the following:

  1. Select the Save button. This is important, otherwise the variables will not save.
  2. Deploy the deployment: you can do so by selecting the Deploy app button.

4. Test

Open your browser and navigate to <domain_name>.poweredbyjourney.com/jwks.

If the setup was successful, the jwks task will render the keys in JSON format. Make sure the format of your JWKS keys matches the format in this example JWKS endpoint.

Usage

Make sure you’ve configured a deployment and set up environment variables as described in the Setup steps above before using the HTTP API endpoints exposed by the CloudCode tasks:

Token

You would call the token HTTP API endpoint when you implement the fetchCredentials() function on the client application.

Send an HTTP GET request to <domain_name>.poweredbyjourney.com/token?user_id=<user_id> to fetch a JWT for a user. You must provide a user_id in the query string of the request, as this is included in the JWT that is generated.

The response of the request would look like this:

{"token":"..."}

JWKS

The jwks HTTP API endpoint is used by PowerSync to validate the token returned from the <domain_name>.poweredbyjourney.com/token endpoint. This URL must be set in the configuration of your PowerSync instance.

Send an HTTP GET request to <domain_name>.poweredbyjourney.com/jwks.

An example of the response format can be found using this link.

Upload

You would call the upload HTTP API endpoint when you implement the uploadData() function on the client application.

Send an HTTP POST request to <domain_name>.poweredbyjourney.com/upload.

The body of the request payload should look like this:

{
  "batch": [{
    "op": "PUT",
    "table": "lists",
    "id": "61d19021-0565-4686-acc4-3ea4f8c48839",
    "data": {
      "created_at": "2024-10-31 10:33:24",
      "name": "Name",
      "owner_id": "8ea4310a-b7c0-4dd7-ae54-51d6e1596b83"
    }
  }]
}
  • batch should be an array of operations from the PowerSync client SDK.
  • op refers to the type of each operation recorded by the PowerSync client SDK (PUT, PATCH or DELETE). Refer to Writing Client Changes for details.
  • table refers to the table in SQLite where the operation originates from, and should match the name of a collection in MongoDB.

The API will respond with HTTP status 200 if the write was successful.

Customization

You can make changes to the way the upload task writes data to the source MongoDB database.

Here is how:

  1. Go to CloudCode at the top of the IDE in your JourneyApps Platform project
  2. Select and expand the upload task in the panel on the left.
  3. The index.ts contains the entry point function that accepts the HTTP request and has a MongoDBStorage class which interacts with the MongoDB database to perform inserts, updates and deletes. To adjust how updates are performed, take a look at the updateBatch function.

Production considerations

Before going into production with this solution, you will need to set up authentication on the HTTP endpoints exposed by the CloudCode tasks.

If you need more data validations and/or authorization than what is provided by the template, that will need to be customized too. Consider introducing schema validation of the data being written to the source MongoDB database. You should use a purpose-built library for this, and use MongoDB Schema Validation to enforce the types in the database.

Please contact us for assistance on any of the above.