worker/lib.rs
1#![allow(clippy::new_without_default)]
2#![allow(clippy::or_fun_call)]
3//! # Features
4//! ## `d1`
5//!
6//! Allows the use of [D1 bindings](crate::d1) and [`query!`](crate::query) macro.
7//!
8//!
9//! ## `queue`
10//!
11//! Enables `queue` event type in [`[event]`](worker_macros::event) macro.
12//!
13//! ```
14//! // Consume messages from a queue
15//! #[event(queue)]
16//! pub async fn main(message_batch: MessageBatch<MyType>, env: Env, _ctx: Context) -> Result<()> {
17//! Ok(())
18//! }
19//! ```
20//!
21//! ## `http`
22//! `worker` `0.0.21` introduced an `http` feature flag which starts to replace custom types with widely used types from the [`http`](https://docs.rs/http/latest/http/) crate.
23//!
24//! This makes it much easier to use crates which use these standard types such as [`axum`].
25//!
26//! This currently does a few things:
27//!
28//! 1. Introduce [`Body`], which implements [`http_body::Body`] and is a simple wrapper around [`web_sys::ReadableStream`].
29//! 1. The `req` argument when using the [`[event(fetch)]`](worker_macros::event) macro becomes `http::Request<worker::Body>`.
30//! 1. The expected return type for the fetch handler is `http::Response<B>` where `B` can be any [`http_body::Body<Data=Bytes>`](http_body::Body).
31//! 1. The argument for [`Fetcher::fetch_request`](Fetcher::fetch_request) is `http::Request<worker::Body>`.
32//! 1. The return type of [`Fetcher::fetch_request`](Fetcher::fetch_request) is `http::Response<worker::Body>`.
33//!
34//! The end result is being able to use frameworks like `axum` directly (see [example](./examples/axum)):
35//!
36//! ```rust
37//! pub async fn root() -> &'static str {
38//! "Hello Axum!"
39//! }
40//!
41//! fn router() -> Router {
42//! Router::new().route("/", get(root))
43//! }
44//!
45//! #[event(fetch)]
46//! async fn fetch(
47//! req: HttpRequest,
48//! _env: Env,
49//! _ctx: Context,
50//! ) -> Result<http::Response<axum::body::Body>> {
51//! Ok(router().call(req).await?)
52//! }
53//! ```
54//!
55//! We also implement `try_from` between `worker::Request` and `http::Request<worker::Body>`, and between `worker::Response` and `http::Response<worker::Body>`.
56//! This allows you to convert your code incrementally if it is tightly coupled to the original types.
57//!
58//! ### `Send` Helpers
59//!
60//! A number of frameworks (including `axum`) require that objects that they are given (including route handlers) can be
61//! sent between threads (i.e are marked as `Send`). Unfortuntately, objects which interact with JavaScript are frequently
62//! not marked as `Send`. In the Workers environment, this is not an issue, because Workers are single threaded. There are still
63//! some ergonomic difficulties which we address with some wrapper types:
64//!
65//! 1. [`send::SendFuture`] - wraps any `Future` and marks it as `Send`:
66//!
67//! ```rust
68//! // `fut` is `Send`
69//! let fut = send::SendFuture::new(async move {
70//! // `JsFuture` is not `Send`
71//! JsFuture::from(promise).await
72//! });
73//! ```
74//!
75//! 2. [`send::SendWrapper`] - Marks an arbitrary object as `Send` and implements `Deref` and `DerefMut`, as well as `Clone`, `Debug`, and `Display` if the
76//! inner type does. This is useful for attaching types as state to an `axum` `Router`:
77//!
78//! ```rust
79//! // `KvStore` is not `Send`
80//! let store = env.kv("FOO")?;
81//! // `state` is `Send`
82//! let state = send::SendWrapper::new(store);
83//! let router = axum::Router::new()
84//! .layer(Extension(state));
85//! ```
86//!
87//! 3. [`[worker::send]`](macro@crate::send) - Macro to make any `async` function `Send`. This can be a little tricky to identify as the problem, but
88//! `axum`'s `[debug_handler]` macro can help, and looking for warnings that a function or object cannot safely be sent
89//! between threads.
90//!
91//! ```rust
92//! // This macro makes the whole function (i.e. the `Future` it returns) `Send`.
93//! #[worker::send]
94//! async fn handler(Extension(env): Extension<Env>) -> Response<String> {
95//! let kv = env.kv("FOO").unwrap()?;
96//! // Holding `kv`, which is not `Send` across `await` boundary would mark this function as `!Send`
97//! let value = kv.get("foo").text().await?;
98//! Ok(format!("Got value: {:?}", value));
99//! }
100//!
101//! let router = axum::Router::new()
102//! .route("/", get(handler))
103//! ```
104//!
105//! # RPC Support
106//! `workers-rs` has experimental support for [Workers RPC](https://developers.cloudflare.com/workers/runtime-apis/rpc/).
107//! For now, this relies on JavaScript bindings and may require some manual usage of `wasm-bindgen`.
108//!
109//! Not all features of RPC are supported yet (or have not been tested), including:
110//! - Function arguments and return values
111//! - Class instances
112//! - Stub forwarding
113//!
114//! ## RPC Server
115//!
116//! Writing an RPC server with `workers-rs` is relatively simple. Simply export methods using `wasm-bindgen`. These
117//! will be automatically detected by `worker-build` and made available to other Workers. See
118//! [example](https://github.com/cloudflare/workers-rs/tree/main/examples/rpc-server).
119//!
120//! ## RPC Client
121//!
122//! Creating types and bindings for invoking another Worker's RPC methods is a bit more involved. You will need to
123//! write more complex `wasm-bindgen` bindings and some boilerplate to make interacting with the RPC methods more
124//! idiomatic. See [example](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/src/calculator.rs).
125//!
126//! With manually written bindings, it should be possible to support non-primitive argument and return types, using
127//! `serde-wasm-bindgen`.
128//!
129//! ## Generating Client Bindings
130//!
131//! There are many routes that can be taken to describe RPC interfaces. Under the hood, Workers RPC uses
132//! [Cap'N Proto](https://capnproto.org/). A possible future direction is for Wasm guests to include Cap'N Proto
133//! serde support and speak directly to the RPC protocol, bypassing JavaScript. This would likely involve defining
134//! the RPC interface in Cap'N Proto schema and generating Rust code from that.
135//!
136//! Another popular interface schema in the WebAssembly community is
137//! [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md). This is a lightweight format
138//! designed for the WebAssembly Component model. `workers-rs` includes an **experimental** code generator which
139//! allows you to describe your RPC interface using WIT and generate JavaScript bindings as shown in the
140//! [rpc-client example](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/wit/calculator.wit).
141//! The easiest way to use this code generator is using a
142//! [build script](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/build.rs) as shown in the example.
143//! This code generator is pre-alpha, with no support guarantee, and implemented only for primitive types at this time.
144
145#[doc(hidden)]
146use std::result::Result as StdResult;
147
148#[doc(hidden)]
149pub use async_trait;
150#[doc(hidden)]
151pub use js_sys;
152pub use url::Url;
153#[doc(hidden)]
154pub use wasm_bindgen;
155#[doc(hidden)]
156pub use wasm_bindgen_futures;
157pub use worker_kv as kv;
158
159pub use cf::{Cf, CfResponseProperties, TlsClientAuth};
160pub use worker_macros::{consume, durable_object, event, send};
161#[doc(hidden)]
162pub use worker_sys;
163pub use worker_sys::{console_debug, console_error, console_log, console_warn};
164
165pub use crate::abort::*;
166pub use crate::ai::*;
167pub use crate::analytics_engine::*;
168pub use crate::cache::{Cache, CacheDeletionOutcome, CacheKey};
169pub use crate::context::Context;
170pub use crate::cors::Cors;
171#[cfg(feature = "d1")]
172pub use crate::d1::*;
173pub use crate::date::{Date, DateInit};
174pub use crate::delay::Delay;
175pub use crate::durable::*;
176pub use crate::dynamic_dispatch::*;
177pub use crate::env::{Env, EnvBinding, Secret, Var};
178pub use crate::error::Error;
179pub use crate::fetcher::Fetcher;
180pub use crate::formdata::*;
181pub use crate::global::Fetch;
182pub use crate::headers::Headers;
183pub use crate::http::Method;
184pub use crate::hyperdrive::*;
185#[cfg(feature = "queue")]
186pub use crate::queue::*;
187pub use crate::r2::*;
188pub use crate::rate_limit::RateLimiter;
189pub use crate::request::{FromRequest, Request};
190pub use crate::request_init::*;
191pub use crate::response::{EncodeBody, IntoResponse, Response, ResponseBody, ResponseBuilder};
192pub use crate::router::{RouteContext, RouteParams, Router};
193pub use crate::schedule::*;
194pub use crate::socket::*;
195pub use crate::streams::*;
196pub use crate::version::*;
197pub use crate::websocket::*;
198
199mod abort;
200mod ai;
201mod analytics_engine;
202mod cache;
203mod cf;
204mod context;
205mod cors;
206pub mod crypto;
207// Require pub module for macro export
208#[cfg(feature = "d1")]
209/// **Requires** `d1` feature.
210pub mod d1;
211mod date;
212mod delay;
213pub mod durable;
214mod dynamic_dispatch;
215mod env;
216mod error;
217mod fetcher;
218mod formdata;
219mod global;
220mod headers;
221mod http;
222mod hyperdrive;
223#[cfg(feature = "queue")]
224mod queue;
225mod r2;
226mod rate_limit;
227mod request;
228mod request_init;
229mod response;
230mod router;
231mod schedule;
232pub mod send;
233mod socket;
234mod sql;
235mod streams;
236mod version;
237mod websocket;
238
239pub type Result<T> = StdResult<T, error::Error>;
240
241#[cfg(feature = "http")]
242/// **Requires** `http` feature. A convenience Body type which wraps [`web_sys::ReadableStream`](web_sys::ReadableStream)
243/// and implements [`http_body::Body`](http_body::Body)
244pub use http::body::Body;
245#[cfg(feature = "http")]
246pub use http::{
247 request::from_wasm as request_from_wasm, request::to_wasm as request_to_wasm,
248 response::from_wasm as response_from_wasm, response::to_wasm as response_to_wasm,
249};
250#[cfg(feature = "http")]
251/// **Requires** `http` feature. Type alias for `http::Request<worker::Body>`.
252pub type HttpRequest = ::http::Request<http::body::Body>;
253#[cfg(feature = "http")]
254/// **Requires** `http` feature. Type alias for `http::Response<worker::Body>`.
255pub type HttpResponse = ::http::Response<http::body::Body>;
256
257pub use crate::sql::*;