* Use mdbook for building the book * Update book config * Update book hierarchy to work properly with mdbook This necessitated adding place-holder index pages since mdbook does not suppoert stand-alon menu items * Update tests to use 2018 edition * Fix various compilation errors in the tests
3 KiB
Integrating with Iron
Iron is a library that's been around for a while in the Rust sphere but lately hasn't seen much of development. Nevertheless, it's still a solid library with a familiar request/response/middleware architecture that works on Rust's stable channel.
Juniper's Iron integration is contained in the juniper_iron
crate:
!FILENAME Cargo.toml
[dependencies]
juniper = "0.10"
juniper_iron = "0.2.0"
Included in the source is a small example which sets up a basic GraphQL and GraphiQL handler.
Basic integration
Let's start with a minimal schema and just get a GraphQL endpoint up and
running. We use mount to attach the GraphQL handler at /graphql
.
The context_factory
function will be executed on every request and can be used
to set up database connections, read session token information from cookies, and
set up other global data that the schema might require.
In this example, we won't use any global data so we just return an empty value.
extern crate juniper;
extern crate juniper_iron;
extern crate iron;
extern crate mount;
use mount::Mount;
use iron::prelude::*;
use juniper::EmptyMutation;
use juniper_iron::GraphQLHandler;
fn context_factory(_: &mut Request) -> IronResult<()> {
Ok(())
}
struct Root;
graphql_object!(Root: () |&self| {
field foo() -> String {
"Bar".to_owned()
}
});
# #[allow(unreachable_code, unused_variables)]
fn main() {
let mut mount = Mount::new();
let graphql_endpoint = GraphQLHandler::new(
context_factory,
Root,
EmptyMutation::<()>::new(),
);
mount.mount("/graphql", graphql_endpoint);
let chain = Chain::new(mount);
# return;
Iron::new(chain).http("0.0.0.0:8080").unwrap();
}
Accessing data from the request
If you want to access e.g. the source IP address of the request from a field resolver, you need to pass this data using Juniper's context feature.
# extern crate juniper;
# extern crate juniper_iron;
# extern crate iron;
# use iron::prelude::*;
use std::net::SocketAddr;
struct Context {
remote_addr: SocketAddr,
}
impl juniper::Context for Context {}
fn context_factory(req: &mut Request) -> IronResult<Context> {
Ok(Context {
remote_addr: req.remote_addr
})
}
struct Root;
graphql_object!(Root: Context |&self| {
field my_addr(&executor) -> String {
let context = executor.context();
format!("Hello, you're coming from {}", context.remote_addr)
}
});
# fn main() {
# let _graphql_endpoint = juniper_iron::GraphQLHandler::new(
# context_factory,
# Root,
# juniper::EmptyMutation::<Context>::new(),
# );
# }
Accessing global data
FIXME: Show how the persistent
crate works with contexts using e.g. r2d2
.