Axum post request


Firstly I am very new to Rust so apologies for what is probably a simple question.

I am trying to set up a post route however am running into this error in

the trait bound `fn(Json<Contact>) -> impl Future<Output = Json<Value>> {create_contact_in_address_book}: Handler<_, _>` is not satisfied
the following other types implement trait `Handler<T, S>`:
  <Layered<L, H, T, S> as Handler<T, S>>
  <MethodRouter<S> as Handler<(), S>>

This is the app.router set up in

let app = Router::new()
    .route("/", get(fetch_data))
    .route("/dispense/products", get(get_products))
    .route("/dispense/barcodes", get(get_barcodes))
    .route("/dispense/products/inventory_pricing", get(get_products_inventory_pricing))
    .route("/edm/contacts", get(get_contacts_by_email_address))
    .route("/edm/contacts", post(create_contact_in_address_book))
    .layer(GovernorLayer {
      config: Box::leak(governor_config),

  axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await.unwrap(); // create the server.

This is the async function sitting in

pub async fn create_contact_in_address_book(Json(body): Json<Contact>) -> Json<Value> {
  // println!("Body: {:?}", body);

  match dotdigital_client().await {
    Ok(client) => {

      let body_value = serde_json::to_value(&body).expect("failed to serialise contact into Value");
      println!("Body Value: {:?}", body_value);

      match client.contacts().create_contact_in_address_book(body.address_book_id, &body_value).await {
        Ok(contact) => {
          println!("Contact: {:?}", contact);
        Err(e) => {
          println!("Error: {:?}", e);
          Json(json!({"error": "Failed to create contact"}));
      return Json(json!({"message": "Client created"}))
    Err(e) => {
      println!("Error: {:?}", e);
      return Json(json!({"error": "Failed to create client"}))

This is the post request inside the client in

 async fn post<T: serde::de::DeserializeOwned>(&self, url: &str, body: &Value) -> Result<T, Error> {
    let response =
      .basic_auth(&self.user, Some(&self.password)) // basic auth

    let result = response.json::<T>().await?;

and this is the actual request function inside

pub async fn create_contact_in_address_book(&self, address_book_id: String, body: &Value) -> Result<Value, Error> {
    let url = format!("{}/address-books/{}/contacts", self.client.base_url, address_book_id);, body).await

I have narrowed this down to something to do with the function create_contact_in_address_book and simple do a json return of { hello: world } this will work as seen below:

I have another method on the client which is a get, using the same logic and this endpoint will successfully return data.

I am extremely lost on why this is causing the error in the other than the return type of the handler doesn't "match" what Axum wants. Any pointers would be great or pointers on where to look so I can further break this down and understand why.

Thanks for your help!

Axum has a guide to Debugging handler type errors that might help.

Legend! Thank you for that. Didn't see that part in the docs.

Found out what was causing it - the one thing I didn't screenshot / copy across. The client on build could return "Box dyn Error" which doesn't match Axum IntoResponse

Rust is no longer cranky.

Appreciate you taking the time to help!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.