You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- remove support for `#[graphql_interface(dyn)]`
- describe all interface trait methods with type's fields or impl block instead of `#[graphql_interface]` attribute on `impl Trait`
- forbid default impls on non-skipped trait methods
- support additional nullable arguments on implementer
- support returning sub-type on implementer
// Values type for interface has `From` implementations for all its implementers,
70
-
// so we don't need to bother with enum variant names.
71
-
letcharacter:CharacterValue=human.into();
72
-
assert_eq!(character.id(), "human-32");
73
-
# }
54
+
#
55
+
# fnmain() {}
74
56
```
75
57
76
58
Also, enum name can be specified explicitly, if desired.
@@ -90,71 +72,11 @@ struct Human {
90
72
id:String,
91
73
home_planet:String,
92
74
}
93
-
#[graphql_interface]
94
-
implCharacterforHuman {
95
-
fnid(&self) ->&str {
96
-
&self.id
97
-
}
98
-
}
99
75
#
100
76
# fnmain() {}
101
77
```
102
78
103
79
104
-
### Trait object values
105
-
106
-
If, for some reason, we would like to use [trait objects][2] for representing [interface][1] values incorporating dynamic dispatch, then it should be specified explicitly in the trait definition.
107
-
108
-
Downcasting [trait objects][2] in Rust is not that trivial, that's why macro transforms the trait definition slightly, imposing some additional type parameters under-the-hood.
109
-
110
-
> __NOTICE__:
111
-
> 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][2] to specify a [GraphQL interface][1] behind it.
112
-
113
-
```rust
114
-
# externcrate juniper;
115
-
# externcrate tokio;
116
-
usejuniper::{graphql_interface, GraphQLObject};
117
-
118
-
// `dyn` argument accepts the name of type alias for the required trait object,
119
-
// and macro generates this alias automatically.
120
-
#[graphql_interface(dyn=DynCharacter, for=Human)]
121
-
traitCharacter {
122
-
asyncfnid(&self) ->&str; // async fields are supported natively
123
-
}
124
-
125
-
#[derive(GraphQLObject)]
126
-
#[graphql(impl=DynCharacter<__S>)] // macro adds `ScalarValue` type parameter to trait,
127
-
structHuman { // so it may be specified explicitly when required
128
-
id:String,
129
-
}
130
-
#[graphql_interface(dyn)] // implementing requires to know about dynamic dispatch too
131
-
implCharacterforHuman {
132
-
asyncfnid(&self) ->&str {
133
-
&self.id
134
-
}
135
-
}
136
-
137
-
#[derive(GraphQLObject)]
138
-
#[graphql(impl=DynCharacter<__S>)]
139
-
structDroid {
140
-
id:String,
141
-
}
142
-
#[graphql_interface]
143
-
implCharacterforDroid {
144
-
asyncfnid(&self) ->&str {
145
-
&self.id
146
-
}
147
-
}
148
-
149
-
# #[tokio::main]
150
-
# asyncfnmain() {
151
-
lethuman=Human { id:"human-32".to_owned() };
152
-
letcharacter:Box<DynCharacter> =Box::new(human);
153
-
assert_eq!(character.id().await, "human-32");
154
-
# }
155
-
```
156
-
157
-
158
80
### Ignoring trait methods
159
81
160
82
We may want to omit some trait methods to be assumed as [GraphQL interface][1] fields and ignore them.
@@ -176,12 +98,6 @@ trait Character {
176
98
structHuman {
177
99
id:String,
178
100
}
179
-
#[graphql_interface]
180
-
implCharacterforHuman {
181
-
fnid(&self) ->&str {
182
-
&self.id
183
-
}
184
-
}
185
101
#
186
102
# fnmain() {}
187
103
```
@@ -278,24 +194,6 @@ struct Human {
278
194
id:String,
279
195
name:String,
280
196
}
281
-
#[graphql_interface]
282
-
implCharacterforHuman {
283
-
fnid(&self, db:&Database) ->Option<&str> {
284
-
ifdb.humans.contains_key(&self.id) {
285
-
Some(&self.id)
286
-
} else {
287
-
None
288
-
}
289
-
}
290
-
291
-
fnname(&self, db:&Database) ->Option<&str> {
292
-
ifdb.humans.contains_key(&self.id) {
293
-
Some(&self.name)
294
-
} else {
295
-
None
296
-
}
297
-
}
298
-
}
299
197
#
300
198
# fnmain() {}
301
199
```
@@ -309,119 +207,50 @@ This requires to explicitly parametrize over [`ScalarValue`][3], as [`Executor`]
By default, the [GraphQL interface][1] value is downcast to one of its implementer types via matching the enum variant or downcasting the trait object (if `dyn` macro argument is used).
361
-
362
-
However, if some custom logic is needed to downcast a [GraphQL interface][1] implementer, you may specify either an external function or a trait method to do so.
The attribute syntax `#[graphql_interface(on ImplementerType = resolver_fn)]` follows the [GraphQL syntax for downcasting interface implementer](https://spec.graphql.org/June2018/#example-5cc55).
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent` of type `Boolean!` isn't present on the interface and so has to be nullable.', $DIR/fail/interface/additional_non_nullable_argument.rs:14:1
6
+
|
7
+
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
0 commit comments