oxidecomputer/dropshot

Allow `Query` to take an `Option<T>` type

zephraph opened this issue · 0 comments

In Oxide's V1 API we have endpoint definitions like the following

#[endpoint {
    method = GET,
    path = "/v1/disks/{disk}",
    tags = ["disks"]
}]
async fn disk_view(
    rqctx: RequestContext<Arc<ServerContext>>,
    path_params: Path<params::DiskPath>,
    query_params: Query<params::OptionalProjectSelector>,
) -> Result<HttpResponseOk<Disk>, HttpError> { ... }

Note that the query_params definition takes a params::OptionalProjectSelector. That OptionalProjectSelector is just a wrapper for ProjectSelector with an Option and #[serde(flatten)] in the definition. It's a whole lot of noise that could be avoided if Query<Option<params::ProjectSelector>> was valid. Unfortunately if we try that we get this gem

Optional query panic
process stderr:thread 'main' panicked at 'invalid type Object(
    SchemaObject {
        metadata: Some(
            Metadata {
                id: None,
                title: Some(
                    "Nullable_ProjectSelector",
                ),
                description: None,
                default: None,
                deprecated: false,
                read_only: false,
                write_only: false,
                examples: [],
            },
        ),
        instance_type: None,
        format: None,
        enum_values: None,
        const_value: None,
        subschemas: Some(
            SubschemaValidation {
                all_of: Some(
                    [
                        Object(
                            SchemaObject {
                                metadata: None,
                                instance_type: None,
                                format: None,
                                enum_values: None,
                                const_value: None,
                                subschemas: None,
                                number: None,
                                string: None,
                                array: None,
                                object: None,
                                reference: Some(
                                    "#/components/schemas/ProjectSelector",
                                ),
                                extensions: {},
                            },
                        ),
                    ],
                ),
                any_of: None,
                one_of: None,
                not: None,
                if_schema: None,
                then_schema: None,
                else_schema: None,
            },
        ),
        number: None,
        string: None,
        array: None,
        extensions: {
            "nullable": Bool(true),
        },
    },
)', /Users/just-be/.cargo/git/checkouts/dropshot-a4a923d29dccc492/ccce224/dropshot/src/schema_util.rs:134:20

This is somewhat related to #635 that that ultimately both Body and Query would be improved by taking Option types.