mirror of
https://github.com/actix/actix-extras.git
synced 2024-12-01 02:44:37 +01:00
commit
2f3a2115c0
@ -99,6 +99,7 @@ codegen-units = 1
|
|||||||
members = [
|
members = [
|
||||||
"./",
|
"./",
|
||||||
"examples/basics",
|
"examples/basics",
|
||||||
|
"examples/juniper",
|
||||||
"examples/diesel",
|
"examples/diesel",
|
||||||
"examples/r2d2",
|
"examples/r2d2",
|
||||||
"examples/json",
|
"examples/json",
|
||||||
|
17
examples/juniper/Cargo.toml
Normal file
17
examples/juniper/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "juniper-example"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["pyros2097 <pyros2097@gmail.com>"]
|
||||||
|
workspace = "../.."
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
env_logger = "0.5"
|
||||||
|
actix = "0.5"
|
||||||
|
actix-web = { path = "../../" }
|
||||||
|
|
||||||
|
futures = "0.1"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde_derive = "1.0"
|
||||||
|
|
||||||
|
juniper = "0.9.2"
|
15
examples/juniper/README.md
Normal file
15
examples/juniper/README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# juniper
|
||||||
|
|
||||||
|
Juniper integration for Actix web
|
||||||
|
|
||||||
|
### server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd actix-web/examples/juniper
|
||||||
|
cargo run (or ``cargo watch -x run``)
|
||||||
|
# Started http server: 127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### web client
|
||||||
|
|
||||||
|
[http://127.0.0.1:8080/graphiql](http://127.0.0.1:8080/graphiql)
|
110
examples/juniper/src/main.rs
Normal file
110
examples/juniper/src/main.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
//! Actix web juniper example
|
||||||
|
//!
|
||||||
|
//! A simple example integrating juniper in actix-web
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate juniper;
|
||||||
|
extern crate futures;
|
||||||
|
extern crate actix;
|
||||||
|
extern crate actix_web;
|
||||||
|
extern crate env_logger;
|
||||||
|
|
||||||
|
use actix::*;
|
||||||
|
use actix_web::*;
|
||||||
|
use juniper::http::graphiql::graphiql_source;
|
||||||
|
use juniper::http::GraphQLRequest;
|
||||||
|
|
||||||
|
use futures::future::Future;
|
||||||
|
|
||||||
|
mod schema;
|
||||||
|
|
||||||
|
use schema::Schema;
|
||||||
|
use schema::create_schema;
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
executor: Addr<Syn, GraphQLExecutor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct GraphQLData(GraphQLRequest);
|
||||||
|
|
||||||
|
impl Message for GraphQLData {
|
||||||
|
type Result = Result<String, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GraphQLExecutor {
|
||||||
|
schema: std::sync::Arc<Schema>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GraphQLExecutor {
|
||||||
|
fn new(schema: std::sync::Arc<Schema>) -> GraphQLExecutor {
|
||||||
|
GraphQLExecutor {
|
||||||
|
schema: schema,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for GraphQLExecutor {
|
||||||
|
type Context = SyncContext<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler<GraphQLData> for GraphQLExecutor {
|
||||||
|
type Result = Result<String, Error>;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: GraphQLData, _: &mut Self::Context) -> Self::Result {
|
||||||
|
let res = msg.0.execute(&self.schema, &());
|
||||||
|
let res_text = serde_json::to_string(&res)?;
|
||||||
|
Ok(res_text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn graphiql(_req: HttpRequest<State>) -> Result<HttpResponse> {
|
||||||
|
let html = graphiql_source("http://localhost:8080/graphql");
|
||||||
|
Ok(HttpResponse::build(StatusCode::OK)
|
||||||
|
.content_type("text/html; charset=utf-8")
|
||||||
|
.body(html).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn graphql(req: HttpRequest<State>) -> Box<Future<Item=HttpResponse, Error=Error>> {
|
||||||
|
let executor = req.state().executor.clone();
|
||||||
|
req.json()
|
||||||
|
.from_err()
|
||||||
|
.and_then(move |val: GraphQLData| {
|
||||||
|
executor.send(val)
|
||||||
|
.from_err()
|
||||||
|
.and_then(|res| {
|
||||||
|
match res {
|
||||||
|
Ok(user) => Ok(httpcodes::HTTPOk.build().body(user)?),
|
||||||
|
Err(_) => Ok(httpcodes::HTTPInternalServerError.into())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.responder()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
::std::env::set_var("RUST_LOG", "actix_web=info");
|
||||||
|
let _ = env_logger::init();
|
||||||
|
let sys = actix::System::new("juniper-example");
|
||||||
|
|
||||||
|
let schema = std::sync::Arc::new(create_schema());
|
||||||
|
let addr = SyncArbiter::start(3, move || {
|
||||||
|
GraphQLExecutor::new(schema.clone())
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start http server
|
||||||
|
let _addr = HttpServer::new(move || {
|
||||||
|
Application::with_state(State{executor: addr.clone()})
|
||||||
|
// enable logger
|
||||||
|
.middleware(middleware::Logger::default())
|
||||||
|
.resource("/graphql", |r| r.method(Method::POST).a(graphql))
|
||||||
|
.resource("/graphiql", |r| r.method(Method::GET).f(graphiql))})
|
||||||
|
.bind("127.0.0.1:8080").unwrap()
|
||||||
|
.start();
|
||||||
|
|
||||||
|
println!("Started http server: 127.0.0.1:8080");
|
||||||
|
let _ = sys.run();
|
||||||
|
}
|
58
examples/juniper/src/schema.rs
Normal file
58
examples/juniper/src/schema.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use juniper::FieldResult;
|
||||||
|
use juniper::RootNode;
|
||||||
|
|
||||||
|
#[derive(GraphQLEnum)]
|
||||||
|
enum Episode {
|
||||||
|
NewHope,
|
||||||
|
Empire,
|
||||||
|
Jedi,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(GraphQLObject)]
|
||||||
|
#[graphql(description = "A humanoid creature in the Star Wars universe")]
|
||||||
|
struct Human {
|
||||||
|
id: String,
|
||||||
|
name: String,
|
||||||
|
appears_in: Vec<Episode>,
|
||||||
|
home_planet: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(GraphQLInputObject)]
|
||||||
|
#[graphql(description = "A humanoid creature in the Star Wars universe")]
|
||||||
|
struct NewHuman {
|
||||||
|
name: String,
|
||||||
|
appears_in: Vec<Episode>,
|
||||||
|
home_planet: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct QueryRoot;
|
||||||
|
|
||||||
|
graphql_object!(QueryRoot: () |&self| {
|
||||||
|
field human(&executor, id: String) -> FieldResult<Human> {
|
||||||
|
Ok(Human{
|
||||||
|
id: "1234".to_owned(),
|
||||||
|
name: "Luke".to_owned(),
|
||||||
|
appears_in: vec![Episode::NewHope],
|
||||||
|
home_planet: "Mars".to_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pub struct MutationRoot;
|
||||||
|
|
||||||
|
graphql_object!(MutationRoot: () |&self| {
|
||||||
|
field createHuman(&executor, new_human: NewHuman) -> FieldResult<Human> {
|
||||||
|
Ok(Human{
|
||||||
|
id: "1234".to_owned(),
|
||||||
|
name: new_human.name,
|
||||||
|
appears_in: new_human.appears_in,
|
||||||
|
home_planet: new_human.home_planet,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>;
|
||||||
|
|
||||||
|
pub fn create_schema() -> Schema {
|
||||||
|
Schema::new(QueryRoot {}, MutationRoot {})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user