Extending BCMS Function

BCMS Functions are JavaScript functions that you can execute by sending an HTTP request to the back end API. Once you create a function, it will be available at
POST: https://{CMS_DOMAIN}/api/function/{FUNCTION_NAME}.

Creating a BCMS function

To create a function, create a file inside src/functions, for example ping-pong.ts.

To keep it simple, this function will be public and echo back a request body.

src/functions/ping-pong.ts


import { createBcmsFunction } from '@becomes/cms-backend/src/function';

export default createBcmsFunction(async () => {
  return {
    config: {
      name: 'ping-pong',
      public: true,
    },
    async handler({ request }) {
      return {
        requestBody: request.body,
      };
    },
  };
});

After saving the file and starting the BCMS you can send a POST request to /api/function/ping-pong. Request and response should look like this:

POST http://localhost:8080/api/function/ping-pong
Content-Type: application/json

{
  "message": "Hello world!"
}

---------------

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 17 Mar 2023 13:18:16 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 68
Connection: close
X-Powered-By: Express
Access-Control-Allow-Origin: *
ETag: W/"44-r1QIq4dWf0ZgljC19i8Qi20S0LY"

{
  "success": true,
  "result": {
    "requestBody": {
      "message": "Hello world!"
    }
  }
}

That's it! You just created a BCMS Function. Since functions are running on the back end, they have access to all BCMS's core utilities and helpers. This means that functions have access to the database and, for example you can return list of all Entries in a specific Template:

src/functions/ping-pong.ts


import { createBcmsFunction } from '@becomes/cms-backend/src/function';
import { BCMSRepo } from '@becomes/cms-backend/src/repo';

export default createBcmsFunction(async () => {
  return {
    config: {
      name: 'ping-pong',
      public: true,
    },
    async handler() {
      const entries = await BCMSRepo.entry.methods.findAllByTemplateId(
        'TEMPLATE_ID'
      );
      return {
        entries: entries.map((entry) => {
          return {
            id: entry._id,
            title: (entry.meta[0].props[0].data as string[])[0],
          };
        }),
      };
    },
  };
});

Public vs Private functions

In the example above, you created a public function. This means that anyone can call thatfunction, from anywhere without authentication. Public functions are useful if you need to return publicly available data to many different clients.

In contrast to public functions, private functions require an authentication using HTTP Signature which is available out-of-the-box with BCMS Client package.


Deploying a function

When you are ready to deploy your function to the CMS, follow these steps:

  • Inside the project, run npm run bundle. This will compile TypeScript files and bootstrap the project.
  • Then, to deploy your function, run npm run deploy.