Function-based design
In serverless architectures, the primary unit of deployment and execution is the function. This function-based design paradigm offers a high degree of modularity, allowing developers to break down complex applications into smaller, more manageable pieces. This approach contrasts with traditional monolithic or even non-serverless microservices architectures, where the unit of deployment is often much larger. Each function is designed to perform a specific task and can be invoked independently, making it easier to develop, test, and deploy individual components. This approach also facilitates code reuse, as functions can be shared across different services or even different applications. This leads us to consider two key aspects of function-based design: granularity in function composition and state management.
Granularity and function composition
Granularity refers to the size and scope of a function in terms of its responsibilities and the resources it consumes. In serverless, the aim is often to make functions as granular as possible, focusing each on a specific task or operation. This granularity allows for more efficient scaling and better resource utilization.
Function composition involves combining multiple granular functions to perform more complex tasks. This can be done sequentially or in parallel, depending on the application’s needs. For example, one function could handle user authentication, another could retrieve data from a database, and a third could perform some form of data transformation. When composed together, these functions could provide a complete end-to-end service.
Stateless versus stateful functions
Serverless functions are stateless, meaning they do not maintain any internal state between invocations. Each function invocation is independent, and any required state must be passed in as input parameters or managed externally. Stateless functions are easier to scale and manage as they can be freely instantiated and terminated without affecting other instances.
However, there are scenarios where stateful behavior is required, such as multi-step workflows or long-running transactions. In such cases, a state can be managed using external data stores such as Amazon DynamoDB or Amazon S3, or through orchestration with AWS Step Functions, which allows Lambda functions to pass data between each other via the state machine definition. It is worth noting that using external data stores for stateful behavior introduces security considerations, such as the need for secure data storage and transmission.