poem icon indicating copy to clipboard operation
poem copied to clipboard

How to define common parameters in OpenAPI spec?

Open banool opened this issue 2 years ago • 3 comments

Let's say I have code like this:

#[OpenApi]
    #[oai(
        path = "/accounts/:address",
        method = "get",
        operation_id = "get_account",
        tag = "ApiTags::General"
    )]
    async fn get_account(
        &self,
        accept: Accept,
        address: Path<AddressWrapper>,
    ) -> AptosResult<AccountData> {
        let accept_type = AcceptType::try_from(&accept)?;
        let address = address.0.try_into()?;
        let account = Account::new(self.context.clone(), address)?;
        account.account(&accept_type)
    }
}

#[derive(Debug, Clone, Eq, Hash, PartialEq, NewType)]
pub struct AddressWrapper(pub String);

impl TryInto<Address> for AddressWrapper {
    type Error = AptosErrorResponse;

    fn try_into(self) -> Result<Address, Self::Error> {
        parse_param::<Address>(self.0)
    }
}

fn parse_param<T: FromStr>(value: String) -> Result<T, AptosErrorResponse>
where
    T::Err: Display,
{
    T::from_str(&value).map_err(|e| {
        AptosErrorResponse::BadRequest(Json(AptosError::new(
            anyhow::format_err!("Given input was in an invalid format: {}: {}", value, e)
                .to_string(),
        )))
    })
}

The relevant part of the spec that this generates is:

paths:
  "/accounts/{address}":
    get:
      tags:
        - General
      summary: get_account
      description: Return high level information about an account such as its sequence number.
      parameters:
        - name: address
          schema:
            type: string
            description: "Hex-encoded 32 byte Aptos account address. This parameter is case insensitive and it does not matter if you prefix it with `0x` or not. See [here](https://aptos.dev/concepts/basics-accounts) for more details."
          in: path
          required: true
          deprecated: false

As you can see, the resulting spec has the parameter right there. Imagine I had 10 endpoints that took in this address parameter, there would be a lot of repetition. To address this, OpenAPI specs can have a section like this:

components:
  parameters:
    Address:
          schema:
            type: string
            description: "Hex-encoded 32 byte Aptos account address. This parameter is case insensitive and it does not matter if you prefix it with `0x` or not. See [here](https://aptos.dev/concepts/basics-accounts) for more details."
          in: path
          required: true
          deprecated: false

Is it possible to express this with Poem? I've been searching the code but can't find anything that generates this parameters section.

banool avatar Jul 18 '22 18:07 banool

This is not supported yet, but I can add it if you need it.

sunli829 avatar Jul 19 '22 01:07 sunli829

It's not critical but it would be a nice win, my spec is currently getting very long due to the repeating the same params with the same long descriptions every time.

banool avatar Jul 19 '22 01:07 banool

You are right, this is a low priority job.

sunli829 avatar Jul 19 '22 01:07 sunli829

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

github-actions[bot] avatar Aug 18 '22 03:08 github-actions[bot]

This issue was closed because it has been stalled for 5 days with no activity.

github-actions[bot] avatar Aug 23 '22 03:08 github-actions[bot]