2022-03-04 10:32:21 -06:00
<!DOCTYPE HTML>
2023-10-06 14:41:48 -05:00
< html lang = "en" class = "light" dir = "ltr" >
2022-03-04 10:32:21 -06:00
< head >
<!-- Book generated using mdBook -->
< meta charset = "UTF-8" >
2022-04-12 11:26:39 -05:00
< title > Iron - Juniper Book (GraphQL server for Rust)< / title >
2023-02-27 13:27:31 -06:00
2022-04-12 11:26:39 -05:00
<!-- Custom HTML head -->
2023-02-27 13:27:31 -06:00
2022-04-12 11:26:39 -05:00
< meta name = "description" content = "User guide for Juniper (GraphQL server library for Rust)." >
2022-03-04 10:32:21 -06:00
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
2023-10-06 14:41:48 -05:00
< meta name = "theme-color" content = "#ffffff" >
2022-03-04 10:32:21 -06:00
2022-04-12 11:26:39 -05:00
< link rel = "icon" href = "../favicon.svg" >
2022-03-04 10:32:21 -06:00
< link rel = "shortcut icon" href = "../favicon.png" >
< link rel = "stylesheet" href = "../css/variables.css" >
< link rel = "stylesheet" href = "../css/general.css" >
< link rel = "stylesheet" href = "../css/chrome.css" >
< link rel = "stylesheet" href = "../css/print.css" media = "print" >
2023-02-27 13:27:31 -06:00
2022-03-04 10:32:21 -06:00
<!-- Fonts -->
< link rel = "stylesheet" href = "../FontAwesome/css/font-awesome.css" >
2022-04-12 11:26:39 -05:00
< link rel = "stylesheet" href = "../fonts/fonts.css" >
2023-02-27 13:27:31 -06:00
2022-03-04 10:32:21 -06:00
<!-- Highlight.js Stylesheets -->
< link rel = "stylesheet" href = "../highlight.css" >
< link rel = "stylesheet" href = "../tomorrow-night.css" >
< link rel = "stylesheet" href = "../ayu-highlight.css" >
<!-- Custom theme stylesheets -->
2023-02-27 13:27:31 -06:00
2022-03-04 10:32:21 -06:00
< / head >
2023-10-06 14:41:48 -05:00
< body class = "sidebar-visible no-js" >
2023-02-27 13:27:31 -06:00
< div id = "body-container" >
2022-03-04 10:32:21 -06:00
<!-- Provide site root to javascript -->
2023-02-27 13:27:31 -06:00
< script >
2022-04-12 11:26:39 -05:00
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
< / script >
2022-03-04 10:32:21 -06:00
<!-- Work around some values being stored in localStorage wrapped in quotes -->
2023-02-27 13:27:31 -06:00
< script >
2022-03-04 10:32:21 -06:00
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') & & theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') & & sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
< / script >
<!-- Set the theme before any content is loaded, prevents flash -->
2023-02-27 13:27:31 -06:00
< script >
2022-03-04 10:32:21 -06:00
var theme;
2022-04-12 11:26:39 -05:00
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('light')
html.classList.add(theme);
2023-10-06 14:41:48 -05:00
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
2022-03-04 10:32:21 -06:00
< / script >
2023-10-06 14:41:48 -05:00
< input type = "checkbox" id = "sidebar-toggle-anchor" class = "hidden" >
2022-03-04 10:32:21 -06:00
<!-- Hide / unhide sidebar before it is displayed -->
2023-02-27 13:27:31 -06:00
< script >
2023-10-06 14:41:48 -05:00
var body = document.querySelector('body');
2023-04-04 07:07:31 -05:00
var sidebar = null;
2023-10-06 14:41:48 -05:00
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
2022-03-04 10:32:21 -06:00
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
2023-04-04 07:07:31 -05:00
} else {
sidebar = 'hidden';
2022-03-04 10:32:21 -06:00
}
2023-10-06 14:41:48 -05:00
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
2022-03-04 10:32:21 -06:00
< / script >
< nav id = "sidebar" class = "sidebar" aria-label = "Table of contents" >
2022-04-12 11:26:39 -05:00
< div class = "sidebar-scrollbox" >
< ol class = "chapter" > < li class = "chapter-item expanded " > < a href = "../index.html" > < strong aria-hidden = "true" > 1.< / strong > Introduction< / a > < / li > < li class = "chapter-item expanded " > < a href = "../quickstart.html" > < strong aria-hidden = "true" > 2.< / strong > Quickstart< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/index.html" > < strong aria-hidden = "true" > 3.< / strong > Type System< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../types/objects/defining_objects.html" > < strong aria-hidden = "true" > 3.1.< / strong > Defining objects< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../types/objects/complex_fields.html" > < strong aria-hidden = "true" > 3.1.1.< / strong > Complex fields< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/objects/using_contexts.html" > < strong aria-hidden = "true" > 3.1.2.< / strong > Using contexts< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/objects/error_handling.html" > < strong aria-hidden = "true" > 3.1.3.< / strong > Error handling< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../types/other-index.html" > < strong aria-hidden = "true" > 3.2.< / strong > Other types< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../types/enums.html" > < strong aria-hidden = "true" > 3.2.1.< / strong > Enums< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/interfaces.html" > < strong aria-hidden = "true" > 3.2.2.< / strong > Interfaces< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/input_objects.html" > < strong aria-hidden = "true" > 3.2.3.< / strong > Input objects< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/scalars.html" > < strong aria-hidden = "true" > 3.2.4.< / strong > Scalars< / a > < / li > < li class = "chapter-item expanded " > < a href = "../types/unions.html" > < strong aria-hidden = "true" > 3.2.5.< / strong > Unions< / a > < / li > < / ol > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../schema/schemas_and_mutations.html" > < strong aria-hidden = "true" > 4.< / strong > Schemas and mutations< / a > < / li > < li class = "chapter-item expanded " > < a href = "../servers/index.html" > < strong aria-hidden = "true" > 5.< / strong > Adding A Server< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../servers/official.html" > < strong aria-hidden = "true" > 5.1.< / strong > Official Server Integrations< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../servers/warp.html" > < strong aria-hidden = "true" > 5.1.1.< / strong > Warp< / a > < / li > < li class = "chapter-item expanded " > < a href = "../servers/rocket.html" > < strong aria-hidden = "true" > 5.1.2.< / strong > Rocket< / a > < / li > < li class = "chapter-item expanded " > < a href = "../servers/iron.html" class = "active" > < strong aria-hidden = "true" > 5.1.3.< / strong > Iron< / a > < / li > < li class = "chapter-item expanded " > < a href = "../servers/hyper.html" > < strong aria-hidden = "true" > 5.1.4.< / strong > Hyper< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../servers/third-party.html" > < strong aria-hidden = "true" > 5.2.< / strong > Third Party Integrations< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../advanced/index.html" > < strong aria-hidden = "true" > 6.< / strong > Advanced Topics< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../advanced/introspection.html" > < strong aria-hidden = "true" > 6.1.< / strong > Introspection< / a > < / li > < li class = "chapter-item expanded " > < a href = "../advanced/non_struct_objects.html" > < strong aria-hidden = "true" > 6.2.< / strong > Non-struct objects< / a > < / li > < li class = "chapter-item expanded " > < a href = "../advanced/implicit_and_explicit_null.html" > < strong aria-hidden = "true" > 6.3.< / strong > Implicit and explicit null< / a > < / li > < li class = "chapter-item expanded " > < a href = "../advanced/objects_and_generics.html" > < strong aria-hidden = "true" > 6.4.< / strong > Objects and generics< / a > < / li > < li class = "chapter-item expanded " > < a href = "../advanced/multiple_ops_per_request.html" > < strong aria-hidden = "true" > 6.5.< / strong > Multiple operations per request< / a > < / li > < li class = "chapter-item expanded " > < a href = "../advanced/dataloaders.html" > < strong aria-hidden = "true" > 6.6.< / strong > Dataloaders< / a > < / li > < li cla
< / div >
< div id = "sidebar-resize-handle" class = "sidebar-resize-handle" > < / div >
2022-03-04 10:32:21 -06:00
< / nav >
2023-07-07 07:41:41 -05:00
<!-- Track and set sidebar scroll position -->
< script >
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
< / script >
2022-03-04 10:32:21 -06:00
< div id = "page-wrapper" class = "page-wrapper" >
< div class = "page" >
2023-02-27 13:27:31 -06:00
< div id = "menu-bar-hover-placeholder" > < / div >
2023-07-07 07:41:41 -05:00
< div id = "menu-bar" class = "menu-bar sticky" >
2022-04-12 11:26:39 -05:00
< div class = "left-buttons" >
2023-10-06 14:41:48 -05:00
< label id = "sidebar-toggle" class = "icon-button" for = "sidebar-toggle-anchor" title = "Toggle Table of Contents" aria-label = "Toggle Table of Contents" aria-controls = "sidebar" >
2022-04-12 11:26:39 -05:00
< i class = "fa fa-bars" > < / i >
2023-10-06 14:41:48 -05:00
< / label >
2022-04-12 11:26:39 -05:00
< button id = "theme-toggle" class = "icon-button" type = "button" title = "Change theme" aria-label = "Change theme" aria-haspopup = "true" aria-expanded = "false" aria-controls = "theme-list" >
< i class = "fa fa-paint-brush" > < / i >
< / button >
< ul id = "theme-list" class = "theme-popup" aria-label = "Themes" role = "menu" >
2023-02-27 13:27:31 -06:00
< li role = "none" > < button role = "menuitem" class = "theme" id = "light" > Light< / button > < / li >
2022-04-12 11:26:39 -05:00
< li role = "none" > < button role = "menuitem" class = "theme" id = "rust" > Rust< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "coal" > Coal< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "navy" > Navy< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "ayu" > Ayu< / button > < / li >
< / ul >
< button id = "search-toggle" class = "icon-button" type = "button" title = "Search. (Shortkey: s)" aria-label = "Toggle Searchbar" aria-expanded = "false" aria-keyshortcuts = "S" aria-controls = "searchbar" >
< i class = "fa fa-search" > < / i >
< / button >
< / div >
< h1 class = "menu-title" > Juniper Book (GraphQL server for Rust)< / h1 >
< div class = "right-buttons" >
< a href = "../print.html" title = "Print this book" aria-label = "Print this book" >
< i id = "print-button" class = "fa fa-print" > < / i >
< / a >
2023-02-27 13:27:31 -06:00
2022-03-04 10:32:21 -06:00
< / div >
< / div >
< div id = "search-wrapper" class = "hidden" >
< form id = "searchbar-outer" class = "searchbar-outer" >
2022-04-12 11:26:39 -05:00
< input type = "search" id = "searchbar" name = "searchbar" placeholder = "Search this book ..." aria-controls = "searchresults-outer" aria-describedby = "searchresults-header" >
2022-03-04 10:32:21 -06:00
< / form >
< div id = "searchresults-outer" class = "searchresults-outer hidden" >
< div id = "searchresults-header" class = "searchresults-header" > < / div >
< ul id = "searchresults" >
< / ul >
< / div >
< / div >
2023-02-27 13:27:31 -06:00
2022-03-04 10:32:21 -06:00
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
2023-02-27 13:27:31 -06:00
< script >
2022-03-04 10:32:21 -06:00
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
< / script >
< div id = "content" class = "content" >
< main >
2022-04-12 11:26:39 -05:00
< h1 id = "integrating-with-iron" > < a class = "header" href = "#integrating-with-iron" > Integrating with Iron< / a > < / h1 >
2022-03-04 10:32:21 -06:00
< p > < a href = "https://github.com/iron/iron" > Iron< / a > 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.< / p >
< p > Juniper's Iron integration is contained in the < code > juniper_iron< / code > crate:< / p >
< p > !FILENAME Cargo.toml< / p >
< pre > < code class = "language-toml" > [dependencies]
2022-04-12 11:26:39 -05:00
juniper = " 0.16.0"
juniper_iron = " 0.8.0"
2022-03-04 10:32:21 -06:00
< / code > < / pre >
< p > Included in the source is a < a href = "https://github.com/graphql-rust/juniper_iron/blob/master/examples/iron_server.rs" > small
example< / a >
which sets up a basic GraphQL and < a href = "https://github.com/graphql/graphiql" > GraphiQL< / a > handler.< / p >
2022-04-12 11:26:39 -05:00
< h2 id = "basic-integration" > < a class = "header" href = "#basic-integration" > Basic integration< / a > < / h2 >
2022-03-04 10:32:21 -06:00
< p > Let's start with a minimal schema and just get a GraphQL endpoint up and
running. We use < a href = "https://github.com/iron/mount" > mount< / a > to attach the GraphQL handler at < code > /graphql< / code > .< / p >
< p > The < code > context_factory< / code > 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.< / p >
< p > In this example, we won't use any global data so we just return an empty value.< / p >
< pre > < code class = "language-rust ignore" > 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;
#[juniper::graphql_object]
impl Root {
fn foo() -> String {
2022-07-13 09:04:13 -05:00
" Bar" .into()
2022-03-04 10:32:21 -06:00
}
}
2022-04-12 11:26:39 -05:00
< span class = "boring" > #[allow(unreachable_code, unused_variables)]
< / span > fn main() {
2022-03-04 10:32:21 -06:00
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);
2022-04-12 11:26:39 -05:00
< span class = "boring" > return;
< / span > Iron::new(chain).http(" 0.0.0.0:8080" ).unwrap();
2023-02-27 13:27:31 -06:00
}< / code > < / pre >
2022-04-12 11:26:39 -05:00
< h2 id = "accessing-data-from-the-request" > < a class = "header" href = "#accessing-data-from-the-request" > Accessing data from the request< / a > < / h2 >
2022-03-04 10:32:21 -06:00
< p > 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 < a href = "../types/objects/using_contexts.html" > context feature< / a > .< / p >
2022-04-12 11:26:39 -05:00
< pre > < code class = "language-rust ignore" > < span class = "boring" > extern crate juniper;
< / span > < span class = "boring" > extern crate juniper_iron;
< / span > < span class = "boring" > extern crate iron;
< / span > < span class = "boring" > use iron::prelude::*;
< / span > use std::net::SocketAddr;
2022-03-04 10:32:21 -06:00
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;
#[juniper::graphql_object(
Context = Context,
)]
impl Root {
field my_addr(context: & Context) -> String {
format!(" Hello, you're coming from {}" , context.remote_addr)
}
}
2022-04-12 11:26:39 -05:00
< span class = "boring" > fn main() {
< / span > < span class = "boring" > let _graphql_endpoint = juniper_iron::GraphQLHandler::new(
< / span > < span class = "boring" > context_factory,
< / span > < span class = "boring" > Root,
< / span > < span class = "boring" > juniper::EmptyMutation::< Context> ::new(),
< / span > < span class = "boring" > );
2023-02-27 13:27:31 -06:00
< / span > < span class = "boring" > }< / span > < / code > < / pre >
2022-03-04 10:32:21 -06:00
< / main >
< nav class = "nav-wrapper" aria-label = "Page navigation" >
<!-- Mobile navigation buttons -->
< a rel = "prev" href = "../servers/rocket.html" class = "mobile-nav-chapters previous" title = "Previous chapter" aria-label = "Previous chapter" aria-keyshortcuts = "Left" >
< i class = "fa fa-angle-left" > < / i >
< / a >
2023-02-27 13:27:31 -06:00
2023-10-06 14:41:48 -05:00
< a rel = "next prefetch" href = "../servers/hyper.html" class = "mobile-nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
2022-03-04 10:32:21 -06:00
< i class = "fa fa-angle-right" > < / i >
< / a >
2023-02-27 13:27:31 -06:00
2022-03-04 10:32:21 -06:00
< div style = "clear: both" > < / div >
< / nav >
< / div >
< / div >
< nav class = "nav-wide-wrapper" aria-label = "Page navigation" >
2022-04-12 11:26:39 -05:00
< a rel = "prev" href = "../servers/rocket.html" class = "nav-chapters previous" title = "Previous chapter" aria-label = "Previous chapter" aria-keyshortcuts = "Left" >
2022-03-04 10:32:21 -06:00
< i class = "fa fa-angle-left" > < / i >
< / a >
2023-02-27 13:27:31 -06:00
2023-10-06 14:41:48 -05:00
< a rel = "next prefetch" href = "../servers/hyper.html" class = "nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
2022-03-04 10:32:21 -06:00
< i class = "fa fa-angle-right" > < / i >
< / a >
< / nav >
< / div >
2023-02-27 13:27:31 -06:00
< script >
2022-04-12 11:26:39 -05:00
window.playground_copyable = true;
< / script >
2023-02-27 13:27:31 -06:00
< script src = "../elasticlunr.min.js" > < / script >
< script src = "../mark.min.js" > < / script >
< script src = "../searcher.js" > < / script >
< script src = "../clipboard.min.js" > < / script >
< script src = "../highlight.js" > < / script >
< script src = "../book.js" > < / script >
2022-03-04 10:32:21 -06:00
<!-- Custom JS scripts -->
2023-02-27 13:27:31 -06:00
< / div >
2022-03-04 10:32:21 -06:00
< / body >
< / html >