Serverless Reference Architecture: Mobile Backend
The Mobile Backend reference architecture (diagram) demonstrates how to use AWS Lambda along with other services to build a serverless backend for a mobile application. The specific example application provided in this repository enables users to upload photos and notes using Amazon Simple Storage Service (Amazon S3) and Amazon API Gateway respectively. The notes are stored in Amazon DynamoDB, and are processed asynchronously using DynamoDB streams and a Lambda function to add them to an Amazon CloudSearch domain. In addition to the source code for the Lambda functions, this repository also contains a prototype iOS application that provides examples for how to use the AWS Mobile SDK for iOS to interface with the backend resources defined in the architecture.
Running the example
To run the full example application, you must first deploy the backend resources, and then compile and run the example iOS application.
Deploying the Backend
The provided AWS CloudFormation template creates most of the backend resources that you need for this example, but you still need to create the Amazon CloudSearch domain, API Gateway REST API, and Cognito identity pool outside of AWS CloudFormation.
Step 1: Create a CloudSearch Domain
Using the AWS CLI, create a new CloudSearch domain providing a domain name of your choice.
aws cloudsearch create-domain --domain-name [YOUR_DOMAIN_NAME]
Note the ARN of the new domain in the output document. You will use this as an input when launching the CloudFormation stack.
Define indexes for the
aws cloudsearch define-index-field --name headline --type text --domain-name [YOUR_DOMAIN_NAME] aws cloudsearch define-index-field --name note_text --type text --domain-name [YOUR_DOMAIN_NAME]
Note: You will need to reindex your Domain via CLI or Console. Here is the CLI command:
aws cloudsearch index-documents --domain-name [YOUR_DOMAIN_NAME]
Step 2: Create an API Gateway REST API
Using the AWS CLI, create a new API providing a name of your choice.
aws apigateway create-rest-api --name [YOUR_API_NAME]
API IDprovided in the output document. You will use this as an input when launching the CloudFormation stack.
Step 3: Create an Amazon Cognito Identity Pool
Using the AWS CLI, create a new identity pool providing a name of your choice.
aws cognito-identity create-identity-pool --allow-unauthenticated-identities --identity-pool-name [YOUR_POOL_NAME]
IdentityPoolIdfrom the output document. You will use this as a parameter when launching the CloudFormation stack.
Step 4: Launch the CloudFormation Template
You can deploy the entire example in the us-east-1 region using the provided CloudFormation template and S3 bucket by Launching the stack below.
If you would like to deploy the template to a different region, you must create an Amazon S3 bucket in that region, then in the file
lambda-functions/upload, modify the BUCKET variable with the bucket you created, run
./upload, and copy config-helper.template and mobile-backend.template into the bucket.
Choose Launch Stack to launch the template in the us-east-1 region in your account:
When prompted, enter the parameter values for the CloudSearch domain, CloudSearch Search/Document Endpoints, API Gateway REST API ID, and Amazon Cognito identity pool resources you created in the previous steps.
Details about the resources created by this template are provided in the CloudFormation Template Resources section of this document.
Step 5: Update Your API Gateway REST API
After you have created the CloudFormation stack, you need to update the API you created previously to use the newly created
- In the Amazon API Gateway Console, choose your API.
- Choose Create Resource to create a new child resource under /.
notesas the resource name and
/notesas the resource path.
- Choose Create Resource.
- With the new
/notesresource selected, choose Create Method.
POSTand select the check box.
- Choose Lambda Function as the integration type and then choose the region where you launched the CloudFormation stack as the Lambda region.
- in Lambda Function, type
NotesApiFunctionand then select the function created by the CloudFormation Stack.
- Choose Save and grant API Gateway permissions to execute the Lambda function.
- Choose Method Request to edit the request configuration.
- For Authorization type, select
- For API Key Required, select
- Select the Actions dropdown, Choose Deploy API.
- For Deployment stage, choose
New Stageand then type a name in Stage name.
- Note the Invoke URL for the new stage. You will use this value when running the sample iOS app.
Step 6: Create an API Key
- In the Amazon API Gateway Console, choose API Keys.
- Choose Create API Key.
- Type a name for the key and then select Save.
- Note the API key. You will use this when running the mobile application.
- Click on Usage Plans and type a name for the plan. Disable Throttling and Quotas. Click Next.
- From the dropdowns, seleect your API and Stage created in Step 4. Click the Checkbox and then Next.
- Click Add API Key to Usage Plan and enter the Key you created earlier then choose Done.
Step 7: Update Your Amazon Cognito Identity Pool
- In the Amazon Cognito Console, select your identity pool.
- Choose Edit Identity Pool.
- For both the Unauthenticated role and the Authenticated role, select the MobileClientRole created by the CloudFormation stack. The full ARN for the role is provided in the outputs of the stack.
- Choose Save Changes.
Running the Sample iOS Application
Building and Running the Application
Check out or download the source code for the ios-sample in this repository.
MobileBackendIOS/Constants.swiftwith the values for your backend deployment. Most of the values can be found in the outputs of the CloudFormation stack. The API Gateway key and endpoint URL values are available in the details for your API in the AWS Management Console.
Run Cocoa Pods from the root
Open the generated
MobileBackendIOS.xcworkspacefile in Xcode.
open -a Xcode MobileBackendIOS.xcworkspace
Build and run the project from Xcode by clicking the play button at the top of the window.
Testing the Application
The sample application provides two features: uploading an image and posting a note.
To upload an image
- Choose Upload Image in the application.
- Choose the camera icon, select an image from the camera roll, and then choose Choose.
- Choose the Upload button.
Validating that the image was uploaded
You should see a log entry that the image has been uploaded to Amazon S3 in the output pane of Xcode.
You can also browse the bucket created by the CloudFormation stack using the AWS Management Console to verify that the image was correctly uploaded.
To post a note
- Choose Post a Note.
- In the note, type a headline and text.
- Choose Save Note.
Validating that the note was posted
You should see a log entry that the note was saved successfully in the output pane of Xcode.
When the note is uploaded, the
NotesApiFunction is invoked by the mobile application. You can view the logs for this function in Amazon CloudWatch.
When the function is successfully invoked, it adds an entry to the DynamoDB table created in the CloudFormation stack. You can verify that the note you posted in the application has been persisted in the created table.
Finally, when the note is persisted in the DynamoDB table a record is added to the table's stream which is in turn processed by the
DynamoStreamHandlerFunction. You can view the logs for this function in CloudWatch and verify that a new document has been added to the CloudSearch domain you created.
Cleaning Up the Application Resources
To remove all resources created by this example, do the following:
- Delete all objects from the S3 bucket created by the CloudFormation stack.
- Delete the CloudFormation stack.
- Delete the Amazon Cognito identity pool, API Gateway, and CloudSearch domain.
- Delete the CloudWatch log groups associated with each Lambda function created by the CloudFormation stack.
CloudFormation Template Resources
NotesApiFunction - A function to handle posted notes from the mobile application via API Gateway.
SearchApiFunction - A function that uses the CloudSearch domain to find indexed notes based on search terms.
DynamoStreamHandlerFunction - A function that adds an indexed document to the provided CloudSearch domain based on records in the
AWS Identity and Access Management (IAM) Roles
NotesApiRole - A role for the
NotesApiFunction. This role grants permission for logging and working with items in the
SearchApiRole - A role for the
SearchApiFunction. This role grants permissions for logging and searching the provided CloudSearch domain.
DynamoStreamHandlerRole - A role for the DynamoStreamHandlerFunction. This role grants permissions for logging and adding documents to the provided CloudSearch domain.
MobileClientRole - A role used by your Amazon Cognito identity pool for both unauthenticated and authenticated users. This role provides access to the provided API Gateway REST API as well as permissions for putting objects to the
MobileUploadsBucket - An S3 bucket for user uploaded photos.
CloudFrontDistribution - A CDN distribution with the
MobileUploadsBucketconfigured as an origin.
PhotoNotesTable - A DynamoDB table that stores notes uploaded by users from the mobile application.
ConfigTable - A DynamoDB table to hold configuration values read by the various Lambda functions. The name of this table, "MobileRefArchConfig", is hard coded into each function's code and cannot be modified without updating the code as well.
ConfigHelperStack - A sub-stack that creates a custom resource for writing entries to the
ConfigTable. This stack creates a Lambda function and execution role that grants UpdateItem permission on the
NotesTableConfig - A configuration entry that identifies the
SearchEndpointConfig - A configuration entry that identifies the search endpoint of the CloudSearch domain passed as a parameter.
DocumentEndpointConfig - A configuration entry that identifies document endpoint of the CloudSearch domain passed as a parameter.
This reference architecture sample is licensed under Apache 2.0.