## Overview The Amplify CLI deploys REST APIs and handlers using [Amazon API Gateway](http://docs.aws.amazon.com/apigateway/latest/developerguide/) and [AWS Lambda](http://docs.aws.amazon.com/lambda/latest/dg/). 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](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html). See [the authentication section for more details](/sdk/auth/how-it-works) for using the `AWSMobileClient` in your application. ## Set Up Your Backend In a terminal window, navigate to your project folder (the folder that contains your app `.Xcodeproj` file), and add the SDK to your app. ```bash cd ./YOUR_PROJECT_FOLDER amplify add api ``` When prompted select the following options: ```console > 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: ```bash amplify push ``` Once the deployment completes a folder called `generated-src` will be added in the folder directory. This is the client SDK that you will add to your project in the next section. ## Connect to Your Backend Add `AWSAPIGateway` to your Podfile: ```ruby target :'YOUR-APP-NAME' do use_frameworks! # For API pod 'AWSAPIGateway' # other pods end ``` Run `pod install --repo-update` and then add the `generated-src` folder and `awsconfiguration.json` file to your project **(File->Add Files to ..->Add)** and then build your project, ensuring there are no issues. Next, set the bridging header for Swift in your project settings. Double-click your project name in the Xcode Project Navigator, choose the Build Settings tab and search for `Objective-C Bridging Header`. Enter `generated-src/Bridging_Header.h` This is needed because the AWS generated code has some Objective-C code which requires bridging to be used for Swift. If you already have a bridging header in your app, you can just append an extra line to it: `#import "AWSApiGatewayBridge.h"` instead of above step. The generated files determine the name of your client when making API calls. In the `generated-src` folder, files ending with name `*Client.swift` are the names of your client (without .swift extension). The path of the client code file is: **./generated-src/YOUR_API_RESOURCE_NAME+YOUR_APP_NAME+Client.swift** So, for an app named `useamplify` with an API resource named `xyz123`, the path of the code file might be **./generated-src/xyz123useamplifyabcdClient.swift**. The API client name would be `xyz123useamplifyabcdClient` and you would use it in your code with `xyz123useamplifyabcdClient.registerClient()` and `xyz123useamplifyabcdClient.client()`. 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 `AWSAPIGateway` and use the generated client class, model, and resource paths as in the below example with `YOUR_API_CLIENT_NAME` replaced from the previous section. For AWS IAM authorization use the `AWSMobileClient` as outlined in [the authentication section](/sdk/auth/how-it-works). ```swift import AWSAPIGateway import AWSMobileClient // ViewController or application context . . . func doInvokeAPI() { // change the method name, or path or the query string parameters here as desired let httpMethodName = "POST" // change to any valid path you configured in the API let URLString = "/items" let queryStringParameters = ["key1":"{value1}"] let headerParameters = [ "Content-Type": "application/json", "Accept": "application/json" ] let httpBody = "{ \n " + "\"key1\":\"value1\", \n " + "\"key2\":\"value2\", \n " + "\"key3\":\"value3\"\n}" // Construct the request object let apiRequest = AWSAPIGatewayRequest(httpMethod: httpMethodName, urlString: URLString, queryParameters: queryStringParameters, headerParameters: headerParameters, httpBody: httpBody) // Create a service configuration let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: AWSMobileClient.default()) // Initialize the API client using the service configuration xyz123useamplifyabcdClient.registerClient(withConfiguration: serviceConfiguration!, forKey: "CloudLogicAPIKey") // Fetch the Cloud Logic client to be used for invocation let invocationClient = xyz123useamplifyabcdClient.client(forKey: "CloudLogicAPIKey") invocationClient.invoke(apiRequest).continueWith { (task: AWSTask) -> Any? in if let error = task.error { print("Error occurred: \(error)") // Handle error here return nil } // Handle successful result here let result = task.result! let responseString = String(data: result.responseData!, encoding: .utf8) print(responseString) print(result.statusCode) return nil } } ``` You can then invoke this method with `self.doInvokeAPI()` from your application code. ### 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 an argument of `token:String`. Next, add a header of `"Authorization" : token` and set the service configuration to have `credentialsProvider: nil`. Finally, overload the `doInvokeAPI()` with a new definition that gets the Cognito User Pools token from the `AWSMobileClient` as below: ```swift //New overloaded function that gets Cognito User Pools tokens func doInvokeAPI(){ AWSMobileClient.default().getTokens { (tokens, err) in self.doInvokeAPI(token: tokens!.idToken!.tokenString!) } } //Updated function with arguments and code updates func doInvokeAPI(token:String) { let headerParameters = [ //other headers "Authorization" : token ] let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: nil) } ``` You can then invoke this method with `self.doInvokeAPI()` from your application code and it will pass the IdToken from Cognito User Pools as an `Authorization` header.