top of page
Search

Serverless Architecture at Tenera


At Tenera, our mission is to develop applications that not only meet our users' needs but also stand on a platform that is efficient, scalable, and rapidly adaptable. In the fast-paced tech landscape, it is important to be able to quickly roll out new features to customers. Equally critical is ensuring that applications are highly stable and reliable. These two qualities rarely go hand-in-hand in software development, but with serverless architecture a team can rapidly iterate while keeping the risk factor compartmentalized to individual functions. Leveraging the power of AWS Amplify, we've already streamlined the process of generating data models and AppSync APIs, which seamlessly integrates with AWS Lambdas generated through Amplify. This combination allows us to embrace the benefits of serverless computing, such as cost efficiency, scalability, and reduced operational overhead, ensuring that our applications remain cutting-edge, responsive, and, above all, user centric.

 

What is Amplify? 

Amazon Web Services (AWS) Amplify is a comprehensive set of tools and services designed for developers looking to build scalable, full-stack applications rapidly. It simplifies complex tasks, such as authentication, API creation, and data storage. Amplify has allowed our team to accelerate development cycles and focus on crafting great user experiences rather than getting bogged down writing boilerplate code for cloud infrastructure. By abstracting away much of the backend complexity, AWS Amplify empowers our developers to quickly learn and integrate with many AWS Technologies, bringing those sought-after features directly to our customers. The key feature of Amplify we would like to focus on today, is Amplify Datastore.

  

What are Lambda Functions?

AWS Lambda functions are autonomous pieces of code that execute in response to specific 'trigger' events, offering a streamlined approach to running backend services without the need to manage servers. Aside from explicit client requests, lambdas can be configured to trigger in response to database interactions, event queues with SQS, and even authorization workflows.

 

These "functions" automatically scale from a few requests to thousands per second, ensuring high availability and performance while significantly reducing operational costs. The service abstracts away the complexity of infrastructure management and optimizes costs by charging only for the compute time used, making it perfect for a rapidly growing system.


At Tenera

At Tenera, our flagship application, Tenera Inspections, is designed with an 'offline-first' philosophy. This approach ensures that a significant portion of our business logic is executed on the client side, allowing users to perform critical tasks without the need for constant internet connectivity.

 

However, certain workflows require a higher level of validation and security that cannot be effectively managed on the frontend alone. For instance, the client cannot be completely trusted to validate user permissions, as local permission records could theoretically be altered by a bad actor. To address this and other similar requirements, we use Lambda Functions to validate sensitive interactions in the cloud to maintain data integrity and security. In addition to this, we use Lambdas to reactively process uploaded resources, handling tasks ranging from data validation and image post-processing to more complex operations like AI analysis.

 

This serverless architecture shines especially when a user reconnects to the internet after a prolonged offline period.  Out of necessity, the client generates a surge of requests as the application synchronizes, causing a traffic spike that could be hard to efficiently manage with traditional servers. Since Tenera uses Lambdas Functions, these spikes are managed by AWS dynamically scaling to meet demand, then scaling down once the synchronization is complete.

 

Moreover, the isolated nature of Lambda functions means that in the rare event of a failure, the impact is contained. The user experiencing the issue may encounter minimal disruption, but the system's overall integrity remains intact, with no adverse effects on other users. This resilience is a testament to the robustness of the serverless model, ensuring that Tenera Inspections remains reliable, secure, and user-friendly, regardless of the connectivity landscape.

 

Creating an implicitly triggered Lambda Function

In this section, we will show you how to quickly set up a lambda function that triggers in response to a new record being created in DynamoDB. This section will assume that you have an amplify project ready to go. If not, refer to Amplify's own documentation here. We also assume you've set up at least one model in your schema, as in our example:

 

type Inspection @model {

  id: ID!

  title: String!

  description: String

}

 

Creating the function

Firstly, you'll want to run "amplify add function" using amplify CLI, this will guide you in the process of creating a new function. Select the an appropriate name and the runtime of your choosing. You can select a template that suits your need, in our case that will be "Lambda Trigger", which comes pre-configured to trigger in response to a resource being created. For this tutorial, select the Inspection model that we've already created and pushed to the cloud.



If you want to configure that from scratch rather than template, you can create a 'hello world' function, and configure the trigger separately using 'amplify update function'

 

The event handler

Once complete, amplify should create a function for you under the amplify/backend/function/<functionName> directory. Here you can see the function code under the src/ directory, as well as CloudFormation configuration generated by amplify which defines, among other things, the lambdas trigger and access permissions in the system. For our purposes, we can leave these unchanged.

 

Open the src/index.js and you should see something like this:

 


This default handler will simply print out the records received in the event, which will represent the record which triggered the lambda. From here we can customize our lambda to do any number of things, from validation to post processing, but for this tutorial we will leave the default implementation as is and expand on it in future blog posts.

 

Triggering the lambda

Next up, we want to push this lambda function to the cloud. Via amplify CLI this is done with the command "amplify push". This will push any schema changes as well as new and updated lambda functions and should take a few minutes to complete.

 

Once complete, you can verify the lambda was created in the AWS lambda console, for example if your lambda is named onResourceIngress, amplify should have created onResourceIngress-<envName> for you:



Next up, we want to test the trigger by creating an inspection. This can be done either via Datastore as explained in the previous blog post, or directly via AppSync in the Amplify console.

 

Validating execution

Once done, you can click into the monitoring tab of your lambda to see that it is triggered in the CloudWatch metrics, or go directly to the CloudWatch logs to see the direct output of the lambda:



And there you have it, now you can begin adding more advanced business logic to your lambdas, all without the need of a dedicated server instance. From here we can add more and more advanced features and workflows, all while keeping costs low and availability high.

 

As always, if you want to learn more about Tenera's journey and continued success stories, make sure to follow us on LinkedIn. If you're interested in difficult tech problems like this one, make sure to visit our careers page to see open roles.

 




bottom of page