AWS SAM vs. Nitric

AWS Serverless Application Model (SAM) is an abstraction layer for CloudFormation that makes it simpler to write serverless applications in AWS.

Although both AWS SAM and Nitric are in the same problem space, there are major differences in the way that Nitric solves simplifying serverless application development compared with SAM.

TLDR

The major differences with SAM are:

  • Only supports AWS.
  • Configuration is defined in lengthy yaml files.
  • Only supports functions, apis, and tables.
  • IAM implementation is the responsibility of the developer.

Building

To build with AWS SAM you need a template yaml, an OpenAPI spec yaml, as well as the actual lambda code.

Here is the example OpenAPI spec AWS uses to demonstrate the simplicity of SAM. That file is over 200 lines long.

Nitric does the spec in 0 lines.

Any Nitric config you write is done as code, keeping the architecture of your application in one place, rather than three.

const newApi = api('test-api')

newApi.get('/hello', (ctx) => {
  return ctx.text('Hello World')
})

Building resources other than lambdas, apis, or tables requires separate CloudFormation extensions to your SAM template files.

Nitric has first-class support for these other resources, and its only one extra line.

const newBucket = bucket('test-bucket')

IAM Policy

SAM's least-privilege permissions are written explicitly in the template configuration. The responsibility (and burden) is on the developer to make sure the lambda policies chosen follow security best practices.

This is done through more yaml configuration, which points to an AWS policy.

---
Resources:
  MyFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://my-bucket/function.zip'
      Policies:
        - SQSPollerPolicy:
            QueueName: !GetAtt MyQueue.QueueName

On the other hand, Nitric handles the implementation of least-privilege policies for you. All that is needed is to specify how you want to use a resource, and the function will be assigned the relevant policy.

const newBucket = bucket('tester').for('reading', 'writing', 'deleting')

Testing

Both the SAM and Nitric frameworks have local testing environments that closely resemble the cloud environment. This means testing that your functions work is as simple as making a request to the local endpoint.

The difference comes when writing automated unit or integration tests.

AWS SAMNitric
UnitAWS SDKBYO
IntegrationAWS SDKBYO
MockingAWS SDKBYO

AWS SAM can't configure all the resources, so when you use the local test environment none of the external resources are going to be mocked. This means for a decent integration testing experience, you have to use the AWS SDK or CLI, which attempts to solve this problem.

Nitric's testing works with any testing framework, as resource creation and calling can be mocked. When running the local test environment, other resources like buckets are created using the file system. This makes the integration testing super smooth, as the files you create and events you push are actually there.

Deploying

The deployment experience between the frameworks is very similar, where a single command will deploy the entire stack. The big difference however, is that AWS SAM only deploys to AWS, while Nitric will deploy to AWS, GCP, or Azure.