graphql-rust / graphql-client

Typed, correct GraphQL requests and responses in Rust
Apache License 2.0
1.12k stars 152 forks source link

Using Enum in query #457

Open ToferC opened 10 months ago

ToferC commented 10 months ago

Hi folks. Love the work here and using it in a prototype for workforce analytics. I'm struggling to figure out how to use an Enum in a query and would love any guidance on how to get it running.

The API I'm hitting has this query:

capabilitiesByNameAndLevel(
name: String!
level: CapabilityLevel!
): [Capability!]!
Accepts a String "name" and a CapabilityLevel and returns matches against both

The enum is a simple:

enum CapabilityLevel {
DESIRED
NOVICE
EXPERIENCED
EXPERT
SPECIALIST
}

The challenge is that I'm getting the CapabilityLevel from a Webform as text, and I can't convert it into a CapabilityLevel to send to the query:

#[derive(GraphQLQuery, Serialize, Deserialize, Clone, Copy)]
#[graphql(
    schema_path = "schema.graphql",
    query_path = "queries/capabilities/capability_by_name_and_level.graphql",
    response_derives = "Debug, Serialize, PartialEq, Deserialize"
)]
pub struct CapabilityByNameAndLevel;

pub fn get_capability_by_name_and_level(name: String, level: String, bearer: String) -> Result<capability_by_name_and_level::ResponseData, Box<dyn Error>> {

    let request_body = CapabilityByNameAndLevel::build_query(capability_by_name_and_level::Variables {
        name,
        level: level,
    });

    let client = reqwest::blocking::Client::new();
    let res = client
        .post("http://127.0.0.1:8080/graphql")
        .header("Bearer", bearer)
        .json(&request_body)
        .send()?;

    let response_body: Response<capability_by_name_and_level::ResponseData> = res.json()?;

    if let Some(errors) = response_body.errors {
        println!("there are errors:");

        for error in &errors {
            println!("{:?}", error);
        }
    };

    let response = response_body.data
        .expect("missing response data");

    // serve HTML page with response_body
    Ok(response)
}

I've tried to use the Strum package, to create a helper enum and can't find a way to create the query in graphql_client. I could go back and change the API to not use enums... but that just seems wrong. I hope I'm just missing something here.

Thanks in advance for any help.

The API frontend is here: https://github.com/ToferC/epifront

GraphQL Query: https://github.com/ToferC/epifront/blob/main/queries/capabilities/capability_by_name_and_level.graphql

Function: https://github.com/ToferC/epifront/blob/main/src/graphql/capability.rs

And Handler: https://github.com/ToferC/epifront/blob/main/src/handlers/capability.rs

tomhoule commented 9 months ago

Yes that seems like a feature gap, thanks for reporting that. The first thing that comes to mind: we could generate Display and FromStr impls for the generated enum types.