1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#![deny(clippy::all, missing_docs)]
//! AWS Lambdas made simple.
//!
//! Vicuna is a library for writing AWS Lambda services using a simple middleware pattern.
//! Middleware can be composed to enable flexible and extensible request and response handling.
//! Because middleware are just functions, they are easy to test and naturally modular.
//!
//! The library is built on top of the [`lambda_runtime`] crate and is meant to be paired with the
//! [`serverless-rust`] plugin for the [Serverless framework].
//!
//!
//! ## Design
//!
//! Middleware are functions which are passed a [`Handler`] and return a `Handler`. Ultimately the
//! `Handler` will process a [`lambda_http::Request`]. The request is passed through the middleware
//! to allow for arbitrary processing of the request-response lifecycle.
//!
//! `Handler` types take in a `lambda_http::Request` and return a [`HandlerResult`].This result can
//! be unfurled to allow for manipulation of the response at that point in the middleware chain.
//!
//! ## Examples
//!
//! To make this more concrete, let's demonstrate what the structure of middleware looks like.
//!
//! ```rust,no_run
//! use vicuna::Handler;
//!
//! fn my_middleware(handler: Handler) -> Handler {
//!     Box::new(move |request, context| {
//!         // Resolve upstream middleware chain into a response...
//!         let mut response = handler(request, context);
//!         // ...mutate response as desired.
//!         response
//!     })
//! }
//! ```
//!
//! More complex variations of this are possible. For instance, we could introspect the request and
//! conditionally respond based on how it's formed. This is often useful for things such as input
//! validation, event filtering, or additional routing.
//!
//! A chain of middleware must be passed a `Handler`. A [`default_handler`] is provided as a
//! convenience and can be used to start a chain of middleware. Once the chain is established, we
//! are ready to provide it as a handler to the `lambda_runtime` framework via the [`lambda!`] macro.
//!
//! To illustrate, let's examine an example that utilizes builtin middleware.
//!
//! ```rust,no_run
//! use vicuna::{
//!     default_handler,
//!     error,
//!     lambda_http::lambda,
//!     middleware::{body, header},
//!     Handler, WrappingHandler,
//! };
//!
//! lambda!(default_handler::<error::Error>()
//!     .wrap_with(body("Hello, world!"))
//!     .wrap_with(header("x-foo", "bar"))
//!     .handler())
//! ```
//!
//! This is a simple example that demonstrates how straightforward it is to establish an AWS Lambda
//! function that's capable of arbitrary request and response handling via a set of composable and
//! reusable middleware functions.
//!
//! [Serverless framework]: https://serverless.com
//! [`HandlerResult`]: handler/type.HandlerResult.html
//! [`Handler`]: handler/type.Handler.html
//! [`default_handler`]: handler/fn.default_handler.html
//! [`lambda!`]: ../lambda_runtime/macro.lambda.html
//! [`lambda_http::Request`]: ../lambda_http/type.Request.html
//! [`lambda_runtime`]: ../lambda_runtime/index.html
//! [`serverless-rust`]: https://github.com/softprops/serverless-rust

pub use handler::{default_handler, Handler, WrappingHandler};
pub use middleware::Middleware;

pub use lambda_http;
pub use lambda_runtime;

/// Error and result types.
pub mod error;

/// AWS Lambda request handler.
pub mod handler;

/// Handler middleware type and trait.
pub mod middleware;