Skip to content

Commit 52e75e2

Browse files
authored
Lambda-related helper methods for http::request::Parts and http::Extensions (#607)
1 parent 3ee4389 commit 52e75e2

File tree

14 files changed

+985
-605
lines changed

14 files changed

+985
-605
lines changed

examples/http-cors/src/main.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@ async fn main() -> Result<(), Error> {
3232
}
3333

3434
async fn func(event: Request) -> Result<Response<Body>, Error> {
35-
Ok(match event.query_string_parameters().first("first_name") {
36-
Some(first_name) => format!("Hello, {}!", first_name).into_response().await,
37-
_ => Response::builder()
38-
.status(400)
39-
.body("Empty first name".into())
40-
.expect("failed to render response"),
41-
})
35+
Ok(
36+
match event
37+
.query_string_parameters_ref()
38+
.and_then(|params| params.first("first_name"))
39+
{
40+
Some(first_name) => format!("Hello, {}!", first_name).into_response().await,
41+
None => Response::builder()
42+
.status(400)
43+
.body("Empty first name".into())
44+
.expect("failed to render response"),
45+
},
46+
)
4247
}

examples/http-query-parameters/src/main.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ use lambda_http::{run, service_fn, Error, IntoResponse, Request, RequestExt, Res
66
/// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples
77
async fn function_handler(event: Request) -> Result<impl IntoResponse, Error> {
88
// Extract some useful information from the request
9-
Ok(match event.query_string_parameters().first("first_name") {
10-
Some(first_name) => format!("Hello, {}!", first_name).into_response().await,
11-
_ => Response::builder()
12-
.status(400)
13-
.body("Empty first name".into())
14-
.expect("failed to render response"),
15-
})
9+
Ok(
10+
match event
11+
.query_string_parameters_ref()
12+
.and_then(|params| params.first("first_name"))
13+
{
14+
Some(first_name) => format!("Hello, {}!", first_name).into_response().await,
15+
None => Response::builder()
16+
.status(400)
17+
.body("Empty first name".into())
18+
.expect("failed to render response"),
19+
},
20+
)
1621
}
1722

1823
#[tokio::main]

examples/http-shared-resource/src/main.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,29 @@ async fn main() -> Result<(), Error> {
3232

3333
// Define a closure here that makes use of the shared client.
3434
let handler_func_closure = move |event: Request| async move {
35-
Result::<Response<Body>, Error>::Ok(match event.query_string_parameters().first("first_name") {
36-
Some(first_name) => {
37-
shared_client_ref
38-
.response(event.lambda_context().request_id, first_name)
39-
.into_response()
40-
.await
41-
}
42-
_ => Response::builder()
43-
.status(400)
44-
.body("Empty first name".into())
45-
.expect("failed to render response"),
46-
})
35+
Result::<Response<Body>, Error>::Ok(
36+
match event
37+
.query_string_parameters_ref()
38+
.and_then(|params| params.first("first_name"))
39+
{
40+
Some(first_name) => {
41+
shared_client_ref
42+
.response(
43+
event
44+
.lambda_context_ref()
45+
.map(|ctx| ctx.request_id.clone())
46+
.unwrap_or_default(),
47+
first_name,
48+
)
49+
.into_response()
50+
.await
51+
}
52+
None => Response::builder()
53+
.status(400)
54+
.body("Empty first name".into())
55+
.expect("failed to render response"),
56+
},
57+
)
4758
};
4859

4960
// Pass the closure to the runtime here.

lambda-http/README.md

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,44 @@
66

77
lambda-http handler is made of:
88

9-
* Request - Represents an HTTP request
10-
* IntoResponse - Future that will convert an [`IntoResponse`] into an actual [`LambdaResponse`]
9+
* `Request` - Represents an HTTP request
10+
* `IntoResponse` - Future that will convert an [`IntoResponse`] into an actual [`LambdaResponse`]
1111

1212
We are able to handle requests from:
1313

1414
* [API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) REST, HTTP and WebSockets API lambda integrations
1515
* AWS [ALB](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html)
1616
* AWS [Lambda function URLs](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html)
1717

18-
Thanks to the Request type we can seemsly handle proxy integrations without the worry to specify the specific service type.
18+
Thanks to the `Request` type we can seamlessly handle proxy integrations without the worry to specify the specific service type.
1919

20-
There is also an Extentions for `lambda_http::Request` structs that provide access to [API gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format) and [ALB](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html) features.
20+
There is also an extension for `lambda_http::Request` structs that provide access to [API gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format) and [ALB](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html) features.
2121

2222
For example some handy extensions:
2323

24-
* query_string_parameters - Return pre-parsed http query string parameters, parameters provided after the `?` portion of a url associated with the request
25-
* path_parameters - Return pre-extracted path parameters, parameter provided in url placeholders `/foo/{bar}/baz/{boom}` associated with the request
26-
* payload - Return the Result of a payload parsed into a serde Deserializeable type
24+
* `query_string_parameters` - Return pre-parsed http query string parameters, parameters provided after the `?` portion of a url associated with the request
25+
* `path_parameters` - Return pre-extracted path parameters, parameter provided in url placeholders `/foo/{bar}/baz/{qux}` associated with the request
26+
* `lambda_context` - Return the Lambda context for the invocation; see the [runtime docs](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html#runtimes-api-next)
27+
* `request_context` - Return the ALB/API Gateway request context
28+
* payload - Return the Result of a payload parsed into a type that implements `serde::Deserialize`
29+
30+
See the `lambda_http::RequestPayloadExt` and `lambda_http::RequestExt` traits for more extensions.
2731

2832
## Examples
2933

30-
Here you will find a few examples to handle basic scenarions:
34+
Here you will find a few examples to handle basic scenarios:
3135

32-
* Reading a JSON from a body and deserialise into a structure
33-
* Reading querystring parameters
36+
* Reading a JSON from a body and deserialize into a structure
37+
* Reading query string parameters
3438
* Lambda Request Authorizer
35-
* Passing the Lambda execution context initialisation to the handler
39+
* Passing the Lambda execution context initialization to the handler
3640

37-
### Reading a JSON from a body and deserialise into a structure
41+
### Reading a JSON from a body and deserialize into a structure
3842

3943
The code below creates a simple API Gateway proxy (HTTP, REST) that accept in input a JSON payload.
4044

4145
```rust
42-
use http::Response;
43-
use lambda_http::{run, http::StatusCode, service_fn, Error, IntoResponse, Request, RequestExt};
46+
use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, IntoResponse, Request, RequestPayloadExt};
4447
use serde::{Deserialize, Serialize};
4548
use serde_json::json;
4649

@@ -77,11 +80,10 @@ pub struct MyPayload {
7780
}
7881
```
7982

80-
### Reading querystring parameters
83+
### Reading query string parameters
8184

8285
```rust
83-
use http::Response;
84-
use lambda_http::{run, http::StatusCode, service_fn, Error, IntoResponse, Request, RequestExt};
86+
use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, RequestExt, IntoResponse, Request};
8587
use serde_json::json;
8688

8789
#[tokio::main]
@@ -96,8 +98,8 @@ async fn main() -> Result<(), Error> {
9698
}
9799

98100
pub async fn function_handler(event: Request) -> Result<impl IntoResponse, Error> {
99-
let name = event.query_string_parameters()
100-
.first("name")
101+
let name = event.query_string_parameters_ref()
102+
.and_then(|params| params.first("name"))
101103
.unwrap_or_else(|| "stranger")
102104
.to_string();
103105

@@ -176,15 +178,14 @@ pub fn custom_authorizer_response(effect: &str, principal: &str, method_arn: &st
176178
}
177179
```
178180

179-
## Passing the Lambda execution context initialisation to the handler
181+
## Passing the Lambda execution context initialization to the handler
180182

181183
One of the [best practices](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html) is to take advantage of execution environment reuse to improve the performance of your function. Initialize SDK clients and database connections outside the function handler. Subsequent invocations processed by the same instance of your function can reuse these resources. This saves cost by reducing function run time.
182184

183185
```rust
184186
use aws_sdk_dynamodb::model::AttributeValue;
185187
use chrono::Utc;
186-
use http::Response;
187-
use lambda_http::{run, http::StatusCode, service_fn, Error, IntoResponse, Request, RequestExt};
188+
use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, RequestExt, IntoResponse, Request};
188189
use serde_json::json;
189190

190191
#[tokio::main]
@@ -207,8 +208,8 @@ async fn main() -> Result<(), Error> {
207208
pub async fn function_handler(dynamodb_client: &aws_sdk_dynamodb::Client, event: Request) -> Result<impl IntoResponse, Error> {
208209
let table = std::env::var("TABLE_NAME").expect("TABLE_NAME must be set");
209210

210-
let name = event.query_string_parameters()
211-
.first("name")
211+
let name = event.query_string_parameters_ref()
212+
.and_then(|params| params.first("name"))
212213
.unwrap_or_else(|| "stranger")
213214
.to_string();
214215

0 commit comments

Comments
 (0)