You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中手动实现AWS API Gateway SDK及替代方案咨询

问题解答

1. Kotlin手动实现API Gateway客户端的正确方式

核心是处理AWS请求签名(若API启用IAM/Cognito授权)和请求构建,具体步骤如下:

1.1 获取Amplify Auth凭证

从Amplify获取当前用户的有效临时凭证,用于后续签名:

val authSession = Amplify.Auth.fetchAuthSession()
if (authSession is AWSCognitoAuthSession) {
    val credentials = authSession.credentialsResult.value
    val awsCredentials = BasicSessionCredentials(
        credentials.accessKey,
        credentials.secretKey,
        credentials.sessionToken
    )
    // 后续用此凭证签名请求
}

1.2 实现SigV4请求签名

API Gateway的IAM授权要求用SigV4签名请求,借助AWS SDK的SigV4Signer完成:

import com.amazonaws.auth.AWSCredentials
import com.amazonaws.auth.SigV4Signer
import com.amazonaws.http.HttpMethodName

fun signRequest(
    credentials: AWSCredentials,
    request: okhttp3.Request,
    region: String = "你的API区域",
    serviceName: String = "execute-api"
): okhttp3.Request {
    val signer = SigV4Signer()
    val awsRequest = com.amazonaws.http.HttpRequest.builder()
        .method(HttpMethodName.fromValue(request.method))
        .endpoint(URI.create(request.url.toString()))
        .apply {
            request.headers.forEach { name, values ->
                values.forEach { value -> addHeader(name, value) }
            }
            request.body?.takeIf { it.contentLength() > 0 }?.let {
                content = it.byteStream()
            }
        }.build()

    signer.sign(awsRequest, credentials, serviceName, region)

    return request.newBuilder()
        .apply {
            awsRequest.headers.forEach { header ->
                addHeader(header.name, header.value)
            }
        }
        .build()
}

1.3 构建Proxy路径请求

针对/resource1/{proxy+}的Proxy资源,替换路径参数并构建基础请求:

val baseApiUrl = "https://你的APIID.execute-api.你的区域.amazonaws.com/你的阶段"
val targetSubPath = "user/123" // 替换{proxy+}的实际路径
val fullUrl = "$baseApiUrl/resource1/$targetSubPath"

// 序列化请求体(以Moshi为例)
val requestBody = RequestBody.create(
    MediaType.parse("application/json"),
    moshi.adapter(YourRequestPOKO::class.java).toJson(yourRequestData)
)

val originalRequest = okhttp3.Request.Builder()
    .url(fullUrl)
    .post(requestBody) // 根据业务需求用GET/PUT/DELETE等方法
    .addHeader("Content-Type", "application/json")
    .build()

1.4 执行签名后的请求

在协程中用OkHttp执行签名后的请求,并解析响应:

val okHttpClient = OkHttpClient()

// 协程内执行
val signedRequest = signRequest(awsCredentials, originalRequest)
okHttpClient.newCall(signedRequest).execute().use { response ->
    if (!response.isSuccessful) throw IOException("请求失败:${response.code}")
    val responseBody = response.body?.string() ?: ""
    val responseData = moshi.adapter(YourResponsePOKO::class.java).fromJson(responseBody)
    // 处理响应数据
}

1.5 异常排查

你遇到的ApiClientException常见原因:

  • 凭证无效:检查Amplify是否完成登录,凭证是否过期
  • 签名错误:确认API区域、服务名(固定为execute-api)与配置一致
  • 路径错误:Proxy参数替换是否正确,API阶段名称是否匹配
  • 授权不匹配:API Gateway的授权方式(IAM/Cognito用户池)需与签名/Token传递方式对应

2. OkHttp vs Ktor 与 CORS问题

2.1 客户端选择

两者都是可行方案,按需选择:

  • OkHttp:生态成熟,文档丰富,与AWS签名工具兼容性好,适合熟悉Android传统网络库的团队
  • Ktor:Kotlin原生,协程支持更自然,DSL语法简洁,适合纯Kotlin项目

两者都能轻松处理请求头、请求体和响应解析,核心差异在于语法风格和生态偏好。

2.2 CORS设置

不需要为Android APP配置CORS。CORS是浏览器的同源策略限制,移动APP不受此约束,直接调用API Gateway端点即可。即使API Gateway配置了CORS规则,也不会影响APP请求,但属于冗余配置。


内容的提问来源于stack exchange,提问作者jbdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:43:17