# Juniper — GraphQL Server Library for Rust > Juniper is a code-first GraphQL server library for Rust that uses macros to derive GraphQL schemas directly from Rust types, providing type-safe query execution with zero runtime overhead. ## Install Save as a script file and run: # Juniper — GraphQL Server Library for Rust ## Quick Use ```rust // Cargo.toml // [dependencies] // juniper = "0.16" // juniper_warp = "0.8" use juniper::{graphql_object, EmptyMutation, EmptySubscription, RootNode}; struct Query; #[graphql_object] impl Query { fn hello() -> &str { "Hello, world!" } } type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; ``` ## Introduction Juniper brings GraphQL to the Rust ecosystem with a code-first approach where your Rust structs and enums become the GraphQL schema. By leveraging Rust's type system and procedural macros, Juniper catches schema errors at compile time and produces a GraphQL server with the same memory safety and performance guarantees that Rust provides. ## What Juniper Does - Derives GraphQL types from Rust structs, enums, and trait implementations using procedural macros - Executes GraphQL queries, mutations, and subscriptions with compile-time type safety - Integrates with web frameworks including Actix-web, Warp, Hyper, and Rocket - Supports the full GraphQL specification including interfaces, unions, input objects, and custom scalars - Provides built-in support for async resolvers using Rust's async/await ## Architecture Overview Juniper uses a derive-macro system to generate GraphQL type metadata from annotated Rust types at compile time. When a query arrives, the executor parses the GraphQL document, validates it against the generated schema, and resolves fields by calling the corresponding Rust methods. The execution engine handles field-level parallelism for async resolvers. Integration crates (juniper_warp, juniper_actix, etc.) bridge the executor to HTTP endpoints. ## Self-Hosting & Configuration - Add `juniper` to Cargo.toml along with an integration crate for your web framework - Define a Context type to hold database connections, auth state, and other per-request data - Annotate structs with `#[derive(GraphQLObject)]` for simple output types or use `#[graphql_object]` for resolver logic - Mount the GraphQL endpoint and optionally enable GraphiQL or GraphQL Playground for development - Configure subscription support with `juniper_subscriptions` for WebSocket-based real-time data ## Key Features - Compile-time schema validation ensures type mismatches and missing fields are caught before deployment - Async resolver support allows non-blocking database queries and external API calls - N+1 query prevention through integration with DataLoader patterns - Custom scalar types for domain-specific values like dates, UUIDs, and URLs - Schema introspection endpoint compatible with GraphQL IDEs and code generators ## Comparison with Similar Tools - **async-graphql** — Rust alternative with attribute macros and built-in subscription support; Juniper has a longer track record and broader framework integration - **Apollo Server** — Node.js GraphQL server with a rich plugin ecosystem; Juniper offers Rust's performance and memory safety - **Strawberry** — Python GraphQL with dataclass-based schema; Juniper provides similar ergonomics in Rust with compile-time checks - **Hot Chocolate** — .NET GraphQL server; Juniper trades the .NET runtime for Rust's zero-cost abstractions - **Hasura** — Auto-generates GraphQL from database schema; Juniper gives full control over resolver logic and business rules ## FAQ **Q: Does Juniper support GraphQL subscriptions?** A: Yes. The `juniper_subscriptions` crate adds subscription support using async streams, compatible with the GraphQL over WebSocket protocol. **Q: Which web framework should I use with Juniper?** A: Juniper provides integration crates for Actix-web, Warp, Hyper, and Rocket. Choose based on your project's existing framework or performance requirements. **Q: Can I use Juniper with an existing database ORM?** A: Yes. Juniper resolvers are regular Rust functions that can call Diesel, SeaORM, sqlx, or any other database library through the context object. **Q: How do I handle authentication in Juniper?** A: Extract auth tokens in your web framework's middleware, validate them, and pass the authenticated user into Juniper's Context. Resolvers then access the context to enforce authorization. ## Sources - https://github.com/graphql-rust/juniper - https://graphql-rust.github.io/juniper/ --- Source: https://tokrepo.com/en/workflows/asset-1532c647 Author: Script Depot