Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
1 task
c-classen opened this issue Mar 9, 2024 · 4 comments
Open
1 task

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

c-classen opened this issue Mar 9, 2024 · 4 comments
Labels
feature-request A feature should be added or improved.

Comments

@c-classen
Copy link

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

@c-classen c-classen added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Mar 9, 2024
@lauzadis
Copy link
Member

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.

@lauzadis lauzadis removed the needs-triage This issue or PR still needs to be triaged. label Mar 14, 2024
@c-classen
Copy link
Author

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.

@lauzadis
Copy link
Member

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.

@jtaub
Copy link

jtaub commented Apr 28, 2024

Out of curiosity, have you considered Snapstart? In my (limited) experience with the Java SDK on Lambda, it didn't make much difference. I haven't tried it with the Kotlin SDK yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved.
Projects
None yet
Development

No branches or pull requests

3 participants