2016-07-22



alvinashcraft
shared this story
from The New Stack.



Joe Emison

Bio: Joe Emison is Founder and Chief Technology Officer at BuildFax, the only provider of automated property condition information to the insurance and lending industries. Joe launched BuildFax on the cloud in 2008, and has consulted with many other companies on their own cloud launches and migrations. Joe oversees all technology and product management for BuildFax. Joe graduated with degrees in English and Mathematics from Williams College and has a law degree from Yale Law School. Find Joe on Twitter: @JoeEmison.

Serverless Computing is a software development process where application code is abstracted away from a server. Traditionally, developers have had to have at least some exposure and knowledge of their infrastructure to be able to develop software. Serverless Computing aims to allow the development of software without the headache of standing up and managing servers.

Two distinct serverless architecture patterns are emerging: “functions-as-a-service” and “servicefull” architectures. The former is a more direct application of “throw code up to a service that will run it” and the latter is the use of cloud-based services to build applications (e.g., Algolia, Cloudinary, Twilio) instead of writing code / running libraries on your hardware.

For the purpose of this post, I will focus on my thoughts on the former serverless architecture pattern, functions-as-a-service (FaaS).  Two platforms that I think do FaaS justice are Auth0 Webtask and AWS Lambda. Each has a different approach.

Webtask was built by Auth0 to allow developers to build easily serverless applications and programmable webhooks that fire after a certain event in your application occurs. The Webtask platform integrates Auth0’s authorization and authentication platform as well as numerous other features allowing Webtask to become a complete serverless platform, all accessible through HTTP calls. Webtasks are written in Node.js and created via the Webtask CLI.

Lambda comes out of AWS with the same goal in mind. “Run code in response to events” is the tagline for Lambda. Lambda is deeply integrated into the AWS ecosystem, for better or worse, and can execute code across many different languages including Java, Python and Node.js. Lambda can be seen more as a back-end processing platform rather than a pure serverless platform. Lambda favors configuration over code, requiring the integration of various AWS products to work properly.

A Case for Serverless Computing

If you’ve ever used a third party API in your application, say implemented Algolia for search or Cloudinary to manage image uploads, you’ve essentially used serverless computing. This example may be reaching, but to put it in perspective, implementing a third party API does not require knowledge of their infrastructure, servers, and so on – you just need to know how to access the resources a server provides.

For our use case, let’s assume we’re building an application that does not require a backend. We could be building an app with Firebase, the real-time database from Google, which allows us to build scalable apps that run entirely client-side. So we have our Firebase app built, but want to use the WalkScore API to allow our users to see the “walkability” score of popular areas. WalkScore requires us to register for an account and get an API key. These credentials, we wouldn’t want anyone to have access to except us.

Lambda functions work a bit differently than Webtasks. Lambda requires a bit more configuration to get up and running.

We could go and build an entire backend for our app. Configure servers, build a deployment pipeline, and all the other fun things that go into setting up a backend. Or we could leverage a serverless computing provider, write code to interface with the WalkScore API, and access that code in our client-side app instead. The serverless option seems a lot more attractive. Let’s see how we can implement this in Webtask and Lambda and compare the two.

Webtask Implementation

Webtask leverages the Node ecosystem heavily. To get started with Webtask, you’ll need to install the wt-cli command line tool via npm. Once you have Node and npm installed, run the `npm install wt-cli -g` command to install Webtask CLI globally on your machine.

With the CLI installed, run the `wt init {email}` command to authenticate yourself. You can use either an email address or your phone number when signing up for a Webtask account. You will receive an email or text message with a code which you will input to confirm your identity. Once that is taken care of you are ready to create a Webtask.

Creating a Webtask is done by running the `wt create {name}.js` command where the `name` is the name of your Webtask. Webtasks can currently only be written in Node.js. A Webtask is a Node.js module that exports a single function. Let’s look at our WalkScore integration below

We’ll save this file and call it walkscore.js. Run the command `wt create walkscore.js` to create the Webtask. You will receive a link in the form of `https://webtask.it.auth0.com/api/run/{your-email}/{webtask-name}`. Navigate to this link and add a city parameter link `?city=1` and you will see the expected result.

Our Webtask is built. Our API key is securely hidden and in our client-side application, we can call this API to get the data safely.

Next, we’ll look at how to do the same with Lambda.

Lambda Implementation

Lambda requires a bit more configuration to get up and running. You will need an AWS account to access the Lambda service.

Lambda functions work a bit differently than Webtasks. We will use much of the same code as in the Webtask implementation, but will have to tackle the problem a bit differently. We’ll have to build our entire application locally, zip it up and upload it in the AWS console. Like many AWS services, Lambda functions can be created with the AWS CLI, but we’ll stick to the to the AWS console as we’ll be using the console extensively to get our serverless Lambda app up and running.

As our code is not overly complex, we can get away with simply installing the `request` module locally by running `npm install request` in the directory where our walkscore.js file is. This will create a new folder called `node_modules` which will contain the request module and any other modules required. We’ll need to update the walkscore.js code slightly to ensure we match what the process that executes our Lambda function expects. Take a look at the code changes below:

Finally, select the walkscore.js file and the node_modules directory and zip them up into a single file called ‘walkscore.zip`. This is the file we will upload as our Lambda function.

When we created our Webtask, we were automatically given an HTTP endpoint where we could access the Webtask. With Lambda, once we have created our Lambda function, we have the option to hook into an existing AWS service or we can use the AWS API Gateway service to get an HTTP endpoint to access our code. We’ll use the API Gateway and create a new GET endpoint.

API Gateway is a fairly complex service that requires a lot of configuration out of the box. We will create a new API Endpoint. In your AWS Console, under the Lambda function you just created, navigate to API Endpoint and then click the Add New Endpoint link. You can name your endpoint whatever you want. Set the Method of the Endpoint to GET and make sure to select Open for Security. We will not be adding authentication for this simple demo. Once the endpoint is created, cClick on it and you will be taken to the API Gateway service part of the AWS Console.

By default, API Gateway does not allow any query parameters or data to pass through, so we will manually need to configure this. Navigate to the API endpoint you created and first we will need to select the Method Request option and add the query parameter that we would like to enable. In our case, we’ll just add one query parameter called city. Next, navigate to the Integration Request section and here we will need to add a Body Mapping that will allow us to map that query parameter to a data variable which we can access in our Lambda code.

There are numerous ways to approach this problem, but to keep it minimalistic, add a Content Type of application/json and in the settings paste the following code:

This will store the value of the city parameter in a variable named querystring. If you look at our integration code for Lambda, you can see we get this data from the event variable that is passed to our handler: `var city = event.querystring;`.

With all this in place, deploy the endpoint in the API Gateway section and navigate to the newly created endpoint. Try passing the different query parameters to make sure it works properly. You have now created a simple serverless app in Lambda.

Webtask vs. Lambda In-Depth

So far, we’ve looked at how you can write serverless apps with Webtask and Lambda. In the isolated scenario, the two platforms are fairly similar. Lambda requires a significant amount of configuration across various products to get up and running while our Webtask was deployed with one simple command. Let’s compare their ecosystem to better understand the two platforms.

Authentication: Auth0 vs. IAM and Cognito

Authentication is a large component of any application. Serverless apps are no exception. Webtask was built by Auth0, so naturally, they provide authentication options through their main product,  Auth0.

Auth0 provides much more than just authentication and authorization. Multifactor authentication, passwordless, an easy to use authentication widget called Lock and much more allows you to develop highly secure Webtasks. Auth0 integration is tightly integrated into Webtask. The `webtask-tools` node module provides helper function to integrate Auth0 authentication and authorization easily with your serverless project. I won’t go deeply into the different options, but if you are considering Webtask, you can learn about them here.

Amazon, on the other hand, supports authentication through their Identity & Access Management (IAM) and Cognito services. When creating a new Lambda function, you must first assign an IAM role to it. IAM roles determine the types of privileges a user account will have. Then, you must create a Cognito User Pool and configure it. Cognito is the service that provides the API to handle user authentication. Finally, you would integrate the Cognito library in your application which would handle the authorization and authentication.

The AWS approach requires a lot more configuration compared to Webtasks Auth0 integration. The IAM and Cognito services are part of the larger AWS ecosystem and can sometimes feel tacked on to Lambda. The differences in documentation between the two are also pretty staggering. The Auth0 documentation provides a clear path on how to get setup while IAM and Cognito requires a lot of tinkering and experimentation to get right.

Access: Standard HTTP vs. API Gateway

Webtasks take a protocol-centric approach to serverless, with HTTP being the primary way in which your code is exposed to the outside world. When you run the `wt create {webtask}.js` command to create a new Webtask you will get a URL to access that Webtask. You can use any standard HTTP verb such as GET, POST or PUT to interact with that Webtask and can programmatically edit the behavior based on the request.

A Lambda function, on the other hand, needs to be exposed via the API Gateway to be accessible via HTTP. API Gateway has traditionally been clunky to work with. As we saw in the integration of the Lambda function above, API Gateway offers a narrower view of the HTTP protocol and gets bogged down by the amount of configuration options. As Lambda is deeply integrated into AWS, it does have the added benefit of allowing Lambda functions to be called within your AWS ecosystem without the need for API Gateway. For example, with the Cognito service, you can set up different Lambda functions to fire when a user signs up, logs in, or have Lambda functions invoked when a user uploads a new file to S3 and so on.

Ecosystem: Integration and Extensibility

Webtasks are written as Node.js modules, so naturally, you’re writing JavaScript. If you wanted to, you could additionally write C# code with the edge.js module for your Webtask. Lambda, on the other hand, supports Node.js, Python and Java. Webtask aims to allow you to write code and not worry about importing and managing modules. They support over 800 modules natively so you could just require the module and your code will run. If the module you need is not supported, you could manually create a bundle yourself. Learn how to do that here with the `wt create –bundle` command. With Lambda, you are free to use any module you wish, but you have to compile your program locally and then upload it to AWS.

Webtasks can be created locally or from a remote resource using the Webtask CLI. Lambda functions can also be created locally via a CLI, uploaded as a .zip file if multiple files are required, such as in the case where you are using different node modules, and can also be accessed if uploaded to Amazon’s S3 service.

Both platforms support numerous ways to run code. Webtask supports direct access over via HTTP requests, but can also be set up to run periodically as Cron jobs. Lambda functions can be called similarly over HTTP, but have a deep integration into the AWS ecosystem and can be activated based on many different events that AWS services provide.

Conclusion

Webtask is a complete product.  Lambda is not a complete anything. It’s part of a back-end framework and integrates well with AWS RDS and DynamoDB. If you are looking to build a serverless app, whether it’d be an entire app or a micro-service, Webtask simply has a better developer experience, with little downside unless you’re using other AWS services as part of the application. Lambda has its place in augmenting the AWS ecosystem but is overly complicated, requires too many other services, and too much configuration compared to Webtask to be a good default choice for most serverless applications.

Ado Kukic, who works for Auth0 (which makes Webtask), assisted in this article.

Feature image by Maico Amorin via Unsplash.

Show more