DEV Community

Cover image for How I save $$$ by using Cloudflare Workers
Assim EL HAMMOUTI
Assim EL HAMMOUTI

Posted on

5 1

How I save $$$ by using Cloudflare Workers

Hi ! In this post (and as the title say) i'll show you how I save $$$ by using Cloudflare Workers instead of AWS's API-Gateway to proxy requests to my AWS Lambda functions.

Why use Cloudflare Workers ?

It's all about the cost. 10 million api requests will cost you :

  • With API-Gateway: \$35
  • With Cloudflare Workers: \$5

We can say that Cloudflare Workers saves you 85% compared to API-Gateway !!

Getting Started

First, create a new node project, in this blog post i'll be using yarn:

mkdir worker-proj
cd worker-proj
yarn init -y
Enter fullscreen mode Exit fullscreen mode

then install some dev packages that we'll need mainly for bundling our worker:

yarn add dotenv-webpack webpack webpack-cli -D
Enter fullscreen mode Exit fullscreen mode

also we need aws4 to sign our requests to aws:

yarn add aws4
Enter fullscreen mode Exit fullscreen mode

Webpack config

We're using webpack in order to bundle our code and use it as a worker.

Create a new file in the project and call it webpack.config.js, and paste the following code into it:

const Dotenv = require('dotenv-webpack')

module.exports = {
  entry: './worker.js', // This will be our entry file
  mode: 'production', // We're building for production to optimize our worker
  plugins: [new Dotenv()], // we'll be using a .env file to store our TOKENS
  optimization: {
    minimize: true,
  },
  performance: {
    hints: false,
  },
  output: {
    path: __dirname + '/dist', // this is the output folder
    publicPath: 'dist',
    filename: 'worker.js', // and this is where our final code will be at.
  },
}
Enter fullscreen mode Exit fullscreen mode

The Tokens we need

We need to specify 4 essential params:

  • ACCESS_KEY, SECRET: Get them from AWS IAM.
  • REGION: The region where our Lambda func lives.
  • FUNCTION: AWS Function name.

once you have all these params, create a .env file and add them to it.

Writing the worker

First, create a file, we'll name it worker.js.
Then, import aws4 and create a credentials object to store our AWS keys:

import aws4 from 'aws4'

const credentials = {
  accessKeyId: process.env.ACCESS_KEY,
  secretAccessKey: process.env.SECRET,
}
Enter fullscreen mode Exit fullscreen mode

Now we write our worker function. It accepts a request param and returns the response of a request sent to our Lambda function.

async function worker(request) {
  const reader = request.body.getReader()
  // getPayloadFromReader is a function that we use to get the body of a request
  const payload = await getPayloadFromReader(reader)
  // we sign our request using the credentials we created earlier
  const req = aws4.sign(
    {
      method: 'POST',
      service: 'lambda',
      region: process.env.REGION,
      path: `/2015-03-31/functions/${process.env.FUNCTION}/invocations/`,
      body: JSON.stringify({ httpMethod: 'POST', body: payload }),
    },
    credentials
  )
  // then we send the signed request to the lambda function and return the response
  return fetch(`https://${req.hostname}/${req.path}`, {
    method: req.method,
    headers: req.headers,
    body: req.body,
  })
}

// The next 3 lines show you how to invoke a worker function using Cloudflare Workers
addEventListener('fetch', event => {
  event.respondWith(worker(event.request))
})
Enter fullscreen mode Exit fullscreen mode

As for getPayloadFromReader:

function binary_to_string(array) {
  // We need this function to convert binary to string
  var result = ``
  for (var i = 0; i < array.length; ++i) {
    result += String.fromCharCode(array[i])
  }
  return result
}

async function getPayloadFromReader(reader) {
  let payload = ''
  while (true) {
    let { done, value } = await reader.read()
    if (done) {
      break
    }
    payload = payload + binary_to_string(value)
  }
  return payload
}
Enter fullscreen mode Exit fullscreen mode

Time to test !

To test what we've done so far, add the build script to your package.json:

{
  "name": "worker",
  "version": "1.0.0",
  "main": "worker.js",
  "license": "MIT",
  "scripts": {
    "build": "webpack -p --progress --colors"
  },
  "dependencies": {
    "aws4": "^1.8.0"
  },
  "devDependencies": {
    "dotenv-webpack": "^1.5.7",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

and run yarn build, then copy the code that'll find in dist/worker.js.

Once you copy the worker code, head to https://cloudflareworkers.com and paste the worker code in the red-bordered section then click on update.
CloudflareWorkers.com

In the right section (green-bordered) of the screenshot above you can see test different kinds of requests.

Conclusion

Now you can save some 💰💰 by using Cloudflare Workers !!

Have a great week !

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more