awslabs / aws-sdk-kotlin

Multiplatform AWS SDK for Kotlin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Publish a low level untyped "light" client for use in AWS Lambda

c-classen opened this issue · comments

Describe the feature

Next to all the service specific libraries, also build and publish a client library that helps with the basics of AWS API usage such as authentication, but is significantly smaller than the other libraries by not containing lots of model and serialization classes.

Is your Feature Request related to a problem?

I would like to use the client libraries in AWS Lambda, but they are not really suited for it.

With Lambda, it is important that the libraries are small, since there is a 50 MB limit for all compiled code combined. Also, according to the AWS knowledge center, the amounts of classes should be minimal to ensure fast cold start times.

However, the media convert client as an extreme example is a 6.4 MB jar. This is without the generic dependencies on things like HTTP client and authentication which can be reused between clients for different services. So 99% of those 6.4 MB only result from model and model specific serialization code. Due to the fact the code is generated this gets really out of hand with dozens of sealed classes existing that contain exactly the two objects "Enabled" and "Disabled".

Proposed Solution

For a start, a new library could be created and published. In its most basic version, this library would only handle authentication and making the actual HTTP request. This means that there is a generic client with a method where the user provides the HTTP method, URL including query parameters, HTTP Headers and request body while the library fetches the credentials using the usual mechanisms, signs the request and actually sends it.

In the case of media convert, this would allow me to put the complex settings for the codecs into a simple JSON file that I can load as a resource and pass to that method without having to load hundreds of classes.

In a further step one could also start thinking about how the client accepts the request body and returns the response body. Having the library parse or serialize JSON or XML could be a neat feature, but accepting and returning plain byte arrays would be sufficient.

Describe alternative solutions or features you've considered

Using the library as it is

This is of course possible, but there will be a significant performance penalty. This is something that in theory is apparent from the sheer mass of model and model specific serialization classes in the client and the suggestion from the knowledge center to reduce the amount of classes loaded.

It has also been practically tested for the Java library for this project, which pursues a similar idea to the one I am proposing here. It shows that having smaller AWS client libraries can cut cold start times by more than half. Of course, this was for the Java SDK v2 and not Kotlin, but I found that the Kotlin SDK even has a lot more classes than the Java one. Most of the properties in the media convert models requiring sealed classes in the Kotlin SDK used just strings in Java.

Using the API without a client library

This should work and resolve the issues with the cold start, but it would also require fiddling not only with the signing of requests itself, but also fetching the authentication from the different possible sources, such as environment variables, .aws/credentials files while respecting the profile, and so on. While it seems to be all documented, it is not trivial and it would be great to be able to use the implementations that are already present in this project instead.

Using the mentioned aws-lightweight-client-java library

While this library comes close to what I want, it has some drawbacks for my use case:

  1. It does not seem to handle fetching the authentication, which is something I'd like to do in a standardized way that is recommended by AWS.
  2. Of course it does not support Kotlin coroutines as it is not a Kotlin library.
  3. Most important: It is not an official AWS library or SDK. I want to use a client where I have confidence that I will get bug fixes and support for future services and service features.

Acknowledge

  • I may be able to implement this feature request

AWS Kotlin SDK version used

1.0.64

Platform (JVM/JS/Native)

JVM

Operating System and version

Ubuntu 22.04.4

Hi, thanks for the feature request! We don't plan to implement something like this at the moment, but I will leave this issue open for you and others to provide extra context and express interest in the feature.

Note: The Kotlin SDK has been designed with modularity in mind, so you should already be able to pick and choose which components you need (i.e signing, credentials providers, serialization / deserialization) and create a light client tailored to your requirements.

Thank you for your response. Is there any documentation about how to to pick those components, like for example only using signing and credential providers while not packaging the model, serialization and deserialization classes? The developer guide as well as the examples only seem to cover how to use the clients including models and serialization, although I might have missed it, especially if it was in one of the service specific examples.

This would be an advanced use of the SDK, so it's not well documented. Here are some pointers:

  • For credentials, you can pick any CredentialsProvider and call its resolve() method to get credentials. If you want the same out-of-the-box experience as the Kotlin SDK, you can use DefaultChainCredentialsProvider.
  • For signing, there is a DefaultAwsSigner which takes an HttpRequest and a signing config, this is likely what you want to use for signing in a light client.
  • For serialization/deserialization, it would depend on the protocol that the service uses. All of the serializers and deserializers for AWS services are implemented and available in the serde project.