Skip to content

remedialchaostheory/aws-node-rest-api-with-dynamodb

Repository files navigation

Serverless REST API with DynamoDB

aws logoserverless framework logopostman logo

Table of Contents

  1. Intro
  2. Improvements/Additions
  3. Setup and Usage
  4. API Testing
  5. Automating Deployment and Testing
  6. Testing and Debugging

Intro

AWS: Lambda, API Gateway, DynamoDB

Serverless Framework: Nodejs runtime, CloudFormation

Postman: API testing

REST API for a todo app. Built from scratch (and improved) using original project as a reference. The Serverless team created it to be a guide or proof of concept, so it was purposely bare bones. It's still incredible how they have so many different types of examples up for the framework (it's at least 30).

Improvements/Additions

  • Issue: the PUT method in update.js required both "text" and "checked" keys in request body

    • Resolution: split up endpoint from /todos/{id} to /todos/{id}/text and /todos/{id}/checked
  • Issue: Get requests for an invalid or nonexistent todo ID returned status 200.

    • Resolution: now returns 403 Forbidden to hide existence of a resource from unauthorized user.
  • Rather than forcing a certain "checked" state, I added an endpoint to toggle it /todos/{id}/tcheck

  • Refactored DynamoDB calls into a helper function to get the todo item's original data before being overwritten (for logging and potential history purposes)

Setup and Usage

Please refer to their original project. I changed a few of the endpoints, so I'll give you a complete list of them next.

API Calls

Note:
glh3x7xjak will be replaced with your own API Gateway ID. I left mine in for you to test it out.

Create todo item

POST request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos

Data:

{ "text": "<your todo>" }

List all todos

GET request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos

Data:

<none>

Get a todo

GET request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos/<id>

Data:

<none>

Update a todo's text

PUT request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos/<id>/text

Data:

{ "text": "<your new todo text>" }

Update a todo's "checked" (aka done) status

PUT request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos/<id>/check

Data:

{ "checked": true } or { "checked": false }

Toggle a todo's "checked" (aka done) status

PUT request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos/<id>/tcheck

Data:

<none>

Delete a todo

PUT request:

https://glh3x7xjak.execute-api.us-east-1.amazonaws.com/dev/todos/<id>

Data:

<none>

API Testing

The Postman test collection is located in api-tests.postman_collection.json

You can import the file into Postman's native app or run it via command line:

newman run api-tests.postman_collection.json

(this will run all tests)

One thing to note is that within a Postman test collection, there are folders that can contain requests. Within those requests are the tests.
E.g: Collection > Folder > Request > Test(s)

Each API call has its own JavaScript file in /todos. Test requests are grouped into folders according to that filename.
E.g: api-tests.postman_collection.json > create.js > Requests > Test(s)

To run a test for a specific API call/JavaScript file from the command line, enter:

newman run api-tests.postman_collection.json --folder <collection folder name>.js

For example:
If you wanted to run all the tests for create.js,

newman run api-tests.postman_collection.json --folder create.js

Note:
The collection folder—in this case, create.js—can be named anything. I just decided to keep it the same as the file name for clarity.

All tests can be run in isolation. Each has a pre-request script that are invoked to set up environment variables (e.g. id, text data, etc).

Automating Deployment and Testing

Tests will generate a random verb and random noun to send the body of the request for creating/updating todo items.

For example:
To test an update call to the API, it will send something like { "text": "navigate pixel" } or { "text": "synthesize monitor" }, which I thought was fun.

I included a simple bash script that will deploy a Lambda function (JavaScript file) and then run the associated tests.
./deploy-and-test-function.sh <javascript file> (do not include the .js extension)

For example:
If you made changes to create.js and wanted to deploy that Lambda function to AWS and immediately run tests: ./deploy-and-test-function.sh create
If you get a permissions error, type chmod 0755 deploy-and-test-function.sh to allow anyone to execute the script.

Only takes 1 positional argument (as of this writing). Either plan to use a for loop or flag arguments. I never needed to deploy and test more than one at a time so it wasn't needed.

Remember:
If you made any changes to the serverless.yml file, those changes won't be included when you use the deploy function method. You need to run a full sls deploy -v instead. Refer back to the original project for more info.

Testing and Debugging

A major issue for serverless apps has always been testing. Deploying the entire application during development is not ideal. Even if you're deploying a single lambda function, which is much faster, it still interrupts your workflow.

Of course, testing Lambda functions locally is ideal. Tooling for this is still currently in development, so here are a couple options:

  1. The Serverless Framework has sls invoke local --function <your function>. It merely emulates an AWS environment, so it's not exactly perfect. Probably suitable enough though.

  2. An alternative is to use the serverless-sam plugin. It will convert your serverless.yml template to a SAM template (CloudFormation template). With AWS SAM you can locally test and debug your app.

About

Serverless REST API with DynamoDB

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published