Added graphql endpoint and tested with tags implementation.

This commit is contained in:
2023-11-20 18:38:10 -08:00
parent 43e4334890
commit f52a76dba3
5 changed files with 461 additions and 37 deletions

View File

@@ -8,7 +8,6 @@ default-bin = "server"
[dependencies]
rocket = { version = "0.5.0-rc.2", features = [ "json" ] }
rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", branch = "master" }
notmuch = { path = "../notmuch" }
shared = { path = "../shared" }
serde_json = "1.0.87"
@@ -18,6 +17,9 @@ log = "0.4.17"
tokio = "1.26.0"
glog = "0.1.0"
urlencoding = "2.1.3"
async-graphql = "6.0.11"
async-graphql-rocket = "6.0.11"
rocket_cors = "0.6.0"
[dependencies.rocket_contrib]
version = "0.4.11"

View File

@@ -1,14 +1,24 @@
#[macro_use]
extern crate rocket;
use std::{error::Error, io::Cursor, str::FromStr};
use std::{
error::Error,
hash::{DefaultHasher, Hash, Hasher},
io::Cursor,
str::FromStr,
};
use async_graphql::{
http::GraphiQLSource, Context, EmptyMutation, EmptySubscription, FieldResult, Object, Schema,
SimpleObject,
};
use async_graphql_rocket::{GraphQLQuery, GraphQLRequest, GraphQLResponse};
use glog::Flags;
use notmuch::{Notmuch, NotmuchError, ThreadSet};
use rocket::{
http::{ContentType, Header},
request::Request,
response::{Debug, Responder},
response::{content, Debug, Responder},
serde::json::Json,
Response, State,
};
@@ -16,11 +26,6 @@ use rocket_cors::{AllowedHeaders, AllowedOrigins};
use server::{error::ServerError, nm::threadset_to_messages};
use shared::Message;
#[get("/")]
fn hello() -> &'static str {
"Hello, world!"
}
#[get("/refresh")]
async fn refresh(nm: &State<Notmuch>) -> Result<Json<String>, Debug<NotmuchError>> {
Ok(Json(String::from_utf8_lossy(&nm.new()?).to_string()))
@@ -125,6 +130,56 @@ async fn original(
Ok((ContentType::Plain, res))
}
#[rocket::get("/")]
fn graphiql() -> content::RawHtml<String> {
content::RawHtml(GraphiQLSource::build().endpoint("/graphql").finish())
}
#[rocket::get("/graphql?<query..>")]
async fn graphql_query(schema: &State<GraphqlSchema>, query: GraphQLQuery) -> GraphQLResponse {
query.execute(schema.inner()).await
}
#[rocket::post("/graphql", data = "<request>", format = "application/json")]
async fn graphql_request(
schema: &State<GraphqlSchema>,
request: GraphQLRequest,
) -> GraphQLResponse {
request.execute(schema.inner()).await
}
pub struct QueryRoot;
#[derive(SimpleObject)]
struct Tag {
name: String,
fg_color: String,
bg_color: String,
}
#[Object]
impl QueryRoot {
async fn tags<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult<Vec<Tag>> {
let nm = ctx.data_unchecked::<Notmuch>();
Ok(nm
.tags()?
.into_iter()
.map(|tag| {
let mut hasher = DefaultHasher::new();
tag.hash(&mut hasher);
let hex = format!("#{:06x}", hasher.finish() % (1 << 24));
Tag {
name: tag,
fg_color: "white".to_string(),
bg_color: hex,
}
})
.collect())
}
}
pub type GraphqlSchema = Schema<QueryRoot, EmptyMutation, EmptySubscription>;
#[rocket::main]
async fn main() -> Result<(), Box<dyn Error>> {
glog::new()
@@ -148,21 +203,28 @@ async fn main() -> Result<(), Box<dyn Error>> {
}
.to_cors()?;
let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
.data(Notmuch::default())
.finish();
let _ = rocket::build()
.mount(
"/",
routes![
original_part,
original,
hello,
refresh,
search_all,
search,
show_pretty,
show
show,
graphql_query,
graphql_request,
graphiql
],
)
.attach(cors)
.manage(schema)
.manage(Notmuch::default())
//.manage(Notmuch::with_config("../notmuch/testdata/notmuch.config"))
.launch()