Development / Serverless / Sponsored

Tips for Writing Lambda Functions in Node 8

16 Aug 2018 6:00am, by

Nuatu Tseggai
Nuatu Tseggai is the director of solutions engineering at Stackery. He is an expert in solutions architecture, site reliability engineering and finding the balance between executing sustainable high-impact projects and shipping things quickly. Prior to joining Stackery, Tseggai has held high-level software and systems engineering roles for a number of firms, including Radware, Lockheed Martin, New Relic and ManTech. He has also served as a systems specialist with the United States Air Force and earned a B.A. in information Systems and technology management at the St. Petersburg College.

Stackery is a sponsor of The New Stack.

Serverless is becoming a very popular solution for standing up web services lately due to the speed at which new services can be created. But if you’re a Node.js developer, there are a few things you should know before you dive in.

Here are a few things to keep in mind to save yourself a lot of frustration and to get the best use out of Lambdas you write.

  1. Lambdas don’t have URLs, they have triggers

This is a basic part of the serverless metaphor that distinguishes it from any kind of server or microservice. I found it difficult to grasp at first: After writing a very basic Lambda that returned an object, such as {message:‘hello world!’}, I would deploy it on Amazon Web Services (AWS) and then try to figure out where I could ping my Lambda at some public URL.

But the rub is that if all you’ve done is deploy a Lambda, then it’s not publicly addressable at all.

Creating a Lambda by the default path on AWS should prompt you to create some triggers for that Lambda.:

  • An API endpoint — if you create one of these and hook it up to your Lambda, then your Lambda will have a URL;
  • S3 events (like a file upload);
  • SNS messages;
  • Any of the other many events AWS resources can generate, enumerated in the AWS documentation.

If you want to “run” your Lambda code without having to stand up any other resources, you can send it a test event from the Lambda dashboard.

  1. To include a module, use the “require()” function just as you would in regular Node

The initial interface for writing Lambdas is dead simple, consisting of just a text box that is maybe five lines high, with a basic wrapper. When first using Lambdas that was what stuck with me: Lambdas are a few lines of javascript run on their own. When I had to parse HTML or do other tricky stuff I switched to a microservice. “Serverless” seemed synonymous with, “no outside requirements.”

The reality is that you can use libraries both big or small — while it’s not immediately obvious how if you’re working in the web interface.

If you point your Lambda to a GitHub repository or use Stackery to manage your Lambdas, you can work with your full Lambda code locally. Once you pull down the source code for your stack, you’ll see that the index.js file is in a folder surrounded by everything you need for a tiny Node app. This includes a package.json which currently only has a dependency for the AWS SDK.

Just like any other Node.js app, you can add packages here and then require them inside your Lambda. You can also require local files adjacent to your index.js file.

  1. Lambdas are triggered with lots of information

When trying to make sure your Lambda has enough context, take the time to add in “console.log(event)” to look at all the parameters that came into your Lambda. If you need to know things like the time you were called, the source, or (with an API gateway), the details of the HTTP request; you’re in luck because those are all in there by default — no need to add parameters.

Now, I have to make a confession: The test events mentioned in my first point are a little deceptive. They only include the data you set in addition to just three default parameters while the event object sent from an API endpoint has over 100 parameters.

  1. Async/await functions aren’t that complicated!

When Ryan Dahl was creating Node.js, he selected Javascript because it could describe asynchrony easily. Ironically, nearly 10 years later, we’re still debating the best way to write asynchronous functions. Async/await is definitely a big step in the right direction — especially since it looks and feels more like synchronous code.

A few tips:

  • My default linter had trouble with async function (params){} format and absolutely refused to parse async (params)=>{} but they both run just fine. So it is essential to make sure your plugins are up to date.
  • await someFunction() only works correctly if someFunction() returns a promise. But here’s the maddening part: it doesn’t break if the return value is a simple value. This means it can lead to code that kind of seems to work but then breaks eventually.
  • If you need to await a function that doesn’t return a promise, just wrap it in a promise.

Lambdas remain a great way to go from an idea to a working service in just an afternoon. After you’ve mastered writing your first few Lambda functions, AWS offers some great tools for monitoring performance and health. If you are serious about building advanced serverless applications that scale with your engineering team, I highly recommend trying out Stackery. To ensure long-term success building microservices with Node.js, be sure to keep up with the best practices and language features that emerge over time.

Feature image via Pixabay.

A newsletter digest of the week’s most important stories & analyses.