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 theExecutor
being generic overScalarValue
types. We, instead, could have used theDefaultScalarValue
, which is the defaultScalarValue
type for theExecutor
, and make our code more ergonomic, but less flexible and generic.TIP:
S: ScalarValue
type parameter on the method is required here to keep theExecutor
being generic overScalarValue
types. We, instead, could have used theDefaultScalarValue
, which is the defaultScalarValue
type for theExecutor
, 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 theLookAheadChildren
.See more available look-ahead features in the API docs of the
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"LookAheadSelection
and theLookAheadChildren
.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 declaringQuery
andMutation
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 declaringQuery
andMutation
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:
-
- The easiest way, suitable for trivial cases, is to use the
-#[derive(GraphQLObject)]
attribute on a struct, as described below.- The other way, using the
+#[graphql_object]
attribute, is described in the "Complex fields" chapter.- The easiest way, suitable for trivial cases, is to use the
+#[derive(GraphQLObject)]
attribute on a struct, as described below.- 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 typeString!
, andage
of typeInt!
. Because of Rust's type system, everything is exported as non-null
by default.-TIP: If a
+null
able field is required, the most obvious way is to useOption
. OrNullable
for distinguishing between explicit and implicitnull
s.TIP: If a
null
able field is required, the most obvious way is to useOption
. OrNullable
for distinguishing between explicit and implicitnull
s.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.
GraphQL object fields can be of any GraphQL type, except input objects.
@@ -594,7 +594,7 @@ struct House {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 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 upextensions
, for example), theIntoFieldError
trait should be implemented.TIP: If a custom conversion into a
FieldError
is needed (to fill upextensions
, for example), theIntoFieldError
trait should be implemented.
-NOTE:
+FieldError
s are GraphQL field errors and are not visible in a GraphQL schema in any way.NOTE:
FieldError
s are GraphQL field errors and are not visible in a GraphQL schema in any way.
null
, and partial errorsJuniper's error behavior conforms to the GraphQL specification.
@@ -1002,7 +1002,7 @@ impl Example { }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 aRootNode
.TIP: If mutation/subscription functionality is not needed, consider using the predefined
EmptyMutation
/EmptySubscription
types for stubbing them in aRootNode
.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 theschema-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 theschema-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 convenienceintrospect()
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 convenienceintrospect()
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, theSubscriptionCoordinator
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 calledCoordinator
. Thesubscribe
method returns aFuture
resolving into aResult<Connection, GraphQLError>
, whereConnection
is aStream
of values returned by the operation, and aGraphQLError
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, theSubscriptionCoordinator
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 calledCoordinator
. Thesubscribe
method returns aFuture
resolving into aResult<Connection, GraphQLError>
, whereConnection
is aStream
of values returned by the operation, and aGraphQLError
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 theNullable
type:Unfortunately, plain
Option
is not capable to distinguish them. That's why in Juniper, this can be done using theNullable
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 theExecutor
being generic overScalarValue
types. We, instead, could have used theDefaultScalarValue
, which is the defaultScalarValue
type for theExecutor
, and make our code more ergonomic, but less flexible and generic.TIP:
S: ScalarValue
type parameter on the method is required here to keep theExecutor
being generic overScalarValue
types. We, instead, could have used theDefaultScalarValue
, which is the defaultScalarValue
type for theExecutor
, 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 theLookAheadChildren
.See more available look-ahead features in the API docs of the
LookAheadSelection
and theLookAheadChildren
.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
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"juniper-eager-loading
crate for Juniper.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 declaringQuery
andMutation
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 declaringQuery
andMutation
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 aRootNode
.TIP: If mutation/subscription functionality is not needed, consider using the predefined
EmptyMutation
/EmptySubscription
types for stubbing them in aRootNode
.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 theschema-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 theschema-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 convenienceintrospect()
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 convenienceintrospect()
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, theSubscriptionCoordinator
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 calledCoordinator
. Thesubscribe
method returns aFuture
resolving into aResult<Connection, GraphQLError>
, whereConnection
is aStream
of values returned by the operation, and aGraphQLError
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, theSubscriptionCoordinator
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 calledCoordinator
. Thesubscribe
method returns aFuture
resolving into aResult<Connection, GraphQLError>
, whereConnection
is aStream
of values returned by the operation, and aGraphQLError
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() {}
-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 @@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.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() {}
-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 @@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.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() {}
-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 @@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.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 animpl
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 animpl
block, which turns its methods into GraphQL fields:extern crate juniper; use juniper::{graphql_object, GraphQLObject}; @@ -359,7 +359,7 @@ impl Person { fn main() {}
-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() {}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.+
FieldResult<T>
is an alias forResult<T, FieldError>
, which is the error type all fallible fields must return. By using the?
operator, any type that implements theDisplay
trait (which most of the error types out there do) can be automatically converted into aFieldError
.
FieldResult<T>
is an alias forResult<T, FieldError>
, which is the error type all fallible fields must return. By using the?
operator, any type that implements theDisplay
trait (which most of the error types out there do) can be automatically converted into aFieldError
.-TIP: If a custom conversion into a
+FieldError
is needed (to fill upextensions
, for example), theIntoFieldError
trait should be implemented.TIP: If a custom conversion into a
FieldError
is needed (to fill upextensions
, for example), theIntoFieldError
trait should be implemented.-NOTE:
+FieldError
s are GraphQL field errors and are not visible in a GraphQL schema in any way.NOTE:
FieldError
s are GraphQL field errors and are not visible in a GraphQL schema in any way.Error payloads,
null
, and partial errorsJuniper'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:
-
- The easiest way, suitable for trivial cases, is to use the
-#[derive(GraphQLObject)]
attribute on a struct, as described below.- The other way, using the
+#[graphql_object]
attribute, is described in the "Complex fields" chapter.- The easiest way, suitable for trivial cases, is to use the
+#[derive(GraphQLObject)]
attribute on a struct, as described below.- 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 typeString!
, andage
of typeInt!
. Because of Rust's type system, everything is exported as non-null
by default.-TIP: If a
+null
able field is required, the most obvious way is to useOption
. OrNullable
for distinguishing between explicit and implicitnull
s.TIP: If a
null
able field is required, the most obvious way is to useOption
. OrNullable
for distinguishing between explicit and implicitnull
s.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.