<labelid="sidebar-toggle"class="icon-button"for="sidebar-toggle-anchor"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="../print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p><strong><ahref="https://docs.rs/juniper">Juniper</a> follows a <ahref="https://www.apollographql.com/blog/backend/architecture/schema-first-vs-code-only-graphql#code-only">code-first</a> approach to define a <ahref="https://graphql.org">GraphQL</a> schema.</strong></p>
<blockquote>
<p><strong>TIP</strong>: For a <ahref="https://www.apollographql.com/blog/backend/architecture/schema-first-vs-code-only-graphql#schema-first">schema-first</a> approach, consider using a <ahref="https://docs.rs/juniper-from-schema"><code>juniper-from-schema</code></a> crate for generating a <ahref="https://docs.rs/juniper"><code>juniper</code></a>-based code from a <ahref="https://graphql.org/learn/schema">schema</a> file.</p>
</blockquote>
<p><ahref="https://spec.graphql.org/October2021#sec-Schema">GraphQL schema</a> consists of three <ahref="https://spec.graphql.org/October2021#sec-Objects">object types</a>: a <ahref="https://spec.graphql.org/October2021#sel-FAHTRFCAACChCtpG">query root</a>, a <ahref="https://spec.graphql.org/October2021#sel-FAHTRHCAACCuE9yD">mutation root</a>, and a <ahref="https://spec.graphql.org/October2021#sel-FAHTRJCAACC3EhsX">subscription root</a>.</p>
<blockquote>
<p>The <strong>query</strong> root operation type must be provided and must be an <ahref="https://spec.graphql.org/October2021#sec-Objects">Object</a> type.</p>
<p>The <strong>mutation</strong> root operation type is optional; if it is not provided, the service does not support mutations. If it is provided, it must be an <ahref="https://spec.graphql.org/October2021#sec-Objects">Object</a> type.</p>
<p>Similarly, the <strong>subscription</strong> root operation type is also optional; if it is not provided, the service does not support subscriptions. If it is provided, it must be an <ahref="https://spec.graphql.org/October2021#sec-Objects">Object</a> type.</p>
<p>The <strong>query</strong>, <strong>mutation</strong>, and <strong>subscription</strong> root types must all be different types if provided.</p>
<p>In <ahref="https://docs.rs/juniper">Juniper</a>, the <ahref="https://docs.rs/juniper/0.16.1/juniper/struct.RootNode.html"><code>RootNode</code></a> type represents a <ahref="https://spec.graphql.org/October2021#sec-Schema">schema</a>. When the <ahref="https://spec.graphql.org/October2021#sec-Schema">schema</a> is first created, <ahref="https://docs.rs/juniper">Juniper</a> will traverse the entire object graph and register all types it can find. This means that if we <ahref="../types/objects/index.html">define a GraphQL object</a> somewhere but never use or reference it, it won't be exposed in a <ahref="https://spec.graphql.org/October2021#sec-Schema">GraphQL schema</a>.</p>
<p>Both <ahref="https://spec.graphql.org/October2021#sel-FAHTRFCAACChCtpG">query</a> and <ahref="https://spec.graphql.org/October2021#sel-FAHTRHCAACCuE9yD">mutation</a> objects are regular <ahref="https://spec.graphql.org/October2021#sec-Objects">GraphQL objects</a>, defined like <ahref="../types/objects/index.html">any other object in Juniper</a>. The <ahref="https://spec.graphql.org/October2021#sel-FAHTRHCAACCuE9yD">mutation</a> and <ahref="https://spec.graphql.org/October2021#sel-FAHTRJCAACC3EhsX">subscription</a> objects, however, are optional, since <ahref="https://spec.graphql.org/October2021#sec-Schema">schemas</a> can be read-only and do not require <ahref="https://spec.graphql.org/October2021#sel-FAHTRJCAACC3EhsX">subscriptions</a>.</p>
<p><strong>TIP</strong>: If <ahref="https://spec.graphql.org/October2021#sel-FAHTRHCAACCuE9yD">mutation</a>/<ahref="https://spec.graphql.org/October2021#sel-FAHTRJCAACC3EhsX">subscription</a> functionality is not needed, consider using the predefined <ahref="https://docs.rs/juniper/0.16.1/juniper/struct.EmptyMutation.html"><code>EmptyMutation</code></a>/<ahref="https://docs.rs/juniper/0.16.1/juniper/struct.EmptySubscription.html"><code>EmptySubscription</code></a> types for stubbing them in a <ahref="https://docs.rs/juniper/0.16.1/juniper/struct.RootNode.html"><code>RootNode</code></a>.</p>
<p><strong>NOTE</strong>: It's considered a <ahref="https://spec.graphql.org/October2021#sec-Root-Operation-Types.Default-Root-Operation-Type-Names">good practice</a> to name <ahref="https://spec.graphql.org/October2021#sel-FAHTRFCAACChCtpG">query</a>, <ahref="https://spec.graphql.org/October2021#sel-FAHTRHCAACCuE9yD">mutation</a>, and <ahref="https://spec.graphql.org/October2021#sel-FAHTRJCAACC3EhsX">subscription</a> root types as <code>Query</code>, <code>Mutation</code>, and <code>Subscription</code> respectively.</p>
</blockquote>
<p>The usage of <ahref="https://spec.graphql.org/October2021#sel-FAHTRJCAACC3EhsX">subscriptions</a> is a little different from the <ahref="https://spec.graphql.org/October2021#sel-FAHTRHCAACCuE9yD">mutation</a> and <ahref="https://spec.graphql.org/October2021#sel-FAHTRFCAACChCtpG">query</a><ahref="https://spec.graphql.org/October2021#sec-Objects">objects</a>, so they are discussed in the <ahref="subscriptions.html">separate chapter</a>.</p>
<p>Many tools in <ahref="https://graphql.org">GraphQL</a> ecosystem require a <ahref="https://graphql.org/learn/schema">schema</a> definition to operate on. With <ahref="https://docs.rs/juniper">Juniper</a> we can export our <ahref="https://spec.graphql.org/October2021#sec-Schema">GraphQL schema</a> defined in <ahref="https://www.rust-lang.org">Rust</a> code either represented in the <ahref="https://graphql.org/learn/schema#type-language">GraphQL schema language</a> or in <ahref="https://www.json.org">JSON</a>.</p>
<p>To generate an <ahref="https://graphql.org/learn/schema#type-language">SDL (schema definition language)</a> representation of a <ahref="https://spec.graphql.org/October2021#sec-Schema">GraphQL schema</a> defined in <ahref="https://www.rust-lang.org">Rust</a> code, the <ahref="https://docs.rs/juniper/0.16.1/juniper/struct.RootNode.html#method.as_sdl"><code>as_sdl()</code> method</a> should be used for the direct extraction (requires enabling the <code>schema-language</code><ahref="https://docs.rs/juniper">Juniper</a> feature):</p>
<p>To export a <ahref="https://spec.graphql.org/October2021#sec-Schema">GraphQL schema</a> defined in <ahref="https://www.rust-lang.org">Rust</a> code as <ahref="https://www.json.org">JSON</a> (often referred to as <code>schema.json</code>), the specially crafted <ahref="https://docs.rs/crate/juniper/latest/source/src/introspection/query.graphql">introspection query</a> should be issued. <ahref="https://docs.rs/juniper">Juniper</a> provides a <ahref="https://docs.rs/juniper/0.16.1/juniper/fn.introspect.html">convenience <code>introspect()</code> function</a> to <ahref="introspection.html">introspect</a> the entire <ahref="https://spec.graphql.org/October2021#sec-Schema">schema</a>, which result can be serialized into <ahref="https://www.json.org">JSON</a>:</p>
let json_result = serde_json::to_string_pretty(&res);
assert!(json_result.is_ok());
}</code></pre></pre>
<blockquote>
<p><strong>TIP</strong>: We still can convert the generated <ahref="https://www.json.org">JSON</a> into a <ahref="https://graphql.org/learn/schema#type-language">GraphQL schema language</a> representation by using tools like <ahref="https://npmjs.com/package/graphql-json-to-sdl"><code>graphql-json-to-sdl</code> command line utility</a>.</p>