[go: up one dir, main page]

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//! - Function arguments and return values
112//! - Class instances
113//! - Stub forwarding
114//!
115//! ## RPC Server
116//!
117//! Writing an RPC server with `workers-rs` is relatively simple. Simply export methods using `wasm-bindgen`. These
118//! will be automatically detected by `worker-build` and made available to other Workers. See
119//! [example](https://github.com/cloudflare/workers-rs/tree/main/examples/rpc-server).
120//!
121//! ## RPC Client
122//!
123//! Creating types and bindings for invoking another Worker's RPC methods is a bit more involved. You will need to
124//! write more complex `wasm-bindgen` bindings and some boilerplate to make interacting with the RPC methods more
125//! idiomatic. See [example](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/src/calculator.rs).
126//!
127//! With manually written bindings, it should be possible to support non-primitive argument and return types, using
128//! `serde-wasm-bindgen`.
129//!
130//! ## Generating Client Bindings
131//!
132//! There are many routes that can be taken to describe RPC interfaces. Under the hood, Workers RPC uses
133//! [Cap'N Proto](https://capnproto.org/). A possible future direction is for Wasm guests to include Cap'N Proto
134//! serde support and speak directly to the RPC protocol, bypassing JavaScript. This would likely involve defining
135//! the RPC interface in Cap'N Proto schema and generating Rust code from that.
136//!
137//! Another popular interface schema in the WebAssembly community is
138//! [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md). This is a lightweight format
139//! designed for the WebAssembly Component model. `workers-rs` includes an **experimental** code generator which
140//! allows you to describe your RPC interface using WIT and generate JavaScript bindings as shown in the
141//! [rpc-client example](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/wit/calculator.wit).
142//! The easiest way to use this code generator is using a
143//! [build script](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/build.rs) as shown in the example.
144//! This code generator is pre-alpha, with no support guarantee, and implemented only for primitive types at this time.
145
146#[doc(hidden)]
147use std::result::Result as StdResult;
148
149#[doc(hidden)]
150pub use async_trait;
151#[doc(hidden)]
152pub use js_sys;
153pub use url::Url;
154#[doc(hidden)]
155pub use wasm_bindgen;
156#[doc(hidden)]
157pub use wasm_bindgen_futures;
158pub use worker_kv as kv;
159
160pub use cf::{Cf, CfResponseProperties, TlsClientAuth};
161pub use worker_macros::{consume, durable_object, event, send};
162#[doc(hidden)]
163pub use worker_sys;
164pub use worker_sys::{console_debug, console_error, console_log, console_warn};
165
166pub use crate::abort::*;
167pub use crate::ai::*;
168pub use crate::analytics_engine::*;
169pub use crate::cache::{Cache, CacheDeletionOutcome, CacheKey};
170pub use crate::container::*;
171pub use crate::context::Context;
172pub use crate::cors::Cors;
173#[cfg(feature = "d1")]
174pub use crate::d1::*;
175pub use crate::date::{Date, DateInit};
176pub use crate::delay::Delay;
177pub use crate::durable::*;
178pub use crate::dynamic_dispatch::*;
179pub use crate::env::{Env, EnvBinding, Secret, Var};
180pub use crate::error::Error;
181pub use crate::fetcher::Fetcher;
182pub use crate::formdata::*;
183pub use crate::global::Fetch;
184pub use crate::headers::Headers;
185pub use crate::http::Method;
186pub use crate::hyperdrive::*;
187#[cfg(feature = "queue")]
188pub use crate::queue::*;
189pub use crate::r2::*;
190pub use crate::rate_limit::RateLimiter;
191pub use crate::request::{FromRequest, Request};
192pub use crate::request_init::*;
193pub use crate::response::{EncodeBody, IntoResponse, Response, ResponseBody, ResponseBuilder};
194pub use crate::router::{RouteContext, RouteParams, Router};
195pub use crate::schedule::*;
196pub use crate::secret_store::SecretStore;
197pub use crate::socket::*;
198pub use crate::streams::*;
199pub use crate::version::*;
200pub use crate::websocket::*;
201
202mod abort;
203mod ai;
204mod analytics_engine;
205mod cache;
206mod cf;
207mod container;
208mod context;
209mod cors;
210pub mod crypto;
211pub mod panic_abort;
212// Require pub module for macro export
213#[cfg(feature = "d1")]
214/// **Requires** `d1` feature.
215pub mod d1;
216mod date;
217mod delay;
218pub mod durable;
219mod dynamic_dispatch;
220mod env;
221mod error;
222mod fetcher;
223mod formdata;
224mod global;
225mod headers;
226mod http;
227mod hyperdrive;
228#[cfg(feature = "queue")]
229mod queue;
230mod r2;
231mod rate_limit;
232mod request;
233mod request_init;
234mod response;
235mod router;
236mod schedule;
237mod secret_store;
238pub mod send;
239mod socket;
240mod sql;
241mod streams;
242mod version;
243mod websocket;
244
245pub type Result<T> = StdResult<T, error::Error>;
246
247#[cfg(feature = "http")]
248/// **Requires** `http` feature. A convenience Body type which wraps [`web_sys::ReadableStream`](web_sys::ReadableStream)
249/// and implements [`http_body::Body`](http_body::Body)
250pub use http::body::Body;
251#[cfg(feature = "http")]
252pub use http::{
253    request::from_wasm as request_from_wasm, request::to_wasm as request_to_wasm,
254    response::from_wasm as response_from_wasm, response::to_wasm as response_to_wasm,
255};
256#[cfg(feature = "http")]
257/// **Requires** `http` feature. Type alias for `http::Request<worker::Body>`.
258pub type HttpRequest = ::http::Request<http::body::Body>;
259#[cfg(feature = "http")]
260/// **Requires** `http` feature. Type alias for `http::Response<worker::Body>`.
261pub type HttpResponse = ::http::Response<http::body::Body>;
262
263pub use crate::sql::*;