This post is part 2 of a 3 part series.
- Serverless Patterns and Best Practices for AWS - Part 1 Design
- Serverless Patterns and Best Practices for AWS - Part 2 Build (this)
- Serverless Patterns and Best Practices for AWS - Part 3 Operate (stay tuned)
In our previous blog we discussed some of the design considerations for serverless functions. Now that you have spent enough time thinking about your function and how they are going to be deployed, you now need to think about how to build these functions, so let's jump into it.
What language/frameworks should you use?
We like to use NodeJs or Python for our Lambda functions as they have the least code start among the other languages. We tend to use NodeJs for APIs and Python for data and general-purpose functions. Python has very strong data related libraries like Pandas and math libraries like NumPy that are very helpful in data related transformations.
One of the important decisions you need to make is the serverless framework to use. Choosing the right framework will simplify your development and deployment life cycle later on. While AWS provides its own framework we do prefer using the serverless framework for the following reasons:
- One of the more mature frameworks
- Simple, flexible configuration file to describe your service
- Supports both Lambda and step functions
- Newer versions give you monitoring and function dashboards
- Large community with many available plugins
- Easy to extend by writing your own plugin
- Its name 😊
The serverless framework has the ability to also create resources for you, however, avoid doing this unless it is specific to your function - as in IAM roles for your functions. Other resources like DynamoDB tables etc. are better to be created outside of the serverless framework.
What should I name my function?
There is no correct answer, unless you name your function "function1", you’ll probably be fine. The following naming convention worked for us and helped to easily identify a function by its name:
- kebab-case for function names as it is easy to read
- You can use the following convention:
Name of your project
Deployment environment, ex: DEV, UAT, NONPROD
A classification of your function and its purpose. Examples:
The logical component that this function sits within, use "common" if it is a general purpose one
A descriptive name of your function
How to structure my projects?
Some frameworks generate a project structure for you and depending on your language of choice your repo structure may differ. Regardless of that, you need to think about a structure that makes sense to your team and makes it easier to maintain the code.
Here is an example:
How can I unit test my Lambda?
Serverless does not really follow the traditional test pyramid. In the serverless world the emphasis is less on unit testing and more on the system testing or integration testing since your function is just a small cog in a bigger machine. However, your code should always have proper unit tests. The challenge is how would you test your serverless function that is heavily dependent on cloud provider services? Here are some pointers that should make it easier to unit test FaaS:
- Write your codes in chunks: The best way to unit test your code is to write it with unit testing in mind. Try to keep your code in the main handler method to a minimum, only routing and calling other functions. This way you can test the other functions in isolation.
- Run local: Serverless framework provides a capability to run your function locally without needing to deploy it. Your code lives in your local machine while it emulates the AWS Lambda function environment for you. It is very helpful to have your data sample ready before you start coding.
- Mock your services: You still need to be able to write unit tests that can run in you CI/CD build server, so you have to rely on mocking all the other external services you integrate with in your code. Libraries like aws-sdk-mock and moto together with examples for events from the official AWS documentation will help you mock your AWS services.
- Isolate your FaaS: Try to encapsulate all the external calls and references into their own methods and isolate it from your code, this way you can mock the FaaS services much easier as described in these examples.
In this blog we have covered some of the decisions that you have to make while building your serverless applications. In the next one we will talk more on the deployment and monitoring aspects of the serverless landscape, so please stay tuned!