Deploy a free backend with REST API using Amazon Web Services (AWS)

Posted on Posted in C#, Cloud

Nowadays most applications require internet access. Usually we need a backend to provide content, store data or to share information between multiple users. However, if you work on a small personal project, most likely you won’t be interested in spending money on servers, especially when you don’t even know if your idea will make any money.

Fortunately there are Amazon Web Services which provide a wide range of services in Free Tier. This is a perfect solution for mobile applications.

Index


AWS
Pricing
Architecture
Prepare environment
Deploy backend using AWS Lambda
Create AWS Lambda project
Prepare models
Implement logic
Create IAM user
Create IAM role
Deploy
Test
Deploy REST API using AWS API Gateway
Define resources & methods
Attach AWS Lambda Function
Add body mapping template
Deploy
Test query parameters
Test path parameters

 

AWS


It’s free, however with some limits. Great thing about this approach is that you pay for what you use, so if your project will become famous, you can easily cover extra costs without any up-front payments.

Another huge advantage of AWS is that it scales up easily, you won’t encounter most issues which are very likely when you have only one server and traffic dramatically increases. Using AWS you can easily add load balancing, enable cache, throttling and provide multiple endpoints located around the world.

 

Pricing


Limits in Free Tier:
  • AWS Lambda – 1 million free requests per month
  • AWS API Gateway – 1 million free API calls per month
  • AWS DynamoDB – free 25GB of storage and up to 200 million requests per month
Limits after the first 12 months (when Free Tier expires)

From 3 services which I mentioned above only AWS API Gateway will become extra paid. To ensure the same limits as in Free Tier, you will have to pay around $4 per month. Exactly it’s $3.50 per million API calls received, plus the cost of data transfer out ($0.09/GB for the first 10 TB).

You may say now ‘wait… so I will have to pay anyway!’, but think about it from another perspective. If during the first year your project won’t make money, then you may decide to close it or move it to some low-performance solution like a small private server. On the other hand, if you do make some money, then probably 2 or 4 dollars per month shouldn’t be a big deal.

 

Architecture


Idea is quite simple, I will create a REST API using AWS API Gateway and each endpoint will call AWS Lambda function to perform backend operations. In this example I will create an endpoint for movies autocomplete feature.

Sample API call:

https://domain.com/movies/autocomplete?genres=1,3&phrase=lord

Sample backend input:

{
    "phrase": "lord",
    "genres": [1, 3]
}

Sample output:

[
   {
      "Id": 1243,
      "Title": "The Lord of the Rings",
      "Genres": [2, 3]
   }
]

 

Prepare environment


  1. Create a Free Tier account on AWS.
  2. Install Visual Studio 2017 with .NET Core.
  3. Download and install AWS Toolkit for Visual Studio, which will add an extensions to create and deploy AWS Lambda easily.

 

Deploy backend using AWS Lambda


AWS Lambda provides a cloud server where you can deploy your own logic to process requests from API Gateway. It’s very handy, because you can implement there a simple backend. You can even integrate it with database like AWS DynamoDB. In this example I will show how to create a function to return list of movies.

AWS Lambda supports C# (.NET Core), Go 1.x, Java 8, Node.js and Python, so you can choose any language you like, I will use C#.

Create AWS Lambda project

Open Visual Studio 2017, click on “Create new project…”, select template called “AWS Lambda Project (.NET Core)” and name it “MoviesLambda”.

Create AWS Lambda project

 

Prepare models

AWS Lambda by default uses JsonSerializer, therfore we can just create a class with public properties and JSON will be automatically converted into this object. Our models could look like this:

Implement logic

Now when we have input data, we can prepare results. A sample implementation to filter results:

Create IAM user

When everything is ready, we can prepare to deploy our Lambda function. First we need to create an IAM user, which will be used to deploy Lambda from Visual Studio.

  1. Go to IAM -> Users
  2. Click on “Add user”
  3. Name it as you wish and check “Programmatic access”
  4. Click on “Next: Permissions”
  5. Click on “Attach existing policies directly” and select “AWSLambdaFullAccess”
  6. Click on “Next: Review”
  7. Click on “Create user”
  8. Click on “Download .csv” (important, later it won’t be possible)
Create IAM role
  1. Go to IAM -> Roles
  2. Click on “Create role”
  3. Click on “AWS Service” and select “Lambda”
  4. Click on “Next: Permissions”
  5. Select “AWSLambdaFullAccess”
  6. Click on “Next: Review”
  7. Name the role as you wish and click on “Create role”
Deploy

Now we are ready to publish our Lambda function.

  1. Go to Visual Studio, right click on the project and select “Publish to AWS Lambda…”
    Publish
  2. Create a new account profile and load previously downloaded .csv file (creating IAM user)
    Create account profile
  3. Select region to upload Lambda
  4. Fill the form according to the screenshot:
    Publishing
  5. Click on “Next”
  6. Select previously created IAM role
  7. Click on “Upload”
Test

After upload is finished you should see a window where you can test your Lambda (you can also test it from AWS Lambda panel on the website), so let’s perform a sample request:

AWS Lambda test window

 

Deploy REST API using AWS API Gateway


AWS API Gateway provides a control panel to define REST API using visual designer. It offers many customizations like body mapping, request transformations, response transformations etc. In this section I will describe a simple usage to demonstrate how to configure it. For more details please refer to the documentation.

Define resources & methods
  1. Go to Amazon API Gateway
  2. Click on “Create API”
  3. Set API Name = “Movies” and click on “Create API”
  4. Now let’s define the following endpoint /autocomplete.
    In order to do that click on “Actions” -> “Create Resource”
  5. Name it “Autocomplete” and click on “Create Resource”
  6. Now let’s define GET method for this resource.
    Click on “Actions” -> “Create Method”, select “GET” and confirm.

    API

I assumed that we are going to call endpoint using query parameters: /autocomplete?genres=1,3&phrase=the. If you want to use path parameters to pass the phrase and genres you just need to create nested resources like this:

API path parameters

Use brackets in resource path to mark it as parameter. Next steps will remain the same no matter which approach you will choose.

Attach AWS Lambda Function

Next we need to attach our Lambda Function to be invoked by created endpoint. In order to do that click on “GET”, select your Lambda function and click on “Save”:

Select Lambda

 

Add body mapping template

So far we’ve got defined API, however we still need to convert URL parameters to JSON object which will be passed to Lambda function. Fortunately it’s quite easy.

We can define our own body mapping and using $input.params(‘param_name’) we can extract parameters from URL. We will also use $util.urlDecode(‘param’) to decode for example ‘the%20lord’ to ‘the lord’ before passing it to Lambda.

To set Body Mapping Template:

  1. Click on “GET” -> “Integration Request” -> “Body Mapping Templates”
  2. Select “Never”
  3. Click on “Add mapping template” and set Content-Type = “application/json”
  4. Set the following template:

    Body Mapping Template

Deploy

Final steps to publish API:

  1. Click on “Actions” -> “Deploy API”
  2. Select “[New Stage]”, name it “movies”
  3. Click on “Deploy”
  4. At the top you will see your public API url:
    https://{id}.execute-api.{region}.amazonaws.com/movies
Test query parameters (autocomplete?genres=1,3&phrase=the)
  1. Deploy your API
  2. Select your stage from Stages menu
  3. Go to “Logs”
  4. Enabled logging according to the screenshot:
    Enable logging
  5. Deploy your API again (to enable CloudWatch logs)
  6. Go to CloudWatch
  7. Click on “Logs” and select your Log Group
  8. Now when you call your endpoint you will see here what’s going on:

    Logs
    Logs
Test path parameters (autocomplete/1,3/the)

In this case it’s simple, you don’t even have to deploy your API.

  1. Click on “GET” method from your API structure.
  2. Click on “TEST” on diagram.
  3. Fill parameters and click on “Test”

    API test
    API test