How the Worker, or one Durable Object, talks to a Durable Object: a JSON message posted to it, and a JSON message back.
Posts ask to the object called name behind binding. what names the
object in an error.
10pub async fn tell<A: Serialize, T: DeserializeOwned>( 11 env: &Env, 12 binding: &str, 13 name: &str, 14 what: &str, 15 ask: &A, 16) -> Result<T, String> { 17 let unreachable = |e: worker::Error| format!("{what}: {e}"); 18 let namespace = env.durable_object(binding).map_err(unreachable)?; 19 let stub = namespace.id_from_name(name).and_then(|id| id.get_stub()).map_err(unreachable)?; 20 let body = serde_json::to_string(ask).map_err(|e| format!("{what}: {e}"))?; 21 let mut init = RequestInit::new(); 22 init.with_method(Method::Post).with_body(Some(body.into())); 23 // The host is never resolved: a stub's fetch goes to its object. 24 let request = Request::new_with_init("https://object/", &init).map_err(unreachable)?; 25 let mut response = stub.fetch_with_request(request).await.map_err(unreachable)?; 26 let text = response.text().await.map_err(unreachable)?; 27 serde_json::from_str(&text).map_err(|e| format!("{what}: {e}")) 28}