Description of changes:
Identifying different Lambda events that pertain to HTTP requests is notoriously
hard since they don't contain a simple kind property to help out. This is generally
true - not just a problem in Rust.
In lambda-http a full deserialization of each enabled request type is attempted in
turn, trying the next on failure of the previous, which has the possibility of being a
bit of a performance hog when multiple features are enabled.
Up to 0.8 of lambda-http, the deserialization was made in two stages - firstly using a
private deserializer available in the serde crate to deserialize to an interim value. That
value was then passed to each enabled types's own deserialize associated function.
In 0.9 this was modified to be far cleaner, deserializing into a serde_json::RawValue
to check the general structure of the request JSON, then deserializing the contained
string slice into the type using standard serde_json functions..
However, this latter implementation entails two more downsides:
The attempted type deserializations use the original string rather than already partially parsed-data
The unintended consequence of disabling the possibility of using simd_json as the
incoming deserializer - not exactly a supported feature anyway, but simd_json has a problem
with RawValue.
This PR attempts to solve all these issues by:
Deserializing into a serde_json::Value using the incoming deserializer - this fixes the simd_json issue
Testing for "type determinants" in the Value instead of trying full deserialization - this avoids invoking the
the full Serde deserialization framework multiple times until one works.
Completing the deserialization to the discovered type from the Value - i.e. a partially -parsed internal
structure is used for for the second deserialization phase - much faster using using a string slice.
This also allows for a much simpler "adoption" of simd_json, at least in the lambda_http package, because
simd_json gets to do what it is design for - the string->Value parsing, while serde_json completes the
Value->event parsing.
The one possible drawback I can see in this PR is that if Passthru is enabled, rather than passing through
the original JSON string, that string is reconstructed from the parsed Value. You still get a JSON string but
it won't be exactly the same as the input string. Others who know the project better than I can chime in on that.
By submitting this pull request
[x] I confirm that my contribution is made under the terms of the Apache 2.0 license.
[x] I confirm that I've made a best effort attempt to update all relevant documentation.
Issue #, if available:
792
Description of changes: Identifying different Lambda events that pertain to HTTP requests is notoriously hard since they don't contain a simple
kind
property to help out. This is generally true - not just a problem in Rust.In lambda-http a full deserialization of each enabled request type is attempted in turn, trying the next on failure of the previous, which has the possibility of being a bit of a performance hog when multiple features are enabled.
Up to 0.8 of lambda-http, the deserialization was made in two stages - firstly using a private deserializer available in the serde crate to deserialize to an interim value. That value was then passed to each enabled types's own
deserialize
associated function.In 0.9 this was modified to be far cleaner, deserializing into a serde_json::RawValue to check the general structure of the request JSON, then deserializing the contained string slice into the type using standard serde_json functions..
However, this latter implementation entails two more downsides:
This PR attempts to solve all these issues by:
The one possible drawback I can see in this PR is that if
Passthru
is enabled, rather than passing through the original JSON string, that string is reconstructed from the parsed Value. You still get a JSON string but it won't be exactly the same as the input string. Others who know the project better than I can chime in on that.By submitting this pull request