A simple AWS-based, serverless note-taking app
The fundamental components of the application are the API Gateway, the Lambda functions, the DynamoDB table, & Cognito.
The API Gateway exposes the API endpoints, & specifies the Cognito UserPool as the authorizor for some of these endpoints. The lambda functions receive the requests from the API endpoints, & interact with the Dynamo DB table to get, add, update, or delete notes. The Dynamo DB table houses all of the notes. Cognito has several interlocking components:
- NotesUserPool is the source of users allowed to interact with the API
- NotesUserPoolClient specifies the way the API may interact with these users
- NotesUserPoolResourceServer defines the Oauth scopes available for use
- NotesUserPoolDomain specifies the Oauth domain at which the Cognito hosted UI lives at
The application leverages the AWS SAM CLI to build & deploy the appropriate AWS resources & roles. To use the AWS SAM CLI, follow these steps: Install the AWS SAM CLI.
Once properly installed & configured with appropriate AWS credentials, you can build the application with
sam build
. This will parse the contents of the AWS SAM template file (template.yam) & generate a build suitable for deployment to AWS.
In order to then deploy this build to AWS, run
sam deploy
, which will deploy using the values defined in (samconfig.toml). Optionally you may run sam deploy --guided
to manually specify deployment options.
After deploying, the output will point you in the direction of your API root path, at which point you can navigate there & begin fiddling.
The API specifies the following endpoints:
- GET /
- retrieves all Notes
- GET /{noteId}
- retrieves the Note with noteId
- returns nothing if not found
- POST /
- requires a JSON body with the following attributes defined
- name: content of the note
- creates a new note with note contents of the body name
- requires a JSON body with the following attributes defined
- PUT /{noteId}
- requires a JSON body with the following attributes defined
- name: note contents
- modifies the Note with the provided ID so that its note contents become the body name
- does nothing if noteId not found
- requires a JSON body with the following attributes defined
- DELETE /{noteId}
- deletes the Note with noteId
- does nothing if noteId not found
The GET endpoints are unauthenticated. The POST, PUT, & DELETE endpoints all expect an OAUTH2 bearer token. This can be done via Postman following the instructions here: Postman - Requesting an OAuth 2.0 Token
- Grant type: Authorization Code
- Callback URL remains default (for browser testing)
- Auth URL: https://notes-authority.auth.us-east-1.amazoncognito.com/login
- Access Token URL: https://notes-authority.auth.us-east-1.amazoncognito.com/oauth2/token
- Client ID: This will be generated by your cloud build, & can be found within the AWS console at Amazon Cognito -> User Pools -> notes-app-NotesUserpool -> App Integration tab -> App Client List, under Client ID
- Client Secret: leave blank
- Scope: openid
- Client authentication: Send credentials in body
- Sending as basic auth header may work, but for me was resulting in 400 errors With all of this properly input, hit 'Get New Access Token'. This should prompt the browser to take you to the notes-authority domain, where the standard Cognito authorization workflow should help you get an account set up & signed in. Finally, once logged in, a token will be generated, & you can then use this in your requests as the authorization. Use the 'Access Token' token type, with Header Prefix 'Bearer'.
Without a valid token generated through the above process, the POST, PUT, & DELETE endpoints will respond with a 401 Unauthorized when requested.