Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

REST API

You are currently viewing the AWS SDK for Mobile documentation which is a collection of low-level libraries. Use the Amplify libraries for all new app development. Learn more

Overview

The Amplify CLI deploys REST APIs and handlers using Amazon API Gateway and AWS Lambda.

The API category will perform SDK code generation which, when used with the AWSMobileClient can be used for creating signed requests for Amazon API Gateway when the service Authorization is set to AWS_IAM or when using a Cognito User Pools Authorizer.

See the authentication section for more details for using the AWSMobileClient in your application.

Set Up Your Backend

In a terminal window, navigate to your project folder (the folder that typically contains your project level build.gradle), and add the SDK to your app.

cd YOUR_PROJECT_FOLDER
amplify add api

When prompted select the following options:

> REST
> Create a new Lambda function
> Serverless express function
> Restrict API access? Yes
> Who should have access? Authenticated and Guest users

When configuration of your API is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by running amplify status. Finally deploy your changes to the cloud:

amplify push

Once the deployment completes a folder with the name of your API's resource name will be created in ./src/main/java. This is the client SDK with the models you will import and use in the ApiClientFactory() builder from your code in the following sections.

Connect to Your Backend

Add the following to your app/build.gradle:

dependencies {
implementation 'com.amazonaws:aws-android-sdk-apigateway-core:ANDROID_SDK_VERSION'
implementation 'com.amazonaws:aws-android-sdk-mobile-client:ANDROID_SDK_VERSION'
implementation 'com.amazonaws:aws-android-sdk-auth-userpools:ANDROID_SDK_VERSION'
}

Build your project. Next, you will need to import the client that was generated in ./src/main/java when you ran amplify push. For example, an app named useamplify with an API resource named xyz123, the path of the code file will be ./src/main/java/xyz123/useamplifyabcdClient.java. The API client name will be useamplifyabcdClient. You would have the following entries in your code:

import YOUR_API_RESOURCE_NAME.YOUR_APP_NAME_XXXXClient;
private YOUR_APP_NAME_XXXXClient apiClient = new ApiClientFactory()
.credentialsProvider(AWSMobileClient.getInstance())
.build(YOUR_API_CLIENT_NAME.class);

Find the resource name of your API by running amplify status. Copy your API client name to use when invoking the API in the following sections.

IAM authorization

To invoke an API Gateway endpoint from your application, import the generated client as outlined in the last section and use the generated client class, model, and resource paths as in the below example with YOUR_API_RESOURCE_NAME.YOUR_APP_NAME_XXXXClient, YOUR_APP_NAME_XXXXClient, and YOUR_API_CLIENT_NAME replaced appropriately. For AWS IAM authorization use the AWSMobileClient as outlined in the authentication section.

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.amazonaws.http.HttpMethodName;
import com.amazonaws.mobile.client.AWSMobileClient;
import com.amazonaws.mobile.client.AWSStartupHandler;
import com.amazonaws.mobile.client.AWSStartupResult;
import com.amazonaws.mobileconnectors.apigateway.ApiClientFactory;
import com.amazonaws.mobileconnectors.apigateway.ApiRequest;
import com.amazonaws.mobileconnectors.apigateway.ApiResponse;
import com.amazonaws.util.IOUtils;
import com.amazonaws.util.StringUtils;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
// TODO Replace this with your api friendly name and client class name
import YOUR_API_RESOURCE_NAME.YOUR_APP_NAME_XXXXClient;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
// TODO Replace this with your client class name
private YOUR_APP_NAME_XXXXClient apiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize the AWS Mobile Client
AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
@Override
public void onComplete(AWSStartupResult awsStartupResult) {
Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!");
}
}).execute();
// Create the client
apiClient = new ApiClientFactory()
.credentialsProvider(AWSMobileClient.getInstance())
.build(YOUR_API_CLIENT_NAME.class);
doInvokeAPI();
}
public void doInvokeAPI() {
// Create components of api request
final String method = "GET";
final String path = "/items";
final String body = "";
final byte[] content = body.getBytes(StringUtils.UTF8);
final Map parameters = new HashMap<>();
parameters.put("lang", "en_US");
final Map headers = new HashMap<>();
// Use components to create the api request
ApiRequest localRequest =
new ApiRequest(apiClient.getClass().getSimpleName())
.withPath(path)
.withHttpMethod(HttpMethodName.valueOf(method))
.withHeaders(headers)
.addHeader("Content-Type", "application/json")
.withParameters(parameters);
// Only set body if it has content.
if (body.length() > 0) {
localRequest = localRequest
.addHeader("Content-Length", String.valueOf(content.length))
.withBody(content);
}
final ApiRequest request = localRequest;
// Make network call on background thread
new Thread(new Runnable() {
@Override
public void run() {
try {
Log.d(TAG,
"Invoking API w/ Request : " +
request.getHttpMethod() + ":" +
request.getPath());
final ApiResponse response = apiClient.execute(request);
final InputStream responseContentStream = response.getContent();
if (responseContentStream != null) {
final String responseData = IOUtils.toString(responseContentStream);
Log.d(TAG, "Response : " + responseData);
}
Log.d(TAG, response.getStatusCode() + " " + response.getStatusText());
} catch (final Exception exception) {
Log.e(TAG, exception.getMessage(), exception);
exception.printStackTrace();
}
}
}).start();
}
}

Cognito User Pools authorization

When invoking an API Gateway endpoint with Cognito User Pools authorizer, you can leverage the AWSMobileClient to dynamically refresh and pass tokens to your endpoint. Using the example from the previous section, update the doInvokeAPI() so that it takes a "token" string argument like doInvokeAPI(String token). Next, add a header for the token to be passed with .addHeader("Authorization", token) and set the service configuration to have credentialsProvider(null). Finally, overload the doInvokeAPI() with a new definition that gets the Cognito User Pools token from the AWSMobileClient as below:

//Pass in null for credentialsProvider
apiClient = new ApiClientFactory()
.credentialsProvider(null)
.build(YOUR_API_CLIENT_NAME.class);
//New overloaded function that gets Cognito User Pools tokens
public void doInvokeAPI(){
AWSMobileClient.getInstance().getTokens(new Callback<Tokens>() {
@Override
public void onResult(Tokens tokens) {
doInvokeAPI(tokens.getIdToken().getTokenString());
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
});
}
//Updated function with arguments and code updates
public void doInvokeAPI(String token) {
ApiRequest localRequest = new ApiRequest(apiClient.getClass().getSimpleName())
.withPath(path)
.withHttpMethod(HttpMethodName.valueOf(method))
.withHeaders(headers)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", token) //Use JWT token
.withParameters(parameters);
}

You can then invoke this method with doInvokeAPI() from your application code and it will pass the IdToken from Cognito User Pools as an Authorization header.