Fix book tests (#711)
This commit is contained in:
parent
de1b332792
commit
61bc35251f
13 changed files with 57 additions and 16 deletions
|
@ -30,6 +30,8 @@ result can then be converted to JSON for use with tools and libraries such as
|
|||
[graphql-client](https://github.com/graphql-rust/graphql-client):
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# extern crate serde_json;
|
||||
use juniper::{EmptyMutation, EmptySubscription, FieldResult, IntrospectionFormat};
|
||||
|
||||
// Define our schema.
|
||||
|
|
|
@ -9,6 +9,7 @@ Using `Result`-like enums can be a useful way of reporting e.g. validation
|
|||
errors from a mutation:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# #[derive(juniper::GraphQLObject)] struct User { name: String }
|
||||
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
|
|
|
@ -13,6 +13,7 @@ Let's make a slightly more compact but generic implementation of [the last
|
|||
chapter](non_struct_objects.md):
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# #[derive(juniper::GraphQLObject)] struct User { name: String }
|
||||
# #[derive(juniper::GraphQLObject)] struct ForumPost { title: String }
|
||||
|
||||
|
|
|
@ -25,19 +25,18 @@ This example shows a subscription operation that returns two events, the strings
|
|||
sequentially:
|
||||
|
||||
```rust
|
||||
# use juniper::http::GraphQLRequest;
|
||||
# use juniper::{DefaultScalarValue, FieldError, SubscriptionCoordinator};
|
||||
# use juniper_subscriptions::Coordinator;
|
||||
# use futures::{Stream, StreamExt};
|
||||
# extern crate futures;
|
||||
# extern crate juniper;
|
||||
# extern crate juniper_subscriptions;
|
||||
# extern crate tokio;
|
||||
# use juniper::FieldError;
|
||||
# use futures::Stream;
|
||||
# use std::pin::Pin;
|
||||
#
|
||||
# #[derive(Clone)]
|
||||
# pub struct Database;
|
||||
# impl juniper::Context for Database {}
|
||||
# impl Database {
|
||||
# fn new() -> Self {
|
||||
# Self {}
|
||||
# }
|
||||
# }
|
||||
|
||||
# pub struct Query;
|
||||
# #[juniper::graphql_object(Context = Database)]
|
||||
# impl Query {
|
||||
|
@ -79,6 +78,11 @@ operation returns a [`Future`][Future] with an `Item` value of a `Result<Connect
|
|||
where [`Connection`][Connection] is a `Stream` of values returned by the operation and [`GraphQLError`][GraphQLError] is the error when the subscription fails.
|
||||
|
||||
```rust
|
||||
# extern crate futures;
|
||||
# extern crate juniper;
|
||||
# extern crate juniper_subscriptions;
|
||||
# extern crate serde_json;
|
||||
# extern crate tokio;
|
||||
# use juniper::http::GraphQLRequest;
|
||||
# use juniper::{DefaultScalarValue, EmptyMutation, FieldError, RootNode, SubscriptionCoordinator};
|
||||
# use juniper_subscriptions::Coordinator;
|
||||
|
|
|
@ -26,6 +26,7 @@ types to a GraphQL schema. The most important one is the
|
|||
resolvers, which you will use for the `Query` and `Mutation` roots.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
use juniper::{FieldResult, EmptySubscription};
|
||||
|
||||
# struct DatabasePool;
|
||||
|
|
|
@ -22,6 +22,7 @@ The query root is just a GraphQL object. You define it like any other GraphQL
|
|||
object in Juniper, most commonly using the `graphql_object` proc macro:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
# #[derive(juniper::GraphQLObject)] struct User { name: String }
|
||||
struct Root;
|
||||
|
@ -43,6 +44,7 @@ Mutations are _also_ just GraphQL objects. Each mutation is a single field
|
|||
that performs some mutating side-effect such as updating a database.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
# #[derive(juniper::GraphQLObject)] struct User { name: String }
|
||||
struct Mutations;
|
||||
|
@ -63,8 +65,7 @@ impl Mutations {
|
|||
Many tools in the GraphQL ecosystem require the schema to be defined in the [GraphQL Schema Language][schema_language]. You can generate a [GraphQL Schema Language][schema_language] representation of your schema defined in Rust using the `schema-language` feature (on by default):
|
||||
|
||||
```rust
|
||||
# // Only needed due to 2018 edition because the macro is not accessible.
|
||||
# #[macro_use] extern crate juniper;
|
||||
# extern crate juniper;
|
||||
use juniper::{FieldResult, EmptyMutation, EmptySubscription, RootNode};
|
||||
|
||||
struct Query;
|
||||
|
|
|
@ -5,6 +5,7 @@ possible values. Simple Rust enums can be converted to GraphQL enums by using a
|
|||
custom derive attribute:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLEnum)]
|
||||
enum Episode {
|
||||
NewHope,
|
||||
|
@ -21,6 +22,7 @@ you want to override this, you can use the `graphql` attribute, similar to how
|
|||
it works when [defining objects](objects/defining_objects.md):
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLEnum)]
|
||||
enum Episode {
|
||||
#[graphql(name="NEW_HOPE")]
|
||||
|
@ -38,6 +40,7 @@ Just like when defining objects, the type itself can be renamed and documented,
|
|||
while individual enum variants can be renamed, documented, and deprecated:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLEnum)]
|
||||
#[graphql(name="Episode", description="An episode of Star Wars")]
|
||||
enum StarWarsEpisode {
|
||||
|
|
|
@ -5,6 +5,7 @@ GraphQL fields. In Juniper, you can define input objects using a custom derive
|
|||
attribute, similar to simple objects and enums:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLInputObject)]
|
||||
struct Coordinate {
|
||||
latitude: f64,
|
||||
|
@ -32,6 +33,7 @@ Just like the [other](objects/defining_objects.md) [derives](enums.md), you can
|
|||
and add documentation to both the type and the fields:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLInputObject)]
|
||||
#[graphql(name="Coordinate", description="A position on the globe")]
|
||||
struct WorldCoordinate {
|
||||
|
|
|
@ -10,6 +10,7 @@ example from the last chapter, this is how you would define `Person` using the
|
|||
macro:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
|
||||
struct Person {
|
||||
name: String,
|
||||
|
@ -43,6 +44,7 @@ field resolver. With this syntax, fields can also take arguments:
|
|||
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
name: String,
|
||||
|
@ -75,6 +77,7 @@ to `camelCase`. If you need to override the conversion, you can simply rename
|
|||
the field. Also, the type name can be changed with an alias:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
|
||||
struct Person {
|
||||
}
|
||||
|
@ -132,6 +135,7 @@ They can have custom descriptions and default values.
|
|||
This will become better once the [Rust RFC 2565](https://github.com/rust-lang/rust/issues/60406) is implemented.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
|
||||
struct Person {}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ attribute. The other way is described in the [Complex fields](complex_fields.md)
|
|||
chapter.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
name: String,
|
||||
|
@ -31,6 +32,7 @@ descriptions:
|
|||
!FILENAME GraphQL descriptions via Rust doc comments
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
/// Information about a person
|
||||
struct Person {
|
||||
|
@ -49,6 +51,7 @@ via the `graphql` attribute. The following example is equivalent to the above:
|
|||
!FILENAME GraphQL descriptions via attribute
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
#[graphql(description="Information about a person")]
|
||||
struct Person {
|
||||
|
@ -66,6 +69,7 @@ doc comments. This enables internal Rust documentation and external GraphQL
|
|||
documentation to differ:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
#[graphql(description="This description shows up in GraphQL")]
|
||||
/// This description shows up in RustDoc
|
||||
|
@ -95,6 +99,7 @@ You can only use the custom derive attribute under these circumstances:
|
|||
Let's see what that means for building relationships between objects:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
name: String,
|
||||
|
@ -120,6 +125,7 @@ By default, struct fields are converted from Rust's standard `snake_case` naming
|
|||
convention into GraphQL's `camelCase` convention:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
first_name: String, // Would be exposed as firstName in the GraphQL schema
|
||||
|
@ -133,6 +139,7 @@ You can override the name by using the `graphql` attribute on individual struct
|
|||
fields:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
name: String,
|
||||
|
@ -150,6 +157,7 @@ To deprecate a field, you specify a deprecation reason using the `graphql`
|
|||
attribute:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
name: String,
|
||||
|
@ -170,6 +178,7 @@ only deprecate object fields and enum values.
|
|||
By default all fields in a `GraphQLObject` are included in the generated GraphQL type. To prevent including a specific field, annotate the field with `#[graphql(skip)]`:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
struct Person {
|
||||
name: String,
|
||||
|
|
|
@ -210,6 +210,7 @@ the string contains a server-side localized error message. However, it is also
|
|||
possible to return a unique string identifier and have the client present a localized string to the user.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
pub struct Item {
|
||||
name: String,
|
||||
|
@ -306,6 +307,7 @@ before. Each resolver function has a custom `ValidationResult` which
|
|||
contains only fields provided by the function.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
pub struct Item {
|
||||
name: String,
|
||||
|
@ -383,6 +385,7 @@ and would generate errors. Since it is not common for the database to
|
|||
fail, the corresponding error is returned as a critical error:
|
||||
|
||||
```rust
|
||||
# // Only needed due to 2018 edition because the macro is not accessible.
|
||||
# #[macro_use] extern crate juniper;
|
||||
|
||||
#[derive(juniper::GraphQLObject)]
|
||||
|
|
|
@ -47,6 +47,7 @@ This can be done with the newtype pattern and a custom derive, similar to how
|
|||
serde supports this pattern with `#[serde(transparent)]`.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
#[derive(juniper::GraphQLScalarValue)]
|
||||
pub struct UserId(i32);
|
||||
|
||||
|
@ -63,6 +64,7 @@ That's it, you can now user `UserId` in your schema.
|
|||
The macro also allows for more customization:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
/// You can use a doc comment to specify a description.
|
||||
#[derive(juniper::GraphQLScalarValue)]
|
||||
#[graphql(
|
||||
|
@ -98,6 +100,7 @@ The example below is used just for illustration.
|
|||
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# mod date {
|
||||
# pub struct Date;
|
||||
# impl std::str::FromStr for Date{
|
||||
|
|
|
@ -15,7 +15,8 @@ For implementing [GraphQL unions][1] Juniper provides:
|
|||
Most of the time, we just need a trivial and straightforward Rust enum to represent a [GraphQL union][1].
|
||||
|
||||
```rust
|
||||
# #![allow(dead_code)]
|
||||
# extern crate juniper;
|
||||
# #[macro_use] extern crate derive_more;
|
||||
use derive_more::From;
|
||||
use juniper::{GraphQLObject, GraphQLUnion};
|
||||
|
||||
|
@ -51,6 +52,8 @@ As an example, let's consider the situation where we need to bind some type para
|
|||
> 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 at runtime__.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# #[macro_use] extern crate derive_more;
|
||||
# use std::marker::PhantomData;
|
||||
use derive_more::From;
|
||||
use juniper::{GraphQLObject, GraphQLUnion};
|
||||
|
@ -85,7 +88,7 @@ enum Character<S> {
|
|||
If some custom logic is needed to resolve a [GraphQL union][1] variant, you may specify an external function to do so:
|
||||
|
||||
```rust
|
||||
# #![allow(dead_code)]
|
||||
# extern crate juniper;
|
||||
use juniper::{GraphQLObject, GraphQLUnion};
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
@ -129,7 +132,7 @@ impl Character {
|
|||
With an external resolver function we can even declare a new [GraphQL union][1] variant where the Rust type is absent in the initial enum definition. The attribute syntax `#[graphql(on VariantType = resolver_fn)]` follows the [GraphQL syntax for dispatching union variants](https://spec.graphql.org/June2018/#example-f8163).
|
||||
|
||||
```rust
|
||||
# #![allow(dead_code)]
|
||||
# extern crate juniper;
|
||||
use juniper::{GraphQLObject, GraphQLUnion};
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
@ -189,6 +192,7 @@ impl Character {
|
|||
Using Rust structs as [GraphQL unions][1] is very similar to using enums, with the nuance that specifying an external resolver function is the only way to declare a [GraphQL union][1] variant.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# use std::collections::HashMap;
|
||||
use juniper::{GraphQLObject, GraphQLUnion};
|
||||
|
||||
|
@ -246,6 +250,7 @@ To use a Rust trait definition as a [GraphQL union][1] you need to use the `#[gr
|
|||
> A __trait has to be [object safe](https://doc.rust-lang.org/stable/reference/items/traits.html#object-safety)__, because schema resolvers will need to return a [trait object](https://doc.rust-lang.org/stable/reference/types/trait-object.html) to specify a [GraphQL union][1] behind it.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
use juniper::{graphql_union, GraphQLObject};
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
@ -284,7 +289,7 @@ impl Character for Droid {
|
|||
If a context is required in a trait method to resolve a [GraphQL union][1] variant, specify it as an argument.
|
||||
|
||||
```rust
|
||||
# #![allow(unused_variables)]
|
||||
# extern crate juniper;
|
||||
# use std::collections::HashMap;
|
||||
use juniper::{graphql_union, GraphQLObject};
|
||||
|
||||
|
@ -336,6 +341,7 @@ impl Character for Droid {
|
|||
As with enums, we may want to omit some trait methods to be assumed as [GraphQL union][1] variants and ignore them.
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
use juniper::{graphql_union, GraphQLObject};
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
@ -377,6 +383,7 @@ impl Character for Droid {
|
|||
Similarly to enums and structs, it's not mandatory to use trait methods as [GraphQL union][1] variant resolvers. Instead, custom functions may be specified:
|
||||
|
||||
```rust
|
||||
# extern crate juniper;
|
||||
# use std::collections::HashMap;
|
||||
use juniper::{graphql_union, GraphQLObject};
|
||||
|
||||
|
@ -444,7 +451,7 @@ fn get_droid<'db>(ch: &DynCharacter<'_>, ctx: &'db Database) -> Option<&'db Droi
|
|||
By default, `#[derive(GraphQLUnion)]` and `#[graphql_union]` macros generate code, which is generic over a [`ScalarValue`][2] type. This may introduce a problem when at least one of [GraphQL union][1] variants is restricted to a concrete [`ScalarValue`][2] type in its implementation. To resolve such problem, a concrete [`ScalarValue`][2] type should be specified:
|
||||
|
||||
```rust
|
||||
# #![allow(dead_code)]
|
||||
# extern crate juniper;
|
||||
use juniper::{DefaultScalarValue, GraphQLObject, GraphQLUnion};
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
|
Loading…
Reference in a new issue