diff --git a/lambda-http/src/ext.rs b/lambda-http/src/ext.rs
index 09551d0e..f034c686 100644
--- a/lambda-http/src/ext.rs
+++ b/lambda-http/src/ext.rs
@@ -55,7 +55,7 @@ impl Error for PayloadError {
     }
 }
 
-/// Extentions for `lambda_http::Request` structs that
+/// Extensions 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.
@@ -109,6 +109,9 @@ pub trait RequestExt {
     /// Return the raw http path for a request without any stage information.
     fn raw_http_path(&self) -> String;
 
+    /// Return the raw http path for a request without any stage information.
+    fn raw_http_path_str(&self) -> &str;
+
     /// Configures instance with the raw http path.
     fn with_raw_http_path(self, path: &str) -> Self;
 
@@ -118,12 +121,24 @@ pub trait RequestExt {
     ///
     /// The yielded value represents both single and multi-valued
     /// parameters alike. When multiple query string parameters with the same
-    /// name are expected, `query_string_parameters().get_all("many")` to retrieve them all.
+    /// name are expected, `query_string_parameters().all("many")` to retrieve them all.
     ///
-    /// No query parameters
-    /// will yield an empty `QueryMap`.
+    /// No query parameters will yield an empty `QueryMap`.
     fn query_string_parameters(&self) -> QueryMap;
 
+    /// Return pre-parsed http query string parameters, parameters
+    /// provided after the `?` portion of a url,
+    /// associated with the API gateway request.
+    ///
+    /// The yielded value represents both single and multi-valued
+    /// parameters alike. When multiple query string parameters with the same
+    /// name are expected,
+    /// `query_string_parameters_ref().and_then(|params| params.all("many"))` to
+    /// retrieve them all.
+    ///
+    /// No query parameters will yield `None`.
+    fn query_string_parameters_ref(&self) -> Option<&QueryMap>;
+
     /// Configures instance with query string parameters
     ///
     /// This is intended for use in mock testing contexts.
@@ -139,6 +154,14 @@ pub trait RequestExt {
     /// These will always be empty for ALB triggered requests
     fn path_parameters(&self) -> QueryMap;
 
+    /// Return pre-extracted path parameters, parameter provided in url placeholders
+    /// `/foo/{bar}/baz/{boom}`,
+    /// associated with the API gateway request. No path parameters
+    /// will yield `None`
+    ///
+    /// These will always be `None` for ALB triggered requests
+    fn path_parameters_ref(&self) -> Option<&QueryMap>;
+
     /// Configures instance with path parameters
     ///
     /// This is intended for use in mock testing contexts.
@@ -153,6 +176,13 @@ pub trait RequestExt {
     /// These will always be empty for ALB triggered requests
     fn stage_variables(&self) -> QueryMap;
 
+    /// Return [stage variables](https://docs.aws.amazon.com/apigateway/latest/developerguide/stage-variables.html)
+    /// associated with the API gateway request. No stage parameters
+    /// will yield `None`
+    ///
+    /// These will always be `None` for ALB triggered requests
+    fn stage_variables_ref(&self) -> Option<&QueryMap>;
+
     /// Configures instance with stage variables under #[cfg(test)] configurations
     ///
     /// This is intended for use in mock testing contexts.
@@ -164,6 +194,10 @@ pub trait RequestExt {
     /// Return request context data associated with the ALB or API gateway request
     fn request_context(&self) -> RequestContext;
 
+    /// Return a reference to the request context data associated with the ALB or
+    /// API gateway request
+    fn request_context_ref(&self) -> Option<&RequestContext>;
+
     /// Configures instance with request context
     ///
     /// This is intended for use in mock testing contexts.
@@ -185,15 +219,23 @@ pub trait RequestExt {
     /// Return the Lambda function context associated with the request
     fn lambda_context(&self) -> Context;
 
+    /// Return a reference to the the Lambda function context associated with the
+    /// request
+    fn lambda_context_ref(&self) -> Option<&Context>;
+
     /// Configures instance with lambda context
     fn with_lambda_context(self, context: Context) -> Self;
 }
 
 impl RequestExt for http::Request<Body> {
     fn raw_http_path(&self) -> String {
+        self.raw_http_path_str().to_string()
+    }
+
+    fn raw_http_path_str(&self) -> &str {
         self.extensions()
             .get::<RawHttpPath>()
-            .map(|ext| ext.0.clone())
+            .map(|RawHttpPath(path)| path.as_str())
             .unwrap_or_default()
     }
 
@@ -204,10 +246,19 @@ impl RequestExt for http::Request<Body> {
     }
 
     fn query_string_parameters(&self) -> QueryMap {
-        self.extensions()
-            .get::<QueryStringParameters>()
-            .map(|ext| ext.0.clone())
-            .unwrap_or_default()
+        self.query_string_parameters_ref().cloned().unwrap_or_default()
+    }
+
+    fn query_string_parameters_ref(&self) -> Option<&QueryMap> {
+        self.extensions().get::<QueryStringParameters>().and_then(
+            |QueryStringParameters(params)| {
+                if params.is_empty() {
+                    None
+                } else {
+                    Some(params)
+                }
+            },
+        )
     }
 
     fn with_query_string_parameters<Q>(self, parameters: Q) -> Self
@@ -220,10 +271,19 @@ impl RequestExt for http::Request<Body> {
     }
 
     fn path_parameters(&self) -> QueryMap {
-        self.extensions()
-            .get::<PathParameters>()
-            .map(|ext| ext.0.clone())
-            .unwrap_or_default()
+        self.path_parameters_ref().cloned().unwrap_or_default()
+    }
+
+    fn path_parameters_ref(&self) -> Option<&QueryMap> {
+        self.extensions().get::<PathParameters>().and_then(
+            |PathParameters(params)| {
+                if params.is_empty() {
+                    None
+                } else {
+                    Some(params)
+                }
+            },
+        )
     }
 
     fn with_path_parameters<P>(self, parameters: P) -> Self
@@ -236,10 +296,19 @@ impl RequestExt for http::Request<Body> {
     }
 
     fn stage_variables(&self) -> QueryMap {
-        self.extensions()
-            .get::<StageVariables>()
-            .map(|ext| ext.0.clone())
-            .unwrap_or_default()
+        self.stage_variables_ref().cloned().unwrap_or_default()
+    }
+
+    fn stage_variables_ref(&self) -> Option<&QueryMap> {
+        self.extensions().get::<StageVariables>().and_then(
+            |StageVariables(vars)| {
+                if vars.is_empty() {
+                    None
+                } else {
+                    Some(vars)
+                }
+            },
+        )
     }
 
     #[cfg(test)]
@@ -253,12 +322,15 @@ impl RequestExt for http::Request<Body> {
     }
 
     fn request_context(&self) -> RequestContext {
-        self.extensions()
-            .get::<RequestContext>()
+        self.request_context_ref()
             .cloned()
             .expect("Request did not contain a request context")
     }
 
+    fn request_context_ref(&self) -> Option<&RequestContext> {
+        self.extensions().get::<RequestContext>()
+    }
+
     fn with_request_context(self, context: RequestContext) -> Self {
         let mut s = self;
         s.extensions_mut().insert(context);
@@ -266,12 +338,15 @@ impl RequestExt for http::Request<Body> {
     }
 
     fn lambda_context(&self) -> Context {
-        self.extensions()
-            .get::<Context>()
+        self.lambda_context_ref()
             .cloned()
             .expect("Request did not contain a lambda context")
     }
 
+    fn lambda_context_ref(&self) -> Option<&Context> {
+        self.extensions().get::<Context>()
+    }
+
     fn with_lambda_context(self, context: Context) -> Self {
         let mut s = self;
         s.extensions_mut().insert(context);
@@ -358,7 +433,7 @@ mod tests {
     }
 
     #[test]
-    fn requests_have_json_parseable_payloads() {
+    fn requests_have_json_parsable_payloads() {
         #[derive(Deserialize, Eq, PartialEq, Debug)]
         struct Payload {
             foo: String,
@@ -421,7 +496,7 @@ mod tests {
     }
 
     #[test]
-    fn requests_omiting_content_types_do_not_support_parseable_payloads() {
+    fn requests_omitting_content_types_do_not_support_parsable_payloads() {
         #[derive(Deserialize, Eq, PartialEq, Debug)]
         struct Payload {
             foo: String,
@@ -429,7 +504,7 @@ mod tests {
         }
         let request = http::Request::builder()
             .body(Body::from(r#"{"foo":"bar", "baz": 2}"#))
-            .expect("failed to bulid request");
+            .expect("failed to build request");
         let payload: Option<Payload> = request.payload().unwrap_or_default();
         assert_eq!(payload, None);
     }
diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs
index 95cf6a52..c31398c5 100644
--- a/lambda-http/src/request.rs
+++ b/lambda-http/src/request.rs
@@ -298,7 +298,7 @@ fn into_websocket_request(ag: ApiGatewayWebsocketProxyRequest) -> http::Request<
         .extension(RequestContext::WebSocket(ag.request_context));
 
     // merge headers into multi_value_headers and make
-    // multi-value_headers our cannoncial source of request headers
+    // multi-value_headers our canonical source of request headers
     let mut headers = ag.multi_value_headers;
     headers.extend(ag.headers);
     update_xray_trace_id_header(&mut headers);