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