[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::context::Context;
171pub use crate::cors::Cors;
172#[cfg(feature = "d1")]
173pub use crate::d1::*;
174pub use crate::date::{Date, DateInit};
175pub use crate::delay::Delay;
176pub use crate::durable::*;
177pub use crate::dynamic_dispatch::*;
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::*;
186#[cfg(feature = "queue")]
187pub use crate::queue::*;
188pub use crate::r2::*;
189pub use crate::rate_limit::RateLimiter;
190pub use crate::request::{FromRequest, Request};
191pub use crate::request_init::*;
192pub use crate::response::{EncodeBody, IntoResponse, Response, ResponseBody, ResponseBuilder};
193pub use crate::router::{RouteContext, RouteParams, Router};
194pub use crate::schedule::*;
195pub use crate::secret_store::SecretStore;
196pub use crate::socket::*;
197pub use crate::streams::*;
198pub use crate::version::*;
199pub use crate::websocket::*;
200
201mod abort;
202mod ai;
203mod analytics_engine;
204mod cache;
205mod cf;
206mod context;
207mod cors;
208pub mod crypto;
209// Require pub module for macro export
210#[cfg(feature = "d1")]
211/// **Requires** `d1` feature.
212pub mod d1;
213mod date;
214mod delay;
215pub mod durable;
216mod dynamic_dispatch;
217mod env;
218mod error;
219mod fetcher;
220mod formdata;
221mod global;
222mod headers;
223mod http;
224mod hyperdrive;
225#[cfg(feature = "queue")]
226mod queue;
227mod r2;
228mod rate_limit;
229mod request;
230mod request_init;
231mod response;
232mod router;
233mod schedule;
234mod secret_store;
235pub mod send;
236mod socket;
237mod sql;
238mod streams;
239mod version;
240mod websocket;
241
242pub type Result<T> = StdResult<T, error::Error>;
243
244#[cfg(feature = "http")]
245/// **Requires** `http` feature. A convenience Body type which wraps [`web_sys::ReadableStream`](web_sys::ReadableStream)
246/// and implements [`http_body::Body`](http_body::Body)
247pub use http::body::Body;
248#[cfg(feature = "http")]
249pub use http::{
250    request::from_wasm as request_from_wasm, request::to_wasm as request_to_wasm,
251    response::from_wasm as response_from_wasm, response::to_wasm as response_to_wasm,
252};
253#[cfg(feature = "http")]
254/// **Requires** `http` feature. Type alias for `http::Request<worker::Body>`.
255pub type HttpRequest = ::http::Request<http::body::Body>;
256#[cfg(feature = "http")]
257/// **Requires** `http` feature. Type alias for `http::Response<worker::Body>`.
258pub type HttpResponse = ::http::Response<http::body::Body>;
259
260pub use crate::sql::*;