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.

1cd YOUR_PROJECT_FOLDER
2amplify add api

When prompted select the following options:

1> REST
2> Create a new Lambda function
3> Serverless express function
4> Restrict API access? Yes
5> 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:

1amplify 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:

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

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:

1import YOUR_API_RESOURCE_NAME.YOUR_APP_NAME_XXXXClient;
2
3private YOUR_APP_NAME_XXXXClient apiClient = new ApiClientFactory()
4 .credentialsProvider(AWSMobileClient.getInstance())
5 .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.

1import android.support.v7.app.AppCompatActivity;
2import android.os.Bundle;
3import android.util.Log;
4
5import com.amazonaws.http.HttpMethodName;
6import com.amazonaws.mobile.client.AWSMobileClient;
7import com.amazonaws.mobile.client.AWSStartupHandler;
8import com.amazonaws.mobile.client.AWSStartupResult;
9import com.amazonaws.mobileconnectors.apigateway.ApiClientFactory;
10import com.amazonaws.mobileconnectors.apigateway.ApiRequest;
11import com.amazonaws.mobileconnectors.apigateway.ApiResponse;
12import com.amazonaws.util.IOUtils;
13import com.amazonaws.util.StringUtils;
14
15import java.io.InputStream;
16import java.util.HashMap;
17import java.util.Map;
18
19// TODO Replace this with your api friendly name and client class name
20import YOUR_API_RESOURCE_NAME.YOUR_APP_NAME_XXXXClient;
21
22public class MainActivity extends AppCompatActivity {
23 private static final String TAG = MainActivity.class.getSimpleName();
24
25 // TODO Replace this with your client class name
26 private YOUR_APP_NAME_XXXXClient apiClient;
27
28 @Override
29 protected void onCreate(Bundle savedInstanceState) {
30 super.onCreate(savedInstanceState);
31 setContentView(R.layout.activity_main);
32
33 // Initialize the AWS Mobile Client
34 AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
35 @Override
36 public void onComplete(AWSStartupResult awsStartupResult) {
37 Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!");
38 }
39 }).execute();
40
41 // Create the client
42 apiClient = new ApiClientFactory()
43 .credentialsProvider(AWSMobileClient.getInstance())
44 .build(YOUR_API_CLIENT_NAME.class);
45
46 doInvokeAPI();
47 }
48
49 public void doInvokeAPI() {
50 // Create components of api request
51 final String method = "GET";
52 final String path = "/items";
53
54 final String body = "";
55 final byte[] content = body.getBytes(StringUtils.UTF8);
56
57 final Map parameters = new HashMap<>();
58 parameters.put("lang", "en_US");
59
60 final Map headers = new HashMap<>();
61
62 // Use components to create the api request
63 ApiRequest localRequest =
64 new ApiRequest(apiClient.getClass().getSimpleName())
65 .withPath(path)
66 .withHttpMethod(HttpMethodName.valueOf(method))
67 .withHeaders(headers)
68 .addHeader("Content-Type", "application/json")
69 .withParameters(parameters);
70
71 // Only set body if it has content.
72 if (body.length() > 0) {
73 localRequest = localRequest
74 .addHeader("Content-Length", String.valueOf(content.length))
75 .withBody(content);
76 }
77
78 final ApiRequest request = localRequest;
79
80 // Make network call on background thread
81 new Thread(new Runnable() {
82 @Override
83 public void run() {
84 try {
85 Log.d(TAG,
86 "Invoking API w/ Request : " +
87 request.getHttpMethod() + ":" +
88 request.getPath());
89
90 final ApiResponse response = apiClient.execute(request);
91
92 final InputStream responseContentStream = response.getContent();
93
94 if (responseContentStream != null) {
95 final String responseData = IOUtils.toString(responseContentStream);
96 Log.d(TAG, "Response : " + responseData);
97 }
98
99 Log.d(TAG, response.getStatusCode() + " " + response.getStatusText());
100
101 } catch (final Exception exception) {
102 Log.e(TAG, exception.getMessage(), exception);
103 exception.printStackTrace();
104 }
105 }
106 }).start();
107 }
108}

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:

1//Pass in null for credentialsProvider
2apiClient = new ApiClientFactory()
3 .credentialsProvider(null)
4 .build(YOUR_API_CLIENT_NAME.class);
5
6//New overloaded function that gets Cognito User Pools tokens
7public void doInvokeAPI(){
8 AWSMobileClient.getInstance().getTokens(new Callback<Tokens>() {
9 @Override
10 public void onResult(Tokens tokens) {
11 doInvokeAPI(tokens.getIdToken().getTokenString());
12 }
13
14 @Override
15 public void onError(Exception e) {
16 e.printStackTrace();
17 }
18 });
19}
20
21//Updated function with arguments and code updates
22public void doInvokeAPI(String token) {
23 ApiRequest localRequest = new ApiRequest(apiClient.getClass().getSimpleName())
24 .withPath(path)
25 .withHttpMethod(HttpMethodName.valueOf(method))
26 .withHeaders(headers)
27 .addHeader("Content-Type", "application/json")
28 .addHeader("Authorization", token) //Use JWT token
29 .withParameters(parameters);
30}

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.