AWS Lambda Function URLs with Serverless Framework

Apr 6, 2022

AWS just released a brand new feature called "Lambda Function URLs", and we are happy to announce that Serverless Framework supports Lambda Function URLs immediately.

A Lambda Function URL is a simple solution to create HTTP endpoints with AWS Lambda. Function URLs are ideal for getting started with AWS Lambda, or for single-function applications like webhooks or APIs built with web frameworks.

While not a complete replacement for API Gateway, which provides more features, a Function URL is a simpler alternative with no extra cost and a much larger timeout limit. We will explore the pros and cons in detail in this article.

Using Lambda Function URLs with Serverless Framework can be done via a single statement:

functions:
  hello:
    handler: handler.hello
    url: true

To use that new feature, upgrade Serverless Framework (v3.12.0 or greater).

Lambda URLs in details

Function URL is a new feature of AWS Lambda that exposes a function as an HTTPS endpoint.

To deploy a function with a URL, use the url property in serverless.yml:

functions:
  hello:
    handler: handler.hello
    url: true

When running serverless deploy, the URL will be created and displayed in the terminal output. The URL will look like this:

https://yti4le2qudflx43hh.lambda-url.eu-south-1.on.aws/

That domain is unique to the Lambda function, and any URI path will invoke the function handler.

The request and response event payloads follow the same format as API Gateway's HTTP API "version 2" payload format. That means it is possible to switch from a Lambda Function URL to API Gateway's HTTP API without any code change.

Here is a simple NodeJS Lambda handler that responds to a Function URL:

exports.handler = async (event) => {
  return {
    statusCode: 200,
    body: 'Hello world!',
  };
};

Endpoint configuration

The endpoint is public by default. It can also be protected by IAM authentication:

functions:
  hello:
    handler: handler.hello
    # Public by default
    url: true
 
  world:
    handler: handler.hello
    # This URL is protected by IAM authentication
    url:
      authorizer: aws_iam

CORS can also be configured on the Function URL:

functions:
  hello:
    handler: handler.hello
    url:
      # Allow CORS for all requests from any origin
      cors: true
 
  world:
    handler: handler.hello
    url:
      # Configure CORS in details:
      cors:
        allowCredentials: …
        allowedHeaders: …
        allowedMethods: …
        allowedOrigins: …
        exposedResponseHeaders: …
        maxAge: ….

View the complete list of options for configuring CORS in the HTTP API event documentation.

Unlike API Gateway, Function URLs do not have a maximum execution time: the execution time is limited by the Lambda function's timeout (up to 15 minutes).

Note that Function URLs do not support custom domains. The solution would be to use CloudFront with the Function URL as the origin.

Function URLs vs. API Gateway

Lambda Function URLs let us create an HTTP endpoint for a Lambda function. Let's address the obvious question: how is that different from API Gateway?

Function URLs send all HTTP requests to one Lambda function. This pairs well with backend frameworks like Express or Apollo (Node), Flask (Python), etc. Indeed, these frameworks can handle HTTP routing, authentication, middlewares, and more. Function URLs also work great for single-purpose endpoints like webhooks.

While simple, the downside of this approach is that the whole API is contained in a single Lambda function: this is the "Mono-Lambda" pattern. The deployed package size could be big, debugging could be complex, and permissions are less granular than they could be. You can read more about that topic in The What, Why, and When of Mono-Lambda vs Single Function APIs.

API Gateway filters, processes, and routes requests to different Lambda functions. This removes the need for using backend frameworks. API Gateway can take care of transforming requests and responses, authenticating clients with different mechanisms, supporting custom domains, managing API access via API keys, and much more.

Note that the exact list of API Gateway features varies between v1 (REST API) and v2 (HTTP API): read Choosing between HTTP APIs and REST APIs to learn more.

While API Gateway provides more features, it also comes with added complexity and costs. Beyond the free tier, API Gateway v1 starts at $3.5/million requests and v2 at $1/million requests. Unlike API Gateway, Lambda Function URLs do not add any cost.

Regarding performance, one could expect Function URLs to add less latency than API Gateway. In practice, the difference is minimal. Here is the latency I measured with a quick test:

  • Function URL adds 9 to 10ms to the HTTP response time
  • API Gateway v2 adds 12 to 15ms to the HTTP response time

The latency mentioned above is added to the Lambda execution duration.

Let's compare all this in detail:

API Gateway REST API Gateway HTTP Function URL
Pricing Lambda + API Gateway$3.5/million requests Lambda + API Gateway$1/million requests Lambda only (no extra costs)
Authorizers IAM, Lambda, Cognito IAM, Lambda, Cognito, OAuth 2 IAM
Custom domain Yes Yes No (but possible with CloudFront)
API key management Yes No No
Caching Yes No No
Request transformation Yes No No
Request/response validation Yes No No
CORS Yes Yes Yes
CloudWatch access logs Yes Yes No
CloudWatch metrics Yes Yes Yes
Maximum HTTP response timeout 29s 29s 15 minutes

Use cases

Based on the comparison with API Gateway, we can conclude that Lambda Function URLs could be great for scenarios like:

  • APIs built with backend frameworks, like ExpressJS/Apollo/Flask…
  • Simple webhooks, where API Gateway could be overkill.
  • Server-side rendered websites, built with CloudFront + Lambda (skipping API Gateway).
  • APIs with a response time longer than 29 seconds (API Gateway's maximum timeout), for example to import or process data, or long-polling scenarios.

It's also worth keeping in mind that Lambda Function events are compatible between Function URLs and API Gateway's HTTP APIs. That means that Function URLs could be a great way to get started with HTTP on Lambda, and later upgrade to API Gateway to use its features.

Those are just ideas, we can't wait to see what you build with it! Check out the Serverless Framework documentation for Lambda Function URLs to get started.

Subscribe to our newsletter to get the latest product updates, tips, and best practices!

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.