title: API Gateway: Empty request body?
body: <p>I am trying to send a <strong>POST body</strong> to a <strong>AWS Lambda</strong> function using the <strong>iOS (Swift) SDK</strong> generated by <strong>AWS API GATEWAY</strong>, but the transmitted body is always empty.</p>
  
  <p>To do so I set up a model:</p>
  
  <pre><code>{
      "$schema": "http://json-schema.org/draft-04/schema#",
      "title": "InputModel",
      "type": "object",
      "required" : ["name"],
      "properties": {
          "name": { "type": "string" },
      }
  }
  </code></pre>
  
  <p>,which I included in the <em>$Resources -> /test -> POST -> Method Execution -> Method Request -> Request Body</em> panel.</p>
  
  <p>Then I deployed the API and downloaded and included the API Gateway generated SDK. Now I am calling the API (as recommended in <a href="http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk-ios-swift.html" rel="nofollow noreferrer">Use Generated iOS SDK (Swift) to Call API</a>) like so:</p>
  
  <pre><code>let apiClient = APITestClient.default()
  let body = APITest()
  body!.name = "HOLA"
  
  apiClient.testPost(body: body!).continueWith { task -&gt; Void in ... }
  </code></pre>
  
  <p>But the <strong>body</strong> my Lambda function receives is always empty <code>{}</code>, which I checked in the <strong>API Gateway</strong> logs:</p>
  
  <pre><code>(c421a895-b0c7-11e7-89a6-891dcbadf1f0) Method request body before transformations:
  {}
  </code></pre>
  
  <p>and the <strong>Lambda function</strong> Logs:</p>
  
  <pre><code>2017-10-14T10:09:29.418Z    c424b611-b0c7-11e7-99c1-251bdb6a1eac    Request:
  {
      "resource": "/test",
      "path": "/test",
      "httpMethod": "POST",
      "headers": {
          "Accept": "application/json",
          "Accept-Encoding": "br, gzip, deflate",
          "Accept-Language": "en-us",
          "CloudFront-Forwarded-Proto": "https",
          "CloudFront-Is-Desktop-Viewer": "true",
          "CloudFront-Is-Mobile-Viewer": "false",
          "CloudFront-Is-SmartTV-Viewer": "false",
          "CloudFront-Is-Tablet-Viewer": "false",
          "CloudFront-Viewer-Country": "ES",
          "content-type": "application/json",
          "Host": "9hlt8n48wd.execute-api.eu-west-1.amazonaws.com",
          "User-Agent": "aws-sdk-iOS/2.6.4 iOS/11.0 en_US",
          "Via": "2.0 9ee2752d23ce7be13204dc3880c3ca6b.cloudfront.net (CloudFront)",
          "X-Amz-Cf-Id": "39uT89_umng7zPCNHqn3WdLlNJ6zFbQ5fmLVzJJNFcud-7pdZYJ1mg==",
          "X-AMZ-Date": "20171014T100929Z",
          "x-amz-security-token": "---",
          "X-Amzn-Trace-Id": "---",
          "X-Forwarded-For": "---",
          "X-Forwarded-Port": "443",
          "X-Forwarded-Proto": "https"
      },
      "queryStringParameters": null,
      "pathParameters": null,
      "stageVariables": null,
      "requestContext": {
          "path": "/production/test",
          "accountId": "037641059503",
          "resourceId": "hfza9c",
          "stage": "production",
          "requestId": "---",
          "identity": {
            ---
          },
          "resourcePath": "/test",
          "httpMethod": "POST",
          "apiId": "---"
      },
      "body": "{}",
      "isBase64Encoded": false
  }
  </code></pre>
  
  <p>Why is the body always empty? Do I have to initialize the body different than I do? Or is there another stage where the body is cleared?</p>
  
  <hr>
  
  <p><strong>Edit:</strong> 
  I am still struggling, but invoking the normal <em>AWS iOS SDK</em>:</p>
  
  <pre><code>let apiClient = APITestClient.default()
  let apiGatewayRequest = AWSAPIGatewayRequest(httpMethod: "POST", urlString: "/test", queryParameters: nil, headerParameters: nil, httpBody: ["name":"example"])
  apiClient.invoke(apiGatewayRequest).continueWith { task -&gt; Void in ... }
  </code></pre>
  
  <p>works perfectly fine. Why does AWS even bother with generating a special API Gateway SDK?!</p>
  
  <hr>
  
  <p><strong>Edit 2: The API model</strong></p>
  
  <pre><code>public class APITest : AWSModel {
  
      var example: String?
  
      public override static func jsonKeyPathsByPropertyKey() -&gt; [AnyHashable : Any]!{
          var params:[AnyHashable : Any] = [:]
          params["name"] = "name"
  
          return params
      }
  }
  </code></pre>
  
  <p>which is then called by</p>
  
  <pre><code>   public func testPost() -&gt; AWSTask&lt;APITest&gt; {
          let headerParameters = [
                     "Content-Type": "application/json",
                     "Accept": "application/json",
  
                  ]
  
          let queryParameters:[String:Any] = [:]
  
          let pathParameters:[String:Any] = [:]
  
          return self.invokeHTTPRequest("POST", urlString: "/test", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: nil, responseClass: APITest.self) as! AWSTask&lt;APITest&gt;
      }
  </code></pre>