df_st_api 0.3.0-development-1

Starting an API server for the DF Storyteller project.
Documentation
use crate::DfStDatabase;
use df_st_db::{id_filter, string_filter, DBObject};
use juniper::RootNode;
use rocket::response::content;
use rocket::State;

/// GraphQL Context
pub struct Context {
    pub conn: DfStDatabase,
}
impl juniper::Context for Context {}
/// Schema for GraphQL
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>;

static ADD_NESTED_ITEMS: bool = true;

/// Struct for querying and searching for data using GraphQL
pub struct QueryRoot;

#[juniper::object(Context = Context)]
impl QueryRoot {
    fn regions(context: &Context, region_id: Option<i32>) -> Vec<df_st_core::Region> {
        let conn = &context.conn;
        if let Some(region_id) = region_id {
            let search_item = df_st_db::Region::get_from_db(
                &*conn,
                id_filter!["id" => region_id],
                ADD_NESTED_ITEMS,
            )
            .unwrap();
            if let Some(item) = search_item {
                return vec![item];
            }
            return vec![];
        } else {
            df_st_db::Region::get_list_from_db(
                &*conn,
                id_filter![],
                string_filter![],
                0,
                200,
                None,
                None,
                None,
                ADD_NESTED_ITEMS,
            )
            .unwrap()
        }
    }

    fn sites(context: &Context, site_id: Option<i32>) -> Vec<df_st_core::Site> {
        let conn = &context.conn;
        if let Some(site_id) = site_id {
            let search_item =
                df_st_db::Site::get_from_db(&*conn, id_filter!["id" => site_id], ADD_NESTED_ITEMS)
                    .unwrap();
            if let Some(item) = search_item {
                return vec![item];
            }
            return vec![];
        } else {
            df_st_db::Site::get_list_from_db(
                &*conn,
                id_filter![],
                string_filter![],
                0,
                200,
                None,
                None,
                None,
                ADD_NESTED_ITEMS,
            )
            .unwrap()
        }
    }

    fn structures(
        context: &Context,
        site_id: Option<i32>,
        structure_id: Option<i32>,
    ) -> Vec<df_st_core::Structure> {
        let conn = &context.conn;
        if let Some(site_id) = site_id {
            if let Some(structure_id) = structure_id {
                let search_item = df_st_db::Structure::get_from_db(
                    &*conn,
                    id_filter!["site_id" => site_id, "local_id" => structure_id],
                    ADD_NESTED_ITEMS,
                )
                .unwrap();
                if let Some(item) = search_item {
                    return vec![item];
                }
                return vec![];
            } else {
                df_st_db::Structure::get_list_from_db(
                    &*conn,
                    id_filter!["site_id" => site_id],
                    string_filter![],
                    0,
                    200,
                    None,
                    None,
                    None,
                    ADD_NESTED_ITEMS,
                )
                .unwrap()
            }
        } else {
            df_st_db::Structure::get_list_from_db(
                &*conn,
                id_filter![],
                string_filter![],
                0,
                200,
                None,
                None,
                None,
                ADD_NESTED_ITEMS,
            )
            .unwrap()
        }
    }

    fn site_properties(
        context: &Context,
        site_id: Option<i32>,
        site_property_id: Option<i32>,
    ) -> Vec<df_st_core::SiteProperty> {
        let conn = &context.conn;
        if let Some(site_id) = site_id {
            if let Some(site_property_id) = site_property_id {
                let search_item = df_st_db::SiteProperty::get_from_db(
                    &*conn,
                    id_filter!["site_id" => site_id, "local_id" => site_property_id],
                    ADD_NESTED_ITEMS,
                )
                .unwrap();
                if let Some(item) = search_item {
                    return vec![item];
                }
                return vec![];
            } else {
                df_st_db::SiteProperty::get_list_from_db(
                    &*conn,
                    id_filter!["site_id" => site_id],
                    string_filter![],
                    0,
                    200,
                    None,
                    None,
                    None,
                    ADD_NESTED_ITEMS,
                )
                .unwrap()
            }
        } else {
            df_st_db::SiteProperty::get_list_from_db(
                &*conn,
                id_filter![],
                string_filter![],
                0,
                200,
                None,
                None,
                None,
                ADD_NESTED_ITEMS,
            )
            .unwrap()
        }
    }
}

/// Struct for adding and modifiable data using GraphQL
pub struct MutationRoot;
#[juniper::object(Context = Context)]
impl MutationRoot {}

/// Open a GraphiQL page for testing GraphQL syntax
#[rocket::get("/")]
pub fn graphiql() -> content::Html<String> {
    juniper_rocket::graphiql_source("/graphql/graphql")
}

/// Open a GraphQL Playground page for testing GraphQL syntax
#[rocket::get("/play")]
pub fn graphiql_playground() -> content::Html<String> {
    juniper_rocket::playground_source("/graphql/graphql")
}

/// Get GraphQL request using GET method
#[rocket::get("/graphql?<request>")]
pub fn get_graphql_handler(
    conn: DfStDatabase,
    request: juniper_rocket::GraphQLRequest,
    schema: State<Schema>,
) -> juniper_rocket::GraphQLResponse {
    let context = Context { conn };
    request.execute(&schema, &context)
}

/// Get GraphQL request using POST method
#[rocket::post("/graphql", data = "<request>")]
pub fn post_graphql_handler(
    conn: DfStDatabase,
    request: juniper_rocket::GraphQLRequest,
    schema: State<Schema>,
) -> juniper_rocket::GraphQLResponse {
    let context = Context { conn };
    request.execute(&schema, &context)
}