From f42054f407a48a550cf5ad36e5abbe3bbc261eee Mon Sep 17 00:00:00 2001 From: Juniper Bot Date: Fri, 23 Oct 2020 23:39:12 +0000 Subject: [PATCH] Updated book for master ***NO_CI*** --- master/advanced/dataloaders.html | 2 +- .../advanced/implicit_and_explicit_null.html | 289 ++++++++++++++++++ master/advanced/index.html | 3 +- master/advanced/introspection.html | 2 +- master/advanced/multiple_ops_per_request.html | 2 +- master/advanced/non_struct_objects.html | 6 +- master/advanced/objects_and_generics.html | 6 +- master/advanced/subscriptions.html | 2 +- master/index.html | 2 +- master/print.html | 93 +++++- master/quickstart.html | 2 +- master/schema/schemas_and_mutations.html | 2 +- master/searchindex.js | 2 +- master/searchindex.json | 2 +- master/servers/hyper.html | 2 +- master/servers/index.html | 2 +- master/servers/iron.html | 2 +- master/servers/official.html | 2 +- master/servers/rocket.html | 2 +- master/servers/third-party.html | 2 +- master/servers/warp.html | 2 +- master/types/enums.html | 2 +- master/types/index.html | 2 +- master/types/input_objects.html | 2 +- master/types/interfaces.html | 2 +- master/types/objects/complex_fields.html | 2 +- master/types/objects/defining_objects.html | 2 +- master/types/objects/error_handling.html | 2 +- master/types/objects/using_contexts.html | 2 +- master/types/other-index.html | 2 +- master/types/scalars.html | 2 +- master/types/unions.html | 2 +- 32 files changed, 416 insertions(+), 35 deletions(-) create mode 100644 master/advanced/implicit_and_explicit_null.html diff --git a/master/advanced/dataloaders.html b/master/advanced/dataloaders.html index c155a598..31fe274c 100644 --- a/master/advanced/dataloaders.html +++ b/master/advanced/dataloaders.html @@ -72,7 +72,7 @@
diff --git a/master/advanced/implicit_and_explicit_null.html b/master/advanced/implicit_and_explicit_null.html new file mode 100644 index 00000000..db70baff --- /dev/null +++ b/master/advanced/implicit_and_explicit_null.html @@ -0,0 +1,289 @@ + + + + + + Implicit and explicit null - Juniper - GraphQL Server for Rust + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Implicit and explicit null

+

There are two ways that a client can submit a null argument or field in a query.

+

They can use a null literal:

+
{
+    field(arg: null)
+}
+
+

Or they can simply omit the argument:

+
{
+    field
+}
+
+

The former is an explicit null and the latter is an implicit null.

+

There are some situations where it's useful to know which one the user provided.

+

For example, let's say your business logic has a function that allows users to +perform a "patch" operation on themselves. Let's say your users can optionally +have favorite and least favorite numbers, and the input for that might look +like this:

+
/// Updates user attributes. Fields that are `None` are left as-is.
+pub struct UserPatch {
+    /// If `Some`, updates the user's favorite number.
+    pub favorite_number: Option<Option<i32>>,
+
+    /// If `Some`, updates the user's least favorite number.
+    pub least_favorite_number: Option<Option<i32>>,
+}
+
+# fn main() {}
+
+

To set a user's favorite number to 7, you would set favorite_number to +Some(Some(7)). In GraphQL, that might look like this:

+
mutation { patchUser(patch: { favoriteNumber: 7 }) }
+
+

To unset the user's favorite number, you would set favorite_number to +Some(None). In GraphQL, that might look like this:

+
mutation { patchUser(patch: { favoriteNumber: null }) }
+
+

If you want to leave the user's favorite number alone, you would set it to +None. In GraphQL, that might look like this:

+
mutation { patchUser(patch: {}) }
+
+

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

+

In Juniper, this can be done using the Nullable type:

+
# extern crate juniper;
+use juniper::{FieldResult, Nullable};
+
+#[derive(juniper::GraphQLInputObject)]
+struct UserPatchInput {
+    pub favorite_number: Nullable<i32>,
+    pub least_favorite_number: Nullable<i32>,
+}
+
+impl Into<UserPatch> for UserPatchInput {
+    fn into(self) -> UserPatch {
+        UserPatch {
+            // The `explicit` function transforms the `Nullable` into an
+            // `Option<Option<T>>` as expected by the business logic layer.
+            favorite_number: self.favorite_number.explicit(),
+            least_favorite_number: self.least_favorite_number.explicit(),
+        }
+    }
+}
+
+# pub struct UserPatch {
+#     pub favorite_number: Option<Option<i32>>,
+#     pub least_favorite_number: Option<Option<i32>>,
+# }
+
+# struct Session;
+# impl Session {
+#     fn patch_user(&self, _patch: UserPatch) -> FieldResult<()> { Ok(()) }
+# }
+
+struct Context {
+    session: Session,
+}
+
+struct Mutation;
+
+#[juniper::graphql_object(Context=Context)]
+impl Mutation {
+    fn patch_user(ctx: &Context, patch: UserPatchInput) -> FieldResult<bool> {
+        ctx.session.patch_user(patch.into())?;
+        Ok(true)
+    }
+}
+# fn main() {}
+
+

This type functions much like Option, but has two empty variants so you can +distinguish between implicit and explicit null.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/master/advanced/index.html b/master/advanced/index.html index 5c96c417..c1fe82d8 100644 --- a/master/advanced/index.html +++ b/master/advanced/index.html @@ -72,7 +72,7 @@
@@ -141,6 +141,7 @@
  • Introspection
  • Non-struct objects
  • +
  • Implicit and explicit null
  • Objects and generics
  • Multiple operations per request
  • Dataloaders
  • diff --git a/master/advanced/introspection.html b/master/advanced/introspection.html index 139f2b13..2c441f42 100644 --- a/master/advanced/introspection.html +++ b/master/advanced/introspection.html @@ -72,7 +72,7 @@
    diff --git a/master/advanced/multiple_ops_per_request.html b/master/advanced/multiple_ops_per_request.html index c34de3bc..46bc6eab 100644 --- a/master/advanced/multiple_ops_per_request.html +++ b/master/advanced/multiple_ops_per_request.html @@ -72,7 +72,7 @@
    diff --git a/master/advanced/non_struct_objects.html b/master/advanced/non_struct_objects.html index 335abf3f..6ac4e55b 100644 --- a/master/advanced/non_struct_objects.html +++ b/master/advanced/non_struct_objects.html @@ -72,7 +72,7 @@
    @@ -199,7 +199,7 @@ be used, and how to model expected errors.

    - @@ -217,7 +217,7 @@ be used, and how to model expected errors.

    - diff --git a/master/advanced/objects_and_generics.html b/master/advanced/objects_and_generics.html index 0a07be9d..b8968cd3 100644 --- a/master/advanced/objects_and_generics.html +++ b/master/advanced/objects_and_generics.html @@ -72,7 +72,7 @@
    @@ -201,7 +201,7 @@ instantiated types. Even if Juniper could figure out the name,