diff --git a/advanced/implicit_and_explicit_null.html b/advanced/implicit_and_explicit_null.html index b5eec536..afe7c5b6 100644 --- a/advanced/implicit_and_explicit_null.html +++ b/advanced/implicit_and_explicit_null.html @@ -218,7 +218,7 @@ struct UserPatch {
mutation { patchUser(patch: {}) }
 

The last two cases rely on being able to distinguish between explicit and implicit null.

-

Unfortunately, plain Option is not capable to distinguish them. That's why in Juniper, this can be done using the Nullable type:

+

Unfortunately, plain Option is not capable to distinguish them. That's why in Juniper, this can be done using the Nullable type:

extern crate juniper;
 use juniper::{graphql_object, FieldResult, GraphQLInputObject, Nullable};
 
diff --git a/advanced/lookahead.html b/advanced/lookahead.html
index 485323e8..f783f154 100644
--- a/advanced/lookahead.html
+++ b/advanced/lookahead.html
@@ -178,7 +178,7 @@
 

In backtracking algorithms, look ahead is the generic term for a subprocedure that attempts to foresee the effects of choosing a branching variable to evaluate one of its values. The two main aims of look-ahead are to choose a variable to evaluate next and to choose the order of values to assign to it.

In GraphQL, look-ahead machinery allows us to introspect the currently executed GraphQL operation to see which fields has been actually selected by it.

-

In Juniper, it's represented by the Executor::look_ahead() method.

+

In Juniper, it's represented by the Executor::look_ahead() method.

#![allow(unused)]
 fn main() {
 extern crate juniper;
@@ -210,7 +210,7 @@ impl Query {
 }
 }
-

TIP: S: ScalarValue type parameter on the method is required here to keep the Executor being generic over ScalarValue types. We, instead, could have used the DefaultScalarValue, which is the default ScalarValue type for the Executor, and make our code more ergonomic, but less flexible and generic.

+

TIP: S: ScalarValue type parameter on the method is required here to keep the Executor being generic over ScalarValue types. We, instead, could have used the DefaultScalarValue, which is the default ScalarValue type for the Executor, and make our code more ergonomic, but less flexible and generic.

#![allow(unused)]
 fn main() {
 extern crate juniper;
@@ -374,7 +374,7 @@ impl Query {
 SELECT id, name FROM cults WHERE id IN (1, 2, 3, 4);
 

More features

-

See more available look-ahead features in the API docs of the LookAheadSelection and the LookAheadChildren.

+

See more available look-ahead features in the API docs of the LookAheadSelection and the LookAheadChildren.

diff --git a/print.html b/print.html index 9f894287..47e88e2b 100644 --- a/print.html +++ b/print.html @@ -223,7 +223,7 @@ juniper = "0.16.0"

Schema

Exposing simple enums and structs as GraphQL types is just a matter of adding a custom derive attribute to them. Juniper includes support for basic Rust types that naturally map to GraphQL features, such as Option<T>, Vec<T>, Box<T>, Arc<T>, String, f64, i32, references, slices and arrays.

-

For more advanced mappings, Juniper provides multiple macros to map your Rust types to a GraphQL schema. The most important one is the #[graphql_object] attribute that is used for declaring a GraphQL object with resolvers (typically used for declaring Query and Mutation roots).

+

For more advanced mappings, Juniper provides multiple macros to map your Rust types to a GraphQL schema. The most important one is the #[graphql_object] attribute that is used for declaring a GraphQL object with resolvers (typically used for declaring Query and Mutation roots).

# ![allow(unused_variables)]
 extern crate juniper;
 
@@ -430,8 +430,8 @@ fn main() {
 

When declaring a GraphQL schema, most of the time we deal with GraphQL objects, because they are the only place where we actually define the behavior once schema gets executed.

There are two ways to define a GraphQL object in Juniper:

    -
  1. The easiest way, suitable for trivial cases, is to use the #[derive(GraphQLObject)] attribute on a struct, as described below.
  2. -
  3. The other way, using the #[graphql_object] attribute, is described in the "Complex fields" chapter.
  4. +
  5. The easiest way, suitable for trivial cases, is to use the #[derive(GraphQLObject)] attribute on a struct, as described below.
  6. +
  7. The other way, using the #[graphql_object] attribute, is described in the "Complex fields" chapter.

Trivial

While any type in Rust can be exposed as a GraphQL object, the most common one is a struct:

@@ -447,7 +447,7 @@ struct Person {
fn main() {}

This creates a GraphQL object type called Person, with two fields: name of type String!, and age of type Int!. Because of Rust's type system, everything is exported as non-null by default.

-

TIP: If a nullable field is required, the most obvious way is to use Option. Or Nullable for distinguishing between explicit and implicit nulls.

+

TIP: If a nullable field is required, the most obvious way is to use Option. Or Nullable for distinguishing between explicit and implicit nulls.

Documentation

We should take advantage of the fact that GraphQL is self-documenting and add descriptions to the defined GraphQL object type and its fields. Juniper will automatically use associated Rust doc comments as GraphQL descriptions:

@@ -564,7 +564,7 @@ struct Person { fn main() {}
-

TIP: See more available features in the API docs of the #[derive(GraphQLObject)] attribute.

+

TIP: See more available features in the API docs of the #[derive(GraphQLObject)] attribute.

Relationships

GraphQL object fields can be of any GraphQL type, except input objects.

@@ -594,7 +594,7 @@ struct House {
  • Defining a circular GraphQL object, where one of its fields returns the type itself.
  • Using some other (non-struct) Rust type to represent a GraphQL object.
  • -

    To support these more complicated use cases, we need a way to define a GraphQL field as a function. In Juniper this is achievable by placing the #[graphql_object] attribute on an impl block, which turns its methods into GraphQL fields:

    +

    To support these more complicated use cases, we need a way to define a GraphQL field as a function. In Juniper this is achievable by placing the #[graphql_object] attribute on an impl block, which turns its methods into GraphQL fields:

    extern crate juniper;
     use juniper::{graphql_object, GraphQLObject};
     
    @@ -772,7 +772,7 @@ impl Person {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[graphql_object] attribute.

    +

    TIP: See more available features in the API docs of the #[graphql_object] attribute.

    Context

    Context is a feature in Juniper that lets field resolvers access global data, most commonly database connections or authentication information.

    @@ -950,12 +950,12 @@ impl Example { } fn main() {} -

    FieldResult<T> is an alias for Result<T, FieldError>, which is the error type all fallible fields must return. By using the ? operator, any type that implements the Display trait (which most of the error types out there do) can be automatically converted into a FieldError.

    +

    FieldResult<T> is an alias for Result<T, FieldError>, which is the error type all fallible fields must return. By using the ? operator, any type that implements the Display trait (which most of the error types out there do) can be automatically converted into a FieldError.

    -

    TIP: If a custom conversion into a FieldError is needed (to fill up extensions, for example), the IntoFieldError trait should be implemented.

    +

    TIP: If a custom conversion into a FieldError is needed (to fill up extensions, for example), the IntoFieldError trait should be implemented.

    -

    NOTE: FieldErrors are GraphQL field errors and are not visible in a GraphQL schema in any way.

    +

    NOTE: FieldErrors are GraphQL field errors and are not visible in a GraphQL schema in any way.

    Error payloads, null, and partial errors

    Juniper's error behavior conforms to the GraphQL specification.

    @@ -1002,7 +1002,7 @@ impl Example { }

    Additional information

    -

    Sometimes it's desirable to return additional structured error information to clients. This can be accomplished by implementing the IntoFieldError trait:

    +

    Sometimes it's desirable to return additional structured error information to clients. This can be accomplished by implementing the IntoFieldError trait:

    #[macro_use] extern crate juniper;
     use juniper::{graphql_object, FieldError, IntoFieldError, ScalarValue};
     
    @@ -1408,7 +1408,7 @@ impl MutationResult<ForumPost> {
     
  • Either a struct, or a trait (in case fields have arguments), which acts only as a blueprint describing the required list of fields, and is not used in runtime at all.
  • An auto-generated enum, representing a dispatchable value-type for the GraphQL interfaces, which may be referred and returned by other fields.
  • -

    This may be done by using either the #[graphql_interface] attribute or the #[derive(GraphQLInterface)]:

    +

    This may be done by using either the #[graphql_interface] attribute or the #[derive(GraphQLInterface)]:

    extern crate juniper;
     use juniper::{graphql_interface, GraphQLInterface, GraphQLObject};
     
    @@ -1750,14 +1750,14 @@ trait Person {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[graphql_interface] attribute.

    +

    TIP: See more available features in the API docs of the #[graphql_interface] attribute.

    Unions

    GraphQL unions represent an object that could be one of a list of GraphQL object types, but provides for no guaranteed fields between those types. They also differ from interfaces in that object types declare what interfaces they implement, but are not aware of what unions contain them.

    From the server's point of view, GraphQL unions are somewhat similar to interfaces: the main difference is that they don't contain fields on their own, and so, we only need to represent a value, dispatchable into concrete objects.

    -

    Obviously, the most straightforward approach to express GraphQL unions in Rust is to use enums. In Juniper this may be done by using #[derive(GraphQLInterface)] attribute on them:

    +

    Obviously, the most straightforward approach to express GraphQL unions in Rust is to use enums. In Juniper this may be done by using #[derive(GraphQLInterface)] attribute on them:

    extern crate derive_more;
     extern crate juniper;
     use derive_more::From;
    @@ -1887,14 +1887,14 @@ enum Character<S> {
     

    WARNING: It's the library user's responsibility to ensure that ignored enum variant is never returned from resolvers, otherwise resolving the GraphQL query will panic in runtime.

    -

    TIP: See more available features in the API docs of the #[derive(GraphQLUnion)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLUnion)] attribute.

    Enums

    GraphQL enum types, like scalar types, also represent leaf values in a GraphQL type system. However enum types describe the set of possible values.

    Enums are not references for a numeric value, but are unique values in their own right. They may serialize as a string: the name of the represented value.

    -

    With Juniper a GraphQL enum may be defined by using the #[derive(GraphQLEnum)] attribute on a Rust enum as long as its variants do not have any fields:

    +

    With Juniper a GraphQL enum may be defined by using the #[derive(GraphQLEnum)] attribute on a Rust enum as long as its variants do not have any fields:

    extern crate juniper;
     use juniper::GraphQLEnum;
     
    @@ -2001,14 +2001,14 @@ enum Episode<T> {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLEnum)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLEnum)] attribute.

    Input objects

    Fields may accept arguments to configure their behavior. These inputs are often scalars or enums, but they sometimes need to represent more complex values.

    A GraphQL input object defines a set of input fields; the input fields are either scalars, enums, or other input objects. This allows arguments to accept arbitrarily complex structs.

    -

    In Juniper, defining a GraphQL input object is quite straightforward and similar to how trivial GraphQL objects are defined - by using the #[derive(GraphQLInputObject)] attribute on a Rust struct:

    +

    In Juniper, defining a GraphQL input object is quite straightforward and similar to how trivial GraphQL objects are defined - by using the #[derive(GraphQLInputObject)] attribute on a Rust struct:

    #![allow(unused_variables)]
     extern crate juniper;
     use juniper::{graphql_object, GraphQLInputObject, GraphQLObject};
    @@ -2128,7 +2128,7 @@ struct Point2D {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLInputObject)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLInputObject)] attribute.

    Scalars

    GraphQL scalars represent primitive leaf values in a GraphQL type system: numbers, strings, and booleans.

    @@ -2150,7 +2150,7 @@ struct Point2D {

    Custom

    We can create custom scalars for other primitive values, but they are still limited in the data types for representation, and only introduce additional semantic meaning. This, also, often requires coordination with the client library, intended to consume the API we're building.

    -

    Custom scalars can be defined in Juniper by using either #[derive(GraphQLScalar)] or #[graphql_scalar] attributes, which do work pretty much the same way (except, #[derive(GraphQLScalar)] cannot be used on type aliases).

    +

    Custom scalars can be defined in Juniper by using either #[derive(GraphQLScalar)] or #[graphql_scalar] attributes, which do work pretty much the same way (except, #[derive(GraphQLScalar)] cannot be used on type aliases).

    Transparent delegation

    Quite often, we want to create a custom GraphQL scalar type by just wrapping an existing one, inheriting all its behavior. In Rust, this is often called as "newtype pattern". This may be achieved by providing a #[graphql(transparent)] attribute to the definition:

    extern crate juniper;
    @@ -2410,12 +2410,12 @@ mod string_or_int {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLScalar)] and #[graphql_scalar] attributes.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLScalar)] and #[graphql_scalar] attributes.

    Foreign

    -

    For implementing custom scalars on foreign types there is #[graphql_scalar] attribute.

    +

    For implementing custom scalars on foreign types there is #[graphql_scalar] attribute.

    -

    NOTE: To satisfy orphan rules, we should provide a local ScalarValue implementation.

    +

    NOTE: To satisfy orphan rules, we should provide a local ScalarValue implementation.

    extern crate juniper;
     mod date {
    @@ -2494,10 +2494,10 @@ mod date_scalar {
     

    Similarly, the subscription 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 Object type.

    The query, mutation, and subscription root types must all be different types if provided.

    -

    In Juniper, the RootNode type represents a schema. When the schema is first created, Juniper will traverse the entire object graph and register all types it can find. This means that if we define a GraphQL object somewhere but never use or reference it, it won't be exposed in a GraphQL schema.

    +

    In Juniper, the RootNode type represents a schema. When the schema is first created, Juniper will traverse the entire object graph and register all types it can find. This means that if we define a GraphQL object somewhere but never use or reference it, it won't be exposed in a GraphQL schema.

    Both query and mutation objects are regular GraphQL objects, defined like any other object in Juniper. The mutation and subscription objects, however, are optional, since schemas can be read-only and do not require subscriptions.

    -

    TIP: If mutation/subscription functionality is not needed, consider using the predefined EmptyMutation/EmptySubscription types for stubbing them in a RootNode.

    +

    TIP: If mutation/subscription functionality is not needed, consider using the predefined EmptyMutation/EmptySubscription types for stubbing them in a RootNode.

    extern crate juniper;
     use juniper::{
    @@ -2539,7 +2539,7 @@ type Schema = RootNode<'static, Query, Mutation, EmptySubscription>;
     

    Export

    Many tools in GraphQL ecosystem require a schema definition to operate on. With Juniper we can export our GraphQL schema defined in Rust code either represented in the GraphQL schema language or in JSON.

    SDL (schema definition language)

    -

    To generate an SDL (schema definition language) representation of a GraphQL schema defined in Rust code, the as_sdl() method should be used for the direct extraction (requires enabling the schema-language Juniper feature):

    +

    To generate an SDL (schema definition language) representation of a GraphQL schema defined in Rust code, the as_sdl() method should be used for the direct extraction (requires enabling the schema-language Juniper feature):

    extern crate juniper;
     use juniper::{
         graphql_object, EmptyMutation, EmptySubscription, FieldResult, RootNode,
    @@ -2578,7 +2578,7 @@ type Query {
         assert_eq!(result, expected);
     }

    JSON

    -

    To export a GraphQL schema defined in Rust code as JSON (often referred to as schema.json), the specially crafted introspection query should be issued. Juniper provides a convenience introspect() function to introspect the entire schema, which result can be serialized into JSON:

    +

    To export a GraphQL schema defined in Rust code as JSON (often referred to as schema.json), the specially crafted introspection query should be issued. Juniper provides a convenience introspect() function to introspect the entire schema, which result can be serialized into JSON:

    extern crate juniper;
     extern crate serde_json;
     use juniper::{
    @@ -2662,9 +2662,9 @@ impl Subscription {
     
     fn main () {}

    Coordinator

    -

    GraphQL subscriptions require a bit more resources than regular queries and provide a great vector for DoS attacks. This can can bring down a server easily if not handled correctly. The SubscriptionCoordinator trait provides coordination logic to enable functionality like DoS attacks mitigation and resource limits.

    -

    The SubscriptionCoordinator contains the schema and can keep track of opened connections, handle subscription start and end, and maintain a global ID for each subscription. Each time a connection is established, the SubscriptionCoordinator spawns a [32], which handles a single connection, providing resolver logic for a client stream as well as reconnection and shutdown logic.

    -

    While we can implement SubscriptionCoordinator ourselves, Juniper contains a simple and generic implementation called Coordinator. The subscribe method returns a Future resolving into a Result<Connection, GraphQLError>, where Connection is a Stream of values returned by the operation, and a GraphQLError is the error when the subscription operation fails.

    +

    GraphQL subscriptions require a bit more resources than regular queries and provide a great vector for DoS attacks. This can can bring down a server easily if not handled correctly. The SubscriptionCoordinator trait provides coordination logic to enable functionality like DoS attacks mitigation and resource limits.

    +

    The SubscriptionCoordinator contains the schema and can keep track of opened connections, handle subscription start and end, and maintain a global ID for each subscription. Each time a connection is established, the SubscriptionCoordinator spawns a [32], which handles a single connection, providing resolver logic for a client stream as well as reconnection and shutdown logic.

    +

    While we can implement SubscriptionCoordinator ourselves, Juniper contains a simple and generic implementation called Coordinator. The subscribe method returns a Future resolving into a Result<Connection, GraphQLError>, where Connection is a Stream of values returned by the operation, and a GraphQLError is the error when the subscription operation fails.

    extern crate futures;
     extern crate juniper;
     extern crate juniper_subscriptions;
    @@ -2764,7 +2764,7 @@ __type(name: String!): __Type
     

    Disabling introspection in production is a widely debated topic, but we believe it’s one of the first things you can do to harden your GraphQL API in production.

    -

    Some security requirements and considerations may mandate to disable GraphQL schema introspection in production environments. In Juniper this can be achieved by using the RootNode::disable_introspection() method:

    +

    Some security requirements and considerations may mandate to disable GraphQL schema introspection in production environments. In Juniper this can be achieved by using the RootNode::disable_introspection() method:

    extern crate juniper;
     use juniper::{
         graphql_object, graphql_vars, EmptyMutation, EmptySubscription, GraphQLError,
    @@ -2944,7 +2944,7 @@ struct UserPatch {
     
    mutation { patchUser(patch: {}) }
     

    The last two cases rely on being able to distinguish between explicit and implicit null.

    -

    Unfortunately, plain Option is not capable to distinguish them. That's why in Juniper, this can be done using the Nullable type:

    +

    Unfortunately, plain Option is not capable to distinguish them. That's why in Juniper, this can be done using the Nullable type:

    extern crate juniper;
     use juniper::{graphql_object, FieldResult, GraphQLInputObject, Nullable};
     
    @@ -3257,7 +3257,7 @@ SELECT id, name FROM cults WHERE id IN (1, 2, 3, 4);
     

    In backtracking algorithms, look ahead is the generic term for a subprocedure that attempts to foresee the effects of choosing a branching variable to evaluate one of its values. The two main aims of look-ahead are to choose a variable to evaluate next and to choose the order of values to assign to it.

    In GraphQL, look-ahead machinery allows us to introspect the currently executed GraphQL operation to see which fields has been actually selected by it.

    -

    In Juniper, it's represented by the Executor::look_ahead() method.

    +

    In Juniper, it's represented by the Executor::look_ahead() method.

    #![allow(unused)]
     fn main() {
     extern crate juniper;
    @@ -3289,7 +3289,7 @@ impl Query {
     }
     }
    -

    TIP: S: ScalarValue type parameter on the method is required here to keep the Executor being generic over ScalarValue types. We, instead, could have used the DefaultScalarValue, which is the default ScalarValue type for the Executor, and make our code more ergonomic, but less flexible and generic.

    +

    TIP: S: ScalarValue type parameter on the method is required here to keep the Executor being generic over ScalarValue types. We, instead, could have used the DefaultScalarValue, which is the default ScalarValue type for the Executor, and make our code more ergonomic, but less flexible and generic.

    #![allow(unused)]
     fn main() {
     extern crate juniper;
    @@ -3453,7 +3453,7 @@ impl Query {
     SELECT id, name FROM cults WHERE id IN (1, 2, 3, 4);
     

    More features

    -

    See more available look-ahead features in the API docs of the LookAheadSelection and the LookAheadChildren.

    +

    See more available look-ahead features in the API docs of the LookAheadSelection and the LookAheadChildren.

    Eager loading

    As a further evolution of the dealing with the N+1 problem via look-ahead, we may systematically remodel Rust types mapping to GraphQL ones in the way to encourage doing eager preloading of data for its fields and using the already preloaded data when resolving a particular field.

    At the moment, this approach is represented with the juniper-eager-loading crate for Juniper.

    diff --git a/quickstart.html b/quickstart.html index ff4d9a3b..8cd10f7d 100644 --- a/quickstart.html +++ b/quickstart.html @@ -185,7 +185,7 @@ juniper = "0.16.0"

    Schema

    Exposing simple enums and structs as GraphQL types is just a matter of adding a custom derive attribute to them. Juniper includes support for basic Rust types that naturally map to GraphQL features, such as Option<T>, Vec<T>, Box<T>, Arc<T>, String, f64, i32, references, slices and arrays.

    -

    For more advanced mappings, Juniper provides multiple macros to map your Rust types to a GraphQL schema. The most important one is the #[graphql_object] attribute that is used for declaring a GraphQL object with resolvers (typically used for declaring Query and Mutation roots).

    +

    For more advanced mappings, Juniper provides multiple macros to map your Rust types to a GraphQL schema. The most important one is the #[graphql_object] attribute that is used for declaring a GraphQL object with resolvers (typically used for declaring Query and Mutation roots).

    # ![allow(unused_variables)]
     extern crate juniper;
     
    diff --git a/schema/index.html b/schema/index.html
    index ebefd9e2..152e355d 100644
    --- a/schema/index.html
    +++ b/schema/index.html
    @@ -185,10 +185,10 @@
     

    Similarly, the subscription 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 Object type.

    The query, mutation, and subscription root types must all be different types if provided.

    -

    In Juniper, the RootNode type represents a schema. When the schema is first created, Juniper will traverse the entire object graph and register all types it can find. This means that if we define a GraphQL object somewhere but never use or reference it, it won't be exposed in a GraphQL schema.

    +

    In Juniper, the RootNode type represents a schema. When the schema is first created, Juniper will traverse the entire object graph and register all types it can find. This means that if we define a GraphQL object somewhere but never use or reference it, it won't be exposed in a GraphQL schema.

    Both query and mutation objects are regular GraphQL objects, defined like any other object in Juniper. The mutation and subscription objects, however, are optional, since schemas can be read-only and do not require subscriptions.

    -

    TIP: If mutation/subscription functionality is not needed, consider using the predefined EmptyMutation/EmptySubscription types for stubbing them in a RootNode.

    +

    TIP: If mutation/subscription functionality is not needed, consider using the predefined EmptyMutation/EmptySubscription types for stubbing them in a RootNode.

    extern crate juniper;
     use juniper::{
    @@ -230,7 +230,7 @@ type Schema = RootNode<'static, Query, Mutation, EmptySubscription>;
     

    Export

    Many tools in GraphQL ecosystem require a schema definition to operate on. With Juniper we can export our GraphQL schema defined in Rust code either represented in the GraphQL schema language or in JSON.

    SDL (schema definition language)

    -

    To generate an SDL (schema definition language) representation of a GraphQL schema defined in Rust code, the as_sdl() method should be used for the direct extraction (requires enabling the schema-language Juniper feature):

    +

    To generate an SDL (schema definition language) representation of a GraphQL schema defined in Rust code, the as_sdl() method should be used for the direct extraction (requires enabling the schema-language Juniper feature):

    extern crate juniper;
     use juniper::{
         graphql_object, EmptyMutation, EmptySubscription, FieldResult, RootNode,
    @@ -269,7 +269,7 @@ type Query {
         assert_eq!(result, expected);
     }

    JSON

    -

    To export a GraphQL schema defined in Rust code as JSON (often referred to as schema.json), the specially crafted introspection query should be issued. Juniper provides a convenience introspect() function to introspect the entire schema, which result can be serialized into JSON:

    +

    To export a GraphQL schema defined in Rust code as JSON (often referred to as schema.json), the specially crafted introspection query should be issued. Juniper provides a convenience introspect() function to introspect the entire schema, which result can be serialized into JSON:

    extern crate juniper;
     extern crate serde_json;
     use juniper::{
    diff --git a/schema/introspection.html b/schema/introspection.html
    index e4609548..84397d6e 100644
    --- a/schema/introspection.html
    +++ b/schema/introspection.html
    @@ -195,7 +195,7 @@ __type(name: String!): __Type
     

    Disabling introspection in production is a widely debated topic, but we believe it’s one of the first things you can do to harden your GraphQL API in production.

    -

    Some security requirements and considerations may mandate to disable GraphQL schema introspection in production environments. In Juniper this can be achieved by using the RootNode::disable_introspection() method:

    +

    Some security requirements and considerations may mandate to disable GraphQL schema introspection in production environments. In Juniper this can be achieved by using the RootNode::disable_introspection() method:

    extern crate juniper;
     use juniper::{
         graphql_object, graphql_vars, EmptyMutation, EmptySubscription, GraphQLError,
    diff --git a/schema/subscriptions.html b/schema/subscriptions.html
    index 2583b151..8ad9ae15 100644
    --- a/schema/subscriptions.html
    +++ b/schema/subscriptions.html
    @@ -218,9 +218,9 @@ impl Subscription {
     
     fn main () {}

    Coordinator

    -

    GraphQL subscriptions require a bit more resources than regular queries and provide a great vector for DoS attacks. This can can bring down a server easily if not handled correctly. The SubscriptionCoordinator trait provides coordination logic to enable functionality like DoS attacks mitigation and resource limits.

    -

    The SubscriptionCoordinator contains the schema and can keep track of opened connections, handle subscription start and end, and maintain a global ID for each subscription. Each time a connection is established, the SubscriptionCoordinator spawns a [32], which handles a single connection, providing resolver logic for a client stream as well as reconnection and shutdown logic.

    -

    While we can implement SubscriptionCoordinator ourselves, Juniper contains a simple and generic implementation called Coordinator. The subscribe method returns a Future resolving into a Result<Connection, GraphQLError>, where Connection is a Stream of values returned by the operation, and a GraphQLError is the error when the subscription operation fails.

    +

    GraphQL subscriptions require a bit more resources than regular queries and provide a great vector for DoS attacks. This can can bring down a server easily if not handled correctly. The SubscriptionCoordinator trait provides coordination logic to enable functionality like DoS attacks mitigation and resource limits.

    +

    The SubscriptionCoordinator contains the schema and can keep track of opened connections, handle subscription start and end, and maintain a global ID for each subscription. Each time a connection is established, the SubscriptionCoordinator spawns a [32], which handles a single connection, providing resolver logic for a client stream as well as reconnection and shutdown logic.

    +

    While we can implement SubscriptionCoordinator ourselves, Juniper contains a simple and generic implementation called Coordinator. The subscribe method returns a Future resolving into a Result<Connection, GraphQLError>, where Connection is a Stream of values returned by the operation, and a GraphQLError is the error when the subscription operation fails.

    extern crate futures;
     extern crate juniper;
     extern crate juniper_subscriptions;
    diff --git a/types/enums.html b/types/enums.html
    index b5990a77..e4eb0102 100644
    --- a/types/enums.html
    +++ b/types/enums.html
    @@ -178,7 +178,7 @@
     

    GraphQL enum types, like scalar types, also represent leaf values in a GraphQL type system. However enum types describe the set of possible values.

    Enums are not references for a numeric value, but are unique values in their own right. They may serialize as a string: the name of the represented value.

    -

    With Juniper a GraphQL enum may be defined by using the #[derive(GraphQLEnum)] attribute on a Rust enum as long as its variants do not have any fields:

    +

    With Juniper a GraphQL enum may be defined by using the #[derive(GraphQLEnum)] attribute on a Rust enum as long as its variants do not have any fields:

    extern crate juniper;
     use juniper::GraphQLEnum;
     
    @@ -285,7 +285,7 @@ enum Episode<T> {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLEnum)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLEnum)] attribute.

    diff --git a/types/input_objects.html b/types/input_objects.html index 396ddf44..a260ece4 100644 --- a/types/input_objects.html +++ b/types/input_objects.html @@ -178,7 +178,7 @@

    Fields may accept arguments to configure their behavior. These inputs are often scalars or enums, but they sometimes need to represent more complex values.

    A GraphQL input object defines a set of input fields; the input fields are either scalars, enums, or other input objects. This allows arguments to accept arbitrarily complex structs.

    -

    In Juniper, defining a GraphQL input object is quite straightforward and similar to how trivial GraphQL objects are defined - by using the #[derive(GraphQLInputObject)] attribute on a Rust struct:

    +

    In Juniper, defining a GraphQL input object is quite straightforward and similar to how trivial GraphQL objects are defined - by using the #[derive(GraphQLInputObject)] attribute on a Rust struct:

    #![allow(unused_variables)]
     extern crate juniper;
     use juniper::{graphql_object, GraphQLInputObject, GraphQLObject};
    @@ -298,7 +298,7 @@ struct Point2D {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLInputObject)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLInputObject)] attribute.

    diff --git a/types/interfaces.html b/types/interfaces.html index 1a7af9f3..c082e57b 100644 --- a/types/interfaces.html +++ b/types/interfaces.html @@ -184,7 +184,7 @@
  • Either a struct, or a trait (in case fields have arguments), which acts only as a blueprint describing the required list of fields, and is not used in runtime at all.
  • An auto-generated enum, representing a dispatchable value-type for the GraphQL interfaces, which may be referred and returned by other fields.
  • -

    This may be done by using either the #[graphql_interface] attribute or the #[derive(GraphQLInterface)]:

    +

    This may be done by using either the #[graphql_interface] attribute or the #[derive(GraphQLInterface)]:

    extern crate juniper;
     use juniper::{graphql_interface, GraphQLInterface, GraphQLObject};
     
    @@ -526,7 +526,7 @@ trait Person {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[graphql_interface] attribute.

    +

    TIP: See more available features in the API docs of the #[graphql_interface] attribute.

    diff --git a/types/objects/complex_fields.html b/types/objects/complex_fields.html index dc0f53cb..8c765b71 100644 --- a/types/objects/complex_fields.html +++ b/types/objects/complex_fields.html @@ -181,7 +181,7 @@
  • Defining a circular GraphQL object, where one of its fields returns the type itself.
  • Using some other (non-struct) Rust type to represent a GraphQL object.
  • -

    To support these more complicated use cases, we need a way to define a GraphQL field as a function. In Juniper this is achievable by placing the #[graphql_object] attribute on an impl block, which turns its methods into GraphQL fields:

    +

    To support these more complicated use cases, we need a way to define a GraphQL field as a function. In Juniper this is achievable by placing the #[graphql_object] attribute on an impl block, which turns its methods into GraphQL fields:

    extern crate juniper;
     use juniper::{graphql_object, GraphQLObject};
     
    @@ -359,7 +359,7 @@ impl Person {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[graphql_object] attribute.

    +

    TIP: See more available features in the API docs of the #[graphql_object] attribute.

    diff --git a/types/objects/error/field.html b/types/objects/error/field.html index e5e1bc1c..d992a7c1 100644 --- a/types/objects/error/field.html +++ b/types/objects/error/field.html @@ -207,12 +207,12 @@ impl Example { } fn main() {}
    -

    FieldResult<T> is an alias for Result<T, FieldError>, which is the error type all fallible fields must return. By using the ? operator, any type that implements the Display trait (which most of the error types out there do) can be automatically converted into a FieldError.

    +

    FieldResult<T> is an alias for Result<T, FieldError>, which is the error type all fallible fields must return. By using the ? operator, any type that implements the Display trait (which most of the error types out there do) can be automatically converted into a FieldError.

    -

    TIP: If a custom conversion into a FieldError is needed (to fill up extensions, for example), the IntoFieldError trait should be implemented.

    +

    TIP: If a custom conversion into a FieldError is needed (to fill up extensions, for example), the IntoFieldError trait should be implemented.

    -

    NOTE: FieldErrors are GraphQL field errors and are not visible in a GraphQL schema in any way.

    +

    NOTE: FieldErrors are GraphQL field errors and are not visible in a GraphQL schema in any way.

    Error payloads, null, and partial errors

    Juniper's error behavior conforms to the GraphQL specification.

    @@ -259,7 +259,7 @@ impl Example { }

    Additional information

    -

    Sometimes it's desirable to return additional structured error information to clients. This can be accomplished by implementing the IntoFieldError trait:

    +

    Sometimes it's desirable to return additional structured error information to clients. This can be accomplished by implementing the IntoFieldError trait:

    #[macro_use] extern crate juniper;
     use juniper::{graphql_object, FieldError, IntoFieldError, ScalarValue};
     
    diff --git a/types/objects/index.html b/types/objects/index.html
    index cf975cca..4cdd1637 100644
    --- a/types/objects/index.html
    +++ b/types/objects/index.html
    @@ -180,8 +180,8 @@
     

    When declaring a GraphQL schema, most of the time we deal with GraphQL objects, because they are the only place where we actually define the behavior once schema gets executed.

    There are two ways to define a GraphQL object in Juniper:

      -
    1. The easiest way, suitable for trivial cases, is to use the #[derive(GraphQLObject)] attribute on a struct, as described below.
    2. -
    3. The other way, using the #[graphql_object] attribute, is described in the "Complex fields" chapter.
    4. +
    5. The easiest way, suitable for trivial cases, is to use the #[derive(GraphQLObject)] attribute on a struct, as described below.
    6. +
    7. The other way, using the #[graphql_object] attribute, is described in the "Complex fields" chapter.

    Trivial

    While any type in Rust can be exposed as a GraphQL object, the most common one is a struct:

    @@ -197,7 +197,7 @@ struct Person {
    fn main() {}

    This creates a GraphQL object type called Person, with two fields: name of type String!, and age of type Int!. Because of Rust's type system, everything is exported as non-null by default.

    -

    TIP: If a nullable field is required, the most obvious way is to use Option. Or Nullable for distinguishing between explicit and implicit nulls.

    +

    TIP: If a nullable field is required, the most obvious way is to use Option. Or Nullable for distinguishing between explicit and implicit nulls.

    Documentation

    We should take advantage of the fact that GraphQL is self-documenting and add descriptions to the defined GraphQL object type and its fields. Juniper will automatically use associated Rust doc comments as GraphQL descriptions:

    @@ -314,7 +314,7 @@ struct Person { fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLObject)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLObject)] attribute.

    Relationships

    GraphQL object fields can be of any GraphQL type, except input objects.

    diff --git a/types/scalars.html b/types/scalars.html index e9e180d5..49b9e4c5 100644 --- a/types/scalars.html +++ b/types/scalars.html @@ -193,7 +193,7 @@

    Custom

    We can create custom scalars for other primitive values, but they are still limited in the data types for representation, and only introduce additional semantic meaning. This, also, often requires coordination with the client library, intended to consume the API we're building.

    -

    Custom scalars can be defined in Juniper by using either #[derive(GraphQLScalar)] or #[graphql_scalar] attributes, which do work pretty much the same way (except, #[derive(GraphQLScalar)] cannot be used on type aliases).

    +

    Custom scalars can be defined in Juniper by using either #[derive(GraphQLScalar)] or #[graphql_scalar] attributes, which do work pretty much the same way (except, #[derive(GraphQLScalar)] cannot be used on type aliases).

    Transparent delegation

    Quite often, we want to create a custom GraphQL scalar type by just wrapping an existing one, inheriting all its behavior. In Rust, this is often called as "newtype pattern". This may be achieved by providing a #[graphql(transparent)] attribute to the definition:

    extern crate juniper;
    @@ -453,12 +453,12 @@ mod string_or_int {
     
     fn main() {}
    -

    TIP: See more available features in the API docs of the #[derive(GraphQLScalar)] and #[graphql_scalar] attributes.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLScalar)] and #[graphql_scalar] attributes.

    Foreign

    -

    For implementing custom scalars on foreign types there is #[graphql_scalar] attribute.

    +

    For implementing custom scalars on foreign types there is #[graphql_scalar] attribute.

    -

    NOTE: To satisfy orphan rules, we should provide a local ScalarValue implementation.

    +

    NOTE: To satisfy orphan rules, we should provide a local ScalarValue implementation.

    extern crate juniper;
     mod date {
    diff --git a/types/unions.html b/types/unions.html
    index 989643a9..69afa717 100644
    --- a/types/unions.html
    +++ b/types/unions.html
    @@ -178,7 +178,7 @@
     

    GraphQL unions represent an object that could be one of a list of GraphQL object types, but provides for no guaranteed fields between those types. They also differ from interfaces in that object types declare what interfaces they implement, but are not aware of what unions contain them.

    From the server's point of view, GraphQL unions are somewhat similar to interfaces: the main difference is that they don't contain fields on their own, and so, we only need to represent a value, dispatchable into concrete objects.

    -

    Obviously, the most straightforward approach to express GraphQL unions in Rust is to use enums. In Juniper this may be done by using #[derive(GraphQLInterface)] attribute on them:

    +

    Obviously, the most straightforward approach to express GraphQL unions in Rust is to use enums. In Juniper this may be done by using #[derive(GraphQLInterface)] attribute on them:

    extern crate derive_more;
     extern crate juniper;
     use derive_more::From;
    @@ -308,7 +308,7 @@ enum Character<S> {
     

    WARNING: It's the library user's responsibility to ensure that ignored enum variant is never returned from resolvers, otherwise resolving the GraphQL query will panic in runtime.

    -

    TIP: See more available features in the API docs of the #[derive(GraphQLUnion)] attribute.

    +

    TIP: See more available features in the API docs of the #[derive(GraphQLUnion)] attribute.