How to get http status and detailed response from an API in AWS using the Amplify framework?

1.5k views Asked by At

In my AWS project, I created webservices using Lambda and API Gateway. Those webservices are called by my iOS app, using the Amplify framework.

In my lambda functions:

  • I return something like the following when there is no error:
    return {
        statusCode: 200,
        body: JSON.stringify({
            "example_key_1": "example_value",
            "example_key_2": 123456789
        })
    };
  • I return something like the following when there is an error:
    return {
        statusCode: 400,
        body: JSON.stringify({
            "custom_error_code": 333333
        })
    };

And from my iOS app, I call my API by doing something like the following:

    Amplify.API.post(request: request) { result in
        switch result
        {
            case .success(let data):
                print("success: \(data)")
            case .failure(let error):
                print("error: \(error)"
        }
    }

Now, here are the infos I need to get from the response of the API:

  • the status code, when there is an error
  • the body of the response, whether there is an error or not

In other words, I need to get in my iOS app the whole content of each return of the lambda, when I call the API.

It seems easily doable with the Amplify framework for Javascript, according to this, but I can't find the equivalent for iOS or Android.

How can I achieve that with the Amplify framework?

Thanks.

3

There are 3 answers

1
Jameson On

Amplify Android

val body = JSONObject()
    .put("name", "Mow the lawn")
    .toString()
    .toByteArray()
val request = RestOptions.builder()
    .addPath("/todo")
    .addBody(body)
    .build()

Amplify.API.post(request,
    { response ->
        if (!response.code.isSuccessful()) {
            Log.w("TAG", "non-200 return code")
        } else {
            val data = repsonse.data.asString()
            Log.i("Demo", "OK! Data = $data")
        }
    },
    { failure ->
        Log.e("Demo", "No response from server", failure)
    }
)

Amplify iOS

let request = RESTRequest(path: "/todo", body: "my new Todo".data(using: .utf8))
Amplify.API.post(request: request) { result in
    switch result {
    case .success(let data):
        let str = String(decoding: data, as: UTF8.self)
        print("Success \(str)")
    case .failure(let apiError):
        switch apiError {
        case .httpStatusError(_, let response):
            println("\(response.statusCode)")
        else:
            println("No response from server")
        }
    }
}
0
Jorge Gonzales On

From version 1.7 you can use:

if case let .httpStatusError(statusCode, response) = error, let awsResponse = response as? AWSHTTPURLResponse {
 if let responseBody = awsResponse.body {
     print("Response contains a \(responseBody.count) byte long response body")
 }
}

As stated in PR #1076

1
Hakan Yıldızay On

I had the same problem as yours when developing integrating API Gateway in iOS project. Actually I raised a PR for that. Take a look.. Unfortunately they closed that PR. But anyway I started using my own fork for my project. It has been live for 2 months. And I haven't faced any issues.

Hope it would help.