Skip to main content

worker/
lib.rs

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