Skip to content

Instantly share code, notes, and snippets.

@acelot
Last active October 29, 2020 05:52
Show Gist options
  • Save acelot/0f54704452b9cff373d280ea3ee94d81 to your computer and use it in GitHub Desktop.
Save acelot/0f54704452b9cff373d280ea3ee94d81 to your computer and use it in GitHub Desktop.
juniper union failure with interfaces
[package]
name = "juniper-test"
version = "0.1.0"
authors = ["acelot <provaleriy@gmail.com>"]
edition = "2018"
[dependencies]
log = "0.4"
env_logger = "0.8"
actix-web = "3.1"
actix-cors = "0.4"
actix-rt = "1.1"
juniper = { git = "https://github.com/graphql-rust/juniper", branch = "master" }
juniper_actix = { git = "https://github.com/graphql-rust/juniper", branch = "master" }
derive_more = "0.99"
use actix_cors::Cors;
use actix_web::{web, App, HttpServer, HttpResponse, Error, middleware};
use std::net::{Ipv4Addr, SocketAddrV4};
use juniper_actix::graphql_handler;
#[allow(dead_code)]
mod schema;
async fn graphql(
req: actix_web::HttpRequest,
payload: actix_web::web::Payload,
schema: web::Data<schema::Schema>,
) -> Result<HttpResponse, Error> {
graphql_handler(&schema, &(), req, payload).await
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
env_logger::init();
HttpServer::new(move || {
App::new()
.data(schema::create())
.wrap(middleware::Logger::default())
.wrap(Cors::default())
.route("/", web::post().to(graphql))
.default_service(web::to(|| async { "404" }))
})
.bind(SocketAddrV4::new(
Ipv4Addr::new(0, 0, 0, 0),
3000,
))?
.run()
.await
}
query {
testField {
__typename
... on Ok {
dummy
}
... on ProblemInterface {
message
}
}
}
use juniper::{RootNode, EmptyMutation, EmptySubscription, GraphQLObject, GraphQLUnion};
pub type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>;
// Query
pub struct Query;
#[juniper::graphql_object]
impl Query {
fn testField(&self) -> TestFieldResult {
TestFieldResult::Ok(Ok { dummy: true })
}
}
// Result union
#[derive(derive_more::From, GraphQLUnion)]
enum TestFieldResult {
Ok(Ok),
SomeProblem(SomeProblem),
AnotherProblem(AnotherProblem),
}
#[derive(GraphQLObject)]
struct Ok {
pub dummy: bool,
}
// Problems
#[juniper::graphql_interface(enum = ProblemInterfaceEnum, for = [SomeProblem, AnotherProblem])]
trait ProblemInterface {
fn message(&self) -> &str;
}
#[derive(GraphQLObject)]
#[graphql(impl = ProblemInterfaceEnum)]
struct SomeProblem {
message: String,
}
#[juniper::graphql_interface]
impl ProblemInterface for SomeProblem {
fn message(&self) -> &str {
&self.message
}
}
#[derive(GraphQLObject)]
#[graphql(impl = ProblemInterfaceEnum)]
struct AnotherProblem {
message: String,
}
#[juniper::graphql_interface]
impl ProblemInterface for AnotherProblem {
fn message(&self) -> &str {
&self.message
}
}
pub fn create() -> Schema {
RootNode::new(
Query,
EmptyMutation::<()>::new(),
EmptySubscription::<()>::new(),
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment