How to Share Code Between Serverless Functions

Different techniques to share code between serverless functionsToday, almost all the popular cloud service providers support serverless functions. Some popular ones are AWS Lambda, Azure Functions, Google Cloud Functions, Cloud Flare Functions, etc. Ov…


This content originally appeared on Bits and Pieces - Medium and was authored by Ashan Fernando

Different techniques to share code between serverless functions

Today, almost all the popular cloud service providers support serverless functions. Some popular ones are AWS Lambda, Azure Functions, Google Cloud Functions, Cloud Flare Functions, etc. Over the years, these functions have evolved from running utility code to full-fledged applications.

However, one common challenge across all the serverless function platforms is its inherent limitation on sharing code between functions. Though several cloud providers introduced novel approaches to share code (e.g., AWS Lambda Layers), most of these techniques are application-specific and may be limited to general-purpose sharing. Therefore, many create packages (e.g., NPM) to share code between functions.

But are there any special techniques, tools, or platforms to improve code sharing? And, what are the significant limitations we need to address when sharing code between functions? Let’s find out.

Why Sharing Code Between Functions is Difficult

Serverless functions, by nature, are distributed systems in runtime. Though this is useful for scaling and functional isolation, it creates challenges when sharing code.

Suppose we need to use a date-time utility code between two serverless functions. And, if we set up the code within a single code base, including the two functions and date-time utility code, for any change made to the date-time utility code, we need to test both functions and deploy them.

project-root/

├── date-utils/ # Shared date-time utility code
│ └── date-utils.js # Main file exporting utility functions

├── function1/ # Serverless function 1
│ └── handler.js # Main handler for function 1 using date-utils

└── function2/ # Serverless function 2
└── handler.js # Main handler for function 2 using date-utils

Doing it for two functions may seem relatively straightforward. But, when the number of functions and shared code increases, it becomes difficult to keep track of the dependency graph of each function. Also, having to update all the functions when a shared code changes defies its purpose.

The main bottleneck here is that, each fucntion depends a specific portion of the code in the file system.

Sharing Code using Packages has a Major Limitation

That’s why sharing code using packages has become popular for serverless functions. With packages, each function can depend on a particular version of the shared code. Yet, packages introduce two significant problems.

  1. Each package has its lifecycle, and testing them with functions becomes complex.
  2. Tracking the dependency graph of functions → packages and packages → packages and their respective versions is a challenge.

Therefore, when the functions and their dependencies grow in numbers, making dependencies into packages doesn’t scale well. Even if aggregating more functionality into a package limits their number, it makes it difficult to track the impact when we modify them since different functions depend on different sets of functionalities.

However, newly added features like NPM workspaces somewhat reduce complexity; a fundamental approach is required to share code between functions.

Introducing Bit for Serverless Functions

In the world of Bit, the fundamental code unit is the component. These components can be put together to build complex applications.

Bit Components

This is achieved by the Bit platform and its tooling by encapsulating the component code, versioning it, managing the component dependencies, and detecting component changes.

And do these features sound familiar to you? These are the exact problems we need to address when sharing code between serverless functions.

Bit Support for Different Serverless Functions and IaC Frameworks

AWS Lambda, Pulumi, CloudFlare Workers

Bit already supports several serverless function types. These include;

  1. AWS Lambda (Direct) — Demo Scope
  2. Serverless Functions using Pulumi (Supports AWS Lambda, Microsoft Azure Functions, Google Cloud Functions) — Demo Scope for AWS Lambda
  3. Cloudflare Workers — Demo Scope

Bit implements App types, Envs, and Generators (Part of Env) to support the deployment, local emulation, and testing of Serverless functions or the IaC framework.

  • App types — Handles the deployment of the Serverless function
  • Envs — Handles bundling, lining, etc., of the Serverless function
  • Generators — Uses templates to create the skeleton of the function

With this support, we can directly create serverless functions that support different cloud providers. Following is an example of an AWS Lambda function created as a Bit component that uses the Pulumi IaC framework.

import { APIGatewayProxyHandler } from 'aws-lambda';
/*
Below, dateUtil is a dependent component (reusable piece of code)
*/
import { dateUtil } from '@bit-pulumi-lambda/demo.utils.date-util'

/*
Lambda function handler
*/
export const handler: APIGatewayProxyHandler = async () => {
const dateType = process.env.DATE_TYPE || "";
const message = `Hey!, ${dateType} is ${dateUtil(dateType)}`;

return {
statusCode: 200,
body: JSON.stringify({ message }),
};
};

Here, you can see that the function usesdate-util as a dependency tracked as a separate component (not just another NPM package) in the Bit platform.

Code Sharing using Components Between Functions

Components can play a significant role at scale when it comes to code sharing. Let’s look at an example where date-util component is used by two Lambda functions. Below is the dependency graph tracked in the Bit Platform.

Example Dependency Graph: Date-Lambda and Hello-Lambda uses Date-Util

Suppose we want to modify the date-util function code. If we don’t use components and all the code in a monorepo, we need to manually find out the dependent functions, test them with modified code, and finally, deploy both functions to AWS.

One unique benefit of this approach is that since all the functions and dependent code are colocated in the same Git repo, it's easier to modify and verify the changes.

With Bit workspaces, you can gain the same benefit even if your functions are spread across multiple applications, where you can import all the required components to your workspace and work with them as if they are in the same repository colocated together.
Bit workspace/

├── component-date-utils/ # Shared date-time utility component
│ └── date-utils.js # Main file exporting utility functions

├── component-function1/ # Serverless function component 1
│ └── handler.js # Main handler for function 1 using date-utils

└── component-function2/ # Serverless function component 2
└── handler.js # Main handler for function 2 using date-utils

Overall, this creates a unique development experience for working with serverless function components and shared components.

Unique dev experience for Serverless function development

CI/CD Support for Function with Ripple CI

The next advantage of using components for serverless functions is that it's easier to set up a CI/CD pipeline that can detect the modified components and their dependencies and finally release the functions that were affected.

Following is an example of the build that is being triggered after modifying the count-lambda function using Ripple CI.

Example of modifying count-lambda

Since the unit tests fail for the function, Ripple CI stops releasing the count-lambda function to AWS. One of the main benefits here is that once the error is fixed, Ripple CI can continue from that function, building the affected components in the dependency graph.

Learn More


How to Share Code Between Serverless Functions was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Ashan Fernando


Print Share Comment Cite Upload Translate Updates
APA

Ashan Fernando | Sciencx (2024-09-30T19:56:54+00:00) How to Share Code Between Serverless Functions. Retrieved from https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/

MLA
" » How to Share Code Between Serverless Functions." Ashan Fernando | Sciencx - Monday September 30, 2024, https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/
HARVARD
Ashan Fernando | Sciencx Monday September 30, 2024 » How to Share Code Between Serverless Functions., viewed ,<https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/>
VANCOUVER
Ashan Fernando | Sciencx - » How to Share Code Between Serverless Functions. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/
CHICAGO
" » How to Share Code Between Serverless Functions." Ashan Fernando | Sciencx - Accessed . https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/
IEEE
" » How to Share Code Between Serverless Functions." Ashan Fernando | Sciencx [Online]. Available: https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/. [Accessed: ]
rf:citation
» How to Share Code Between Serverless Functions | Ashan Fernando | Sciencx | https://www.scien.cx/2024/09/30/how-to-share-code-between-serverless-functions/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.