> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shuttle.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Resources

> This example shows how you can make a custom Shuttle resource annotation.

This example shows how you can make a custom resource.

The example resource we'll be making will be a Plain Data Object (which we will refer to as `pdo`), and outputs the value that you pass into the "name" attribute for the resource.

We are using the Axum framework in `main.rs` so we can showcase the resource in action, but the implementation is entirely separate from what web framework you use so you can add your custom resource to any Shuttle-hosted resource.

You can clone the example below by running the following (you'll need `shuttle` CLI installed):

```bash theme={null}
shuttle init --from https://github.com/shuttle-hq/shuttle-examples --subfolder custom-resource/pdo
```

<CodeGroup>
  ```rust src/main.rs theme={null}
  use axum::{extract::State, routing::get, Router};
  use pdo::{Builder, Pdo};
  use std::sync::Arc;

  async fn hello_world(State(pdo): State<Arc<Pdo>>) -> String {
      pdo.name.clone()
  }

  #[shuttle_runtime::main]
  async fn axum(#[Builder(name = "John")] pdo: Pdo) -> shuttle_axum::ShuttleAxum {
      let state = Arc::new(pdo);
      let router = Router::new().route("/", get(hello_world)).with_state(state);

      Ok(router.into())
  }
  ```

  ```rust src/lib.rs theme={null}
  use async_trait::async_trait;
  use serde::Serialize;
  use shuttle_service::{resource::Type, Error, Factory, IntoResource, ResourceBuilder};

  #[derive(Default, Serialize)]
  pub struct Builder {
      name: String,
  }

  pub struct Pdo {
      pub name: String,
  }

  impl Builder {
      /// Name to give resource
      pub fn name(mut self, name: &str) -> Self {
          self.name = name.to_string();
          self
      }
  }

  #[async_trait]
  impl ResourceBuilder for Builder {
      const TYPE: Type = Type::Custom;
      type Config = Self;
      type Output = String;

      fn config(&self) -> &Self::Config {
          self
      }

      async fn output(self, _factory: &mut dyn Factory) -> Result<Self::Output, Error> {
          // factory can be used to get resources from Shuttle
          Ok(self.name)
      }
  }

  #[async_trait]
  impl IntoResource<Pdo> for String {
      async fn into_resource(self) -> Result<Pdo, Error> {
          Ok(Pdo { name: self })
      }
  }
  ```

  ```toml Cargo.toml theme={null}
  [package]
  name = "pdo"
  version = "0.1.0"
  edition = "2021"

  [dependencies]
  async-trait = "0.1.56"
  axum = "0.7.3"
  serde = { version = "1.0.148", default-features = false, features = ["derive"] }
  shuttle-service = "0.57.0"
  shuttle-axum = "0.57.0"
  shuttle-runtime = "0.57.0"
  tokio = "1.28.2"
  ```
</CodeGroup>
