GithubHelp home page GithubHelp logo

examples's Introduction

async-graphql

a high-performance graphql server library that's fully specification compliant

Book中文文档DocsGitHub repositoryCargo package


ci status code coverage Unsafe Rust forbidden Crates.io version docs.rs docs downloads PRs Welcome

This crate uses #![forbid(unsafe_code)] to ensure everything is implemented in 100% safe Rust.

Static schema

use std::error::Error;

use async_graphql::{http::GraphiQLSource, EmptyMutation, EmptySubscription, Object, Schema};
use async_graphql_poem::*;
use poem::{listener::TcpListener, web::Html, *};

struct Query;

#[Object]
impl Query {
    async fn howdy(&self) -> &'static str {
        "partner"
    }
}

#[handler]
async fn graphiql() -> impl IntoResponse {
    Html(GraphiQLSource::build().finish())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // create the schema
    let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();

    // start the http server
    let app = Route::new().at("/", get(graphiql).post(GraphQL::new(schema)));
    println!("GraphiQL: http://localhost:8000");
    Server::new(TcpListener::bind("0.0.0.0:8000"))
        .run(app)
        .await?;
    Ok(())
}

Dynamic schema

Requires the dynamic-schema feature to be enabled.

use std::error::Error;

use async_graphql::{dynamic::*, http::GraphiQLSource};
use async_graphql_poem::*;
use poem::{listener::TcpListener, web::Html, *};

#[handler]
async fn graphiql() -> impl IntoResponse {
    Html(GraphiQLSource::build().finish())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let query = Object::new("Query").field(Field::new(
        "howdy",
        TypeRef::named_nn(TypeRef::STRING),
        |_| FieldFuture::new(async { "partner" }),
    ));

    // create the schema
    let schema = Schema::build(query, None, None).register(query).finish()?;

    // start the http server
    let app = Route::new().at("/", get(graphiql).post(GraphQL::new(schema)));
    println!("GraphiQL: http://localhost:8000");
    Server::new(TcpListener::bind("0.0.0.0:8000"))
        .run(app)
        .await?;
    Ok(())
}

Features

  • Static and dynamic schemas are fully supported
  • Fully supports async/await
  • Type safety
  • Rustfmt friendly (Procedural Macro)
  • Custom scalars
  • Minimal overhead
  • Easy integration (poem, axum, actix-web, tide, warp, rocket ...)
  • Upload files (Multipart request)
  • Subscriptions (WebSocket transport)
  • Custom extensions
  • Error extensions
  • Limit query complexity/depth
  • Batch queries
  • Apollo Persisted Queries
  • Apollo Tracing extension
  • Apollo Federation(v2)

Note: Minimum supported Rust version: 1.75.0 or later

Examples

All examples are in the sub-repository, located in the examples directory.

git submodule update # update the examples repo
cd examples && cargo run --bin [name]

For more information, see the sub-repository README.md.

Integrations

Integrations are what glue async-graphql with your web server, here are provided ones, or you can build your own!

Crate features

This crate offers the following features. Most are not activated by default, except the integrations of GraphiQL (graphiql) and GraphQL Playground (playground):

feature enables
apollo_tracing Enable the Apollo tracing extension.
apollo_persisted_queries Enable the Apollo persisted queries extension.
log Enable the Logger extension.
tracing Enable the Tracing extension.
opentelemetry Enable the OpenTelemetry extension.
unblock Support Asynchronous reader for Upload
bson Integrate with the bson crate.
chrono Integrate with the chrono crate.
chrono-tz Integrate with the chrono-tz crate.
url Integrate with the url crate.
uuid Integrate with the uuid crate.
string_number Enable the StringNumber.
dataloader Support DataLoader.
secrecy Integrate with the secrecy crate.
decimal Integrate with the rust_decimal crate.
bigdecimal Integrate with the bigdecimal crate.
cbor Support for serde_cbor.
smol_str Integrate with the smol_str crate.
hashbrown Integrate with the hashbrown crate.
time Integrate with the time crate.
tokio-sync Integrate with the tokio::sync::RwLock and tokio::sync::Mutex.
fast_chemail Integrate with the fast_chemail crate.
tempfile Save the uploaded content in the temporary file.
dynamic-schema Support dynamic schema
graphiql Enables the GraphiQL IDE integration
playground Enables the GraphQL playground IDE integration

Observability

One of the tools used to monitor your graphql server in production is Apollo Studio. Apollo Studio is a cloud platform that helps you build, monitor, validate, and secure your organization's data graph. Add the extension crate async_graphql_apollo_studio_extension to make this avaliable.

Who's using async-graphql in production?

Community Showcase

  • rust-actix-graphql-sqlx-postgresql Using GraphQL with Rust and Apollo Federation
  • entity-rs A simplistic framework based on TAO, Facebook's distributed database for Social Graph.
  • vimwiki-server Provides graphql server to inspect and manipulate vimwiki files.
  • Diana Diana is a GraphQL system for Rust that's designed to work as simply as possible out of the box, without sacrificing configuration ability.
  • cindythink
  • sudograph

Blog Posts

References

License

Licensed under either of

examples's People

Contributors

alisenai avatar bramvanneerven avatar ccbrown avatar colemannerd avatar danbruder avatar dbanty avatar dependabot[bot] avatar edulanasca avatar ejez avatar gianalarcon avatar jakeisnt avatar jerboas86 avatar kestrer avatar michiel avatar onx2 avatar punie avatar shanesveller avatar smmoosavi avatar sunli829 avatar sync avatar vkill avatar weasy666 avatar xoac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

examples's Issues

Warp + Subscription example not working

I'm testing this out on macOS (if that is of relevance) and can't get the subscriptions working properly whether that is integration into my codebase or by running the example. Here is the output from the example (with some extra logging):

    Finished dev [unoptimized + debuginfo] target(s) in 0.37s
     Running `target/debug/server`
Playground: http://localhost:8000
[2020-07-02T22:12:07Z INFO  warp::server] listening on http://0.0.0.0:8000
[2020-07-02T22:12:10Z DEBUG hyper::proto::h1::io] read 1848 bytes
[2020-07-02T22:12:10Z DEBUG hyper::proto::h1::io] parsed 12 headers
[2020-07-02T22:12:10Z DEBUG hyper::proto::h1::conn] incoming body is content-length (1468 bytes)
[2020-07-02T22:12:10Z DEBUG hyper::proto::h1::conn] incoming body completed
[2020-07-02T22:12:10Z INFO  warp::filters::log] 127.0.0.1:62976 "POST / HTTP/1.1" 200 "http://localhost:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0" 25.517814ms
[2020-07-02T22:12:10Z DEBUG hyper::proto::h1::io] flushed 23023 bytes
[2020-07-02T22:12:11Z DEBUG hyper::proto::h1::io] read 503 bytes
[2020-07-02T22:12:11Z DEBUG hyper::proto::h1::io] parsed 15 headers
[2020-07-02T22:12:11Z DEBUG hyper::proto::h1::conn] incoming body is empty
[2020-07-02T22:12:11Z INFO  warp::filters::log] 127.0.0.1:62977 "GET / HTTP/1.1" 200 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0" 142.884µs
[2020-07-02T22:12:11Z DEBUG hyper::proto::h1::io] flushed 19149 bytes
[2020-07-02T22:12:11Z DEBUG hyper::proto::h1::io] read 0 bytes
[2020-07-02T22:12:11Z DEBUG hyper::proto::h1::conn] read eof
[2020-07-02T22:12:12Z DEBUG hyper::proto::h1::io] read 1848 bytes
[2020-07-02T22:12:12Z DEBUG hyper::proto::h1::io] parsed 12 headers
[2020-07-02T22:12:12Z DEBUG hyper::proto::h1::conn] incoming body is content-length (1468 bytes)
[2020-07-02T22:12:12Z DEBUG hyper::proto::h1::conn] incoming body completed
[2020-07-02T22:12:12Z INFO  warp::filters::log] 127.0.0.1:62976 "POST / HTTP/1.1" 200 "http://localhost:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0" 26.931438ms
[2020-07-02T22:12:12Z DEBUG hyper::proto::h1::io] flushed 23023 bytes

And from the playground:

{
  "error": "Could not connect to websocket endpoint ws://localhost:8000/. Please check if the endpoint url is correct."
}

Seems like the subscription isn't being called at all. This was tested on the exact deps in cargo, as well as the latest versions of each of the libraries.

sea orm issues

i get an error when using async_graphql to return a seaorm model from two routes:
thread 'main' panicked at: 'entity::user::Model' and 'entity::config::Model' have the same GraphQL name 'Model'

Error handling on Mutation

Running this example about error handling on mutation

actix-web/error-extensions/src/main.rs

I get

error: cannot find derive macro `Error` in this scope
   | #[derive(Debug, Error)]
   |                 ^^^^^

How am I supposed to use Error with
actix-web = { version = "4.0.0-beta.13", default-features = false } ?

How to access the request headers in async-graphql ?

I am new to Rust and I couldn't figure out how to access the request headers in a Graphql request.
I read the async-graphql docs, where Context is used to set the headers in the response but there is no function to get the request headers. It's would be great if you could show me how to do this. I am using async-graphql with poem.

can anyone help me?

I'm new to rust and
I'am facing error in post request.
axum 7

type MySchema = Schema<QueryRoot, Mutation, EmptySubscription>;
async fn graphql_handler(
schema: State,
_headers: HeaderMap,
request: GraphQLRequest,
) -> GraphQLResponse {
schema.execute(request.0).await.into()
}

let app = Router::new()
.route("/api/healthchecker", post(health_checker_handler))
.route("/graphql", post(graphql_handler))
.route("/playground", get(graphql_playground))
.with_state(schema.clone())
.layer(
CorsLayer::new()
.allow_origin("http://localhost:3000".parse::().unwrap())
.allow_methods([Method::GET, Method::POST, Method::PATCH, Method::DELETE]),
);

and the error here
the trait bound fn(axum::extract::State<async_graphql::Schema<QueryRoot, schema::Mutation, EmptySubscription>>, HeaderMap, GraphQLRequest) -> impl std::future::Future<Output = GraphQLResponse> {graphql_handler}: Handler<_, _> is not satisfied
--> src\main.rs:89:33
|
89 | .route("/graphql", post(graphql_handler))
| ---- ^^^^^^^^^^^^^^^ the trait Handler<_, _> is not implemented for fn item fn(axum::extract::State<async_graphql::Schema<QueryRoot, schema::Mutation, EmptySubscription>>, HeaderMap, GraphQLRequest) -> impl std::future::Future<Output = GraphQLResponse> {graphql_handler}
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait Handler<T, S>:
<Layered<L, H, T, S> as Handler<T, S>>
<MethodRouter as Handler<(), S>>
note: required by a bound in post

Starwars connection result is wrong

When running the StarWars example I looked into the pageInfo for humans (There is a total count of 5 humans. ).

Requesting the first 3 gives this (which is correct):

...
"pageInfo": {
        "startCursor": "0",
        "endCursor": "2",
        "hasNextPage": true,
        "hasPreviousPage": false
      }
...

Requesting the next 3 after the first 3 (first:3, after: "2") gives this (which is wrong, hasNextPage should be false)

"pageInfo": {
        "startCursor": "3",
        "endCursor": "4",
        "hasNextPage": true,
        "hasPreviousPage": true
      }

I played around with it a little bit further and found other things:

humans(first: 0, after: "2") gives

"pageInfo": {
        "startCursor": null,
        "endCursor": null,
        "hasNextPage": false, // should be true
        "hasPreviousPage": true
      }

Because the calculation to get the connection data is rather complex and mutativ (if this is a word) I didn't really understand what was going wrong.

🤔 I also wondered if these calculations could get abstracted away somehow (given the total count of items and all the other cursor info as input)

Master branch does not build

Cloned master branch but does not build with this error:

error: failed to load manifest for workspace member `/Users/asahin/Code/sandbox/async-graphql-examples/models/starwars`

Caused by:
  failed to load manifest for dependency `async-graphql`

Caused by:
  failed to read `/Users/asahin/Code/sandbox/Cargo.toml`

Caused by:
  No such file or directory (os error 2)

Subscription example fails to compile

I tried to update my code and had an issue with subscriptions. I then tried to run the example and it seems to give me the same error:

error[E0599]: no method named `clone` found for struct `async_graphql_parser::pos::Positioned<async_graphql_parser::query::SelectionSet>` in the current scope
   --> models/books/src/lib.rs:97:1
    |
97  | #[async_graphql::Subscription]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `async_graphql_parser::pos::Positioned<async_graphql_parser::query::SelectionSet>`
    | 
   ::: /home/nicolai/.cargo/registry/src/github.com-1ecc6299db9ec823/async-graphql-parser-0.5.0/src/query.rs:195:1
    |
195 | pub struct SelectionSet {
    | ----------------------- doesn't satisfy `_: std::clone::Clone`
    | 
   ::: /home/nicolai/.cargo/registry/src/github.com-1ecc6299db9ec823/async-graphql-parser-0.5.0/src/pos.rs:32:1
    |
32  | pub struct Positioned<T: ?Sized> {
    | -------------------------------- doesn't satisfy `_: std::clone::Clone`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `async_graphql_parser::query::SelectionSet: std::clone::Clone`
            which is required by `async_graphql_parser::pos::Positioned<async_graphql_parser::query::SelectionSet>: std::clone::Clone`
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0599]: no method named `as_ref` found for struct `std::sync::Arc<_>` in the current scope
  --> models/books/src/lib.rs:97:1
   |
97 | #[async_graphql::Subscription]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `std::sync::Arc<_>`
   |
   = note: `#[async_graphql::Subscription]` is a function, perhaps you wish to call it
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

is it possible get db client in post handler?

I have some code as below:

// shchema

   let schema = Schema::build(Query::default(), Mutation::default(), EmptySubscription)
        .data(db)
        .data(jwt_key) 
        .finish();

// handler

pub async fn graphql_handler(
    schema: Extension<Schema<Query, Mutation, EmptySubscription>>,
    req: GraphQLRequest,
    headers: HeaderMap,
    db: Extension<Arc<PrismaClient>>, // from handler Extention 
    jwt_key: Extension<Arc<HS256Key>>, // from handler Extention 
) -> GraphQLResponse {
   
    let mut req = req.into_inner();
    let operation_name = req.operation_name.clone();
    match operation_name.as_deref() {
        Some("login") | Some("register") => {
           req = get_token_and_user_from_headers(&headers,&db,req).await; 
        } 
        _ => {}
    }

// try to attached db and jwt_key to context, but not work for me, i cant find by their type.
    req = req.data(db).data(jwt_key);
    schema.execute(req).await.into()
}

i want check the token and insert current user into context if the operation is one of "login" and “register”, in that way i will need get the db-client in graphql handler to run get current user query. but i dont knwo how can i get the db-client which attached when build the shchem.

i also tried to attached the db-client to an Extension and attachd it to graphql Request in the handler . but it not work for me, i cant get them back from context by the client type, may be i did not use the right type.

so I have to attach the db-client to an handler Extention and also push it into the shchema when build it. in that way i can use the db-client from extention to check the token user and use the db-clinet from context in resover.

just wondering is there anyway we can get the db-client pushed in schema in the handler or we can push db-client from extention to graphql-request in hander. thanks.

Examples for filtering and pagination?

Congratulations again for the work done so far.

I'm wondering if there is somewhere a more common example of complex pagination and filtering.

Example:

  1. "sort on multiple fields",
  2. "filter with EQ, NEQ, AND, OR on field"
  3. etc.

[bug] dynamic schema example is not running for me

While testing static schema I found that dynamic schema don't run correct for me. Please check item #73; the dynamic and static start scripts are swapped.

version: async-graphql v6.0.8

Error:

error[E029]: Encountered 1 build error while trying to build a supergraph.

Caused by:
    PROVIDES_ON_NON_OBJECT_FIELD: [reviews] Invalid @provides directive on field "Review.product": field has type "String!" which is not a Composite Type
    
        The subgraph schemas you provided are incompatible with each other. See https://www.apollographql.com/docs/federation/errors/ for more information on resolving build errors.

error[E029]: Encountered 1 build error while trying to build a supergraph.

Caused by:
    PROVIDES_ON_NON_OBJECT_FIELD: [reviews] Invalid @provides directive on field "Review.product": field has type "String!" which is not a Composite Type
    
        The subgraph schemas you provided are incompatible with each other. See https://www.apollographql.com/docs/federation/errors/ for more information on resolving build errors.

Include a gateway implementation in the federation example

The federation example uses rover to pull the subgraphs together into a supergraph. I have a Apollo Federation gateway written in TypeScript but I'd like to re-write it in Rust. I'm not sure how, and an example here would really help.

Documentation on how to use QueryRoot to expose _service

I am trying to integrate ApolloRouter in rust with a subgraph written in async-graphql, do you have any examples how to expose the _service query for apollo rover, Looks like the QueryRoot type (not a pub crate) has this functionality, just don't know how to use it please.

Upload file to folder

How can I move the file to a folder?

I am using the following example

    async fn single_upload(&self, ctx: &Context<'_>, file: Upload) -> FileInfo {
        let mut storage = ctx.data_unchecked::<FileStorage>().lock().await;
        println!("files count: {}", storage.len());
        let entry = storage.vacant_entry();
        let upload = file.value(ctx).unwrap();
        let info = FileInfo {
            id: entry.key().into(),
            filename: upload.filename.clone(),
            mimetype: upload.content_type,
        };
        entry.insert(info.clone());
        info
    }

I am using Actix-web 3.1

Starwars Mutation example

Many of the example here work

https://graphql.org/learn/queries/

But

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}

results in

"errors": [
{
"message": "Schema is not configured for mutations.",

Would be great if there was an example mutation (in my case I'm using warp) an end-to-end query/mutation/sub example that includes a working mutable data context would help many for sure

Warp example issue

Hey guys,

I've used the Warp example in the docs to create a graphql application. That said, I am trying to now serve a react spa directory, but is running into issues.

It seems that anything after the "graphql_post" route from the example, does not work at all, making it impossible to serve the static files on fall through cases.

How would i use this example but end it with or(other) without it giving this error:

{"data":null,"errors":[{"message":" --> 1:1\n  |\n1 | \n  | ^---\n  |\n  = expected executable_definition","locations":[{"line":1,"column":1}]}]}
    let graphql_post = warp::header::optional::<String>("auth")
        .and(async_graphql_warp::graphql(schema.clone()))
        .and_then(
            |token,
             (schema, mut request): (
                Schema<QueryRoot, MutationRoot, SubscriptionRoot>,
                async_graphql::Request,
            )| async move {
                if let Some(token) = token {
                    request = request.data(MyToken(token));
                }
                let resp = schema.execute(request).await;
                Ok::<_, Infallible>(Response::from(resp))
            },
        );

    let graphql_playground = warp::path("api").and(warp::get()).map(|| {
        HttpResponse::builder()
            .header("content-type", "text/html")
            .body(playground_source(
                GraphQLPlaygroundConfig::new("/api").subscription_endpoint("/api"),
            ))
    });

    let app_modeling_out_csv = warp::path("app_modeling.csv")
        .and(warp::get())
        .and(with_db(database_connections.0.clone()))
        .and_then(out_csv_app_modeling);

    let db_modeling_out_csv = warp::path("db_modeling.csv")
        .and(warp::get())
        .and(with_db(database_connections.0.clone()))
        .and_then(out_csv_db_modeling);

    let cors = warp::cors()
        .allow_any_origin()
        .allow_headers(vec![
            "auth",
            "accept",
            "sec-ch-ua",
            "sec-ch-ua-mobile",
            "User-Agent",
            "Sec-Fetch-Mode",
            "Referer",
            "Origin",
            "Access-Control-Request-Method",
            "Access-Control-Request-Headers",
            "content-type",
        ])
        .allow_methods(vec!["OPTIONS", "GET", "POST", "DELETE", "PUT"]);

    let react_app = warp::fs::dir("build");

    // let other = warp::path::end().and(warp::fs::dir("build"));
    let other = warp::fs::file("build/index.html");
    let warp_log = warp::log("info");
    let routes = react_app
        .or(graphql_subscription(schema))
        .or(app_modeling_out_csv)
        .or(db_modeling_out_csv)
        .or(graphql_playground)
        .or(graphql_post)
        .or(other) // THIS DOES NOT GET READ, if i put it above graphql post, it works, but graphql post does not.
        .recover(recover_api)
        .with(cors)
        .with(warp_log);

    warp::serve(routes)
        .run(([0, 0, 0, 0], 5000))
        .await;

[Axum] axum-token-from-header not working

I have the same issue as described here with the axum example.

Screenshot 2023-11-25 at 16 52 44

When doing the same with poem-token-from-header it gives me

{
  "errors": [
    {
      "message": "Socket closed with event 1002 Token is required",
      "stack": "error@https://unpkg.com/graphiql/graphiql.min.js:71224:18\n../../../node_modules/graphql-ws/lib/client.mjs/createClient/subscribe/<@https://unpkg.com/graphiql/graphiql.min.js:20834:14\n"
    }
  ]
}

so I know I am already in the on_connection_init code. I guess my open question for this is then how to provide the correct payload to the on_connection_init method?

Any idea what might be wrong?

Rocket examples

Hello all,

Can we please have more examples with rocket?

Similar to actix, with subscriptions and authentication tokens?

我尝试直接使用schema.execute(req.into_inner()).await 出现错误

cargo.toml

actix-web = { version = "4.0.0-beta.9", features = ["openssl"] }
#async-graphql = { git = "https://github.com/async-graphql/async-graphql", features = ["dataloader",], branch="master" }
async-graphql = "2.10.2"
async-graphql-actix-web = { git = "https://github.com/async-graphql/async-graphql", branch = "actix-web-v4-beta" }
actix-files = "0.6.0-beta.6"
actix-http = "3.0.0-beta.8"
actix-service = "2.0.0"
actix-cors = "0.6.0-beta.2"
actix-server = "2.0.0-beta.5"

测试代码就是简单的actix_web

async fn index1(schema: web::Data<StarWarsSchema>, req: Request) -> Response {
   // let request = req.into_inner();
   // let request = request.query;
    schema.execute(req.into_inner()).await.into()
}

会提示``` the trait From<async_graphql::request::Request> is not implemented for `std::string::String` ``

只有使用

    let request = req.into_inner();
    let request = request.query;
    schema.execute(request).await.into()

才可以。请问我的使用方法是不是错误

Must be called from the context of Tokio runtime

Playing around examples/federation/gateway, I'm facing this issue when trying to start services federation-reviews, federation-accounts and federation-products

thread 'main' panicked at 'there is no reactor running, must be called from the context of Tokio runtime', /Users/ricardoalmeida/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.23/src/io/driver/mod.rs:204:14

Schema execute trait bounds error

Hi, i'm working on getting a new graphql server up using the actix-web v4 branch(async-graphql-actix-web = { git = "https://github.com/async-graphql/async-graphql", branch = "actix-web-v4-beta" }) and i'm running into a few trait bounds issues that i'm unsure of how to fix. Here is the base code:

#[post("/graphql")]
async fn graphql(
  schema: web::Data<Schema<Query, Mutation, EmptySubscription>>,
  req: Request,
) -> Response {
  let span = tracing::info_span!("root");
  
  schema
    .execute(req.into_inner())
    .instrument(span)
    .await
    .into()
}

#[get("/playground")]
async fn playground() -> HttpResponse {
  HttpResponse::Ok()
    .content_type("text/html; charset=utf-8")
    .body(playground_source(GraphQLPlaygroundConfig::new("/graphql")))
}

pub fn init(pg: Pool<Postgres>) -> Box<dyn Fn(&mut web::ServiceConfig)> {
  let schema = Schema::build(Query::default(), Mutation::default(), EmptySubscription)
    .data(pg)
    .finish();

  Box::new(move |app: &mut web::ServiceConfig| {
    app
      .app_data(web::Data::new(schema.clone()))
      .service(graphql)
      .service(playground);
  })
}

This will throw:

the trait bound `std::string::String: std::convert::From<async_graphql::request::Request>` is not satisfied
the following implementations were found:
  <std::string::String as std::convert::From<&mut str>>
  <std::string::String as std::convert::From<&std::string::String>>
  <std::string::String as std::convert::From<&str>>
  <std::string::String as std::convert::From<async_graphql::ID>>
and 5 others
required because of the requirements on the impl of `std::convert::Into<std::string::String>` for `async_graphql::request::Request`
required because of the requirements on the impl of `std::convert::From<async_graphql::request::Request>` for `async_graphql::Request`
1 redundant requirement hidden
required because of the requirements on the impl of `std::convert::Into<async_graphql::Request>` for `async_graphql::request::Request`

and:

the trait bound `async_graphql_actix_web::Response: std::convert::From<async_graphql::Response>` is not satisfied
the following implementations were found:
  <async_graphql_actix_web::Response as std::convert::From<async_graphql::response::BatchResponse>>
  <async_graphql_actix_web::Response as std::convert::From<async_graphql::response::Response>>
required because of the requirements on the impl of `std::convert::Into<async_graphql_actix_web::Response>` for `async_graphql::Response`

Is this issue present only because of the branch i'm working off of?

Actix runtime

Hi,

I'm following a few actix tutorials and they all use [actix-web::main]. Why do you use [actix-rt::main]? Does that provide a benefit to `async-graphql?

Axum starwars example fails to run

When I try to run the starwars example for axum I get the following error:

error[E0277]: the trait bound `std::string::String: From<async_graphql::Request>` is not satisfied
   --> axum/starwars/src/main.rs:15:20
    |
15  |     schema.execute(req.into_inner()).await.into()
    |            ------- ^^^^^^^^^^^^^^^^ the trait `From<async_graphql::Request>` is not implemented for `std::string::String`
    |            |
    |            required by a bound introduced by this call
    |
    = help: the following other types implement trait `From<T>`:
              <std::string::String as From<&mut str>>
              <std::string::String as From<&std::string::String>>
              <std::string::String as From<&str>>
              <std::string::String as From<Box<str>>>
              <std::string::String as From<Cow<'a, str>>>
              <std::string::String as From<ID>>
              <std::string::String as From<async_graphql::types::id::ID>>
              <std::string::String as From<char>>
              <std::string::String as From<url::Url>>
    = note: required for `async_graphql::Request` to implement `Into<std::string::String>`
    = note: required for `async_graphql::request::Request` to implement `From<async_graphql::Request>`
    = note: 1 redundant requirement hidden
    = note: required for `async_graphql::Request` to implement `Into<async_graphql::request::Request>`
note: required by a bound in `async_graphql::schema::Schema::<Query, Mutation, Subscription>::execute`
   --> /Users/matthewboman/.cargo/registry/src/github.com-1ecc6299db9ec823/async-graphql-4.0.16/src/schema.rs:658:47
    |
658 |     pub async fn execute(&self, request: impl Into<Request>) -> Response {
    |                                               ^^^^^^^^^^^^^ required by this bound in `Schema::<Query, Mutation, Subscription>::execute`

error[E0277]: the trait bound `GraphQLResponse: From<async_graphql::response::Response>` is not satisfied
  --> axum/starwars/src/main.rs:15:44
   |
15 |     schema.execute(req.into_inner()).await.into()
   |                                            ^^^^ the trait `From<async_graphql::response::Response>` is not implemented for `GraphQLResponse`
   |
   = help: the following other types implement trait `From<T>`:
             <GraphQLResponse as From<BatchResponse>>
             <GraphQLResponse as From<async_graphql::Response>>
   = note: required for `async_graphql::response::Response` to implement `Into<GraphQLResponse>`

error[E0277]: the trait bound `QueryRoot: async_graphql::ObjectType` is not satisfied
   --> axum/starwars/src/main.rs:24:32
    |
24  |     let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
    |                  ------------- ^^^^^^^^^ the trait `async_graphql::ObjectType` is not implemented for `QueryRoot`
    |                  |
    |                  required by a bound introduced by this call
    |
    = help: the following other types implement trait `async_graphql::ObjectType`:
              &T
              Arc<T>
              Box<T>
              Edge<Cursor, Node, EdgeFields, Name>
              EmptyFields
              EmptyMutation
              MergedObjectTail
              PageInfo
            and 8 others
note: required by a bound in `async_graphql::Schema::<Query, Mutation, Subscription>::build`
   --> /Users/matthewboman/.cargo/registry/src/github.com-1ecc6299db9ec823/async-graphql-5.0.7/src/schema.rs:310:12
    |
310 |     Query: ObjectType + 'static,
    |            ^^^^^^^^^^ required by this bound in `Schema::<Query, Mutation, Subscription>::build`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `axum-starwars` due to 3 previous errors

This happens using version "5.0.7" of both async-graphql and async-graphql-axum.

`@key` doesn't get added to entities on the exported SDL

@key directive doesn't get applied on entities even when federation is enabled.

This is the following code example that I tried.

#[derive(Debug, Clone, SimpleObject)]
pub struct User {
    pub id: &'static str,
    pub name: &'static str,
}

#[Object(extends)]
impl Query {
    pub async fn users(&self) -> Vec<User> {
        User::all()
    }

    #[graphql(entity)]
    pub async fn find_user_by_id(&self, #[graphql(key)] id: ID) -> User {
        User::find_by_id(id)
    }
}

The exported SDL for the above User type is

type User {
    id: String!,
    name: String!
}

whereas what I expect is

type User @key(fields: "id") {
    id: String!,
    name: String!
}

Let me know if I am missing something..

deadpool-postgres cursor connections - how to implement?

I am new to rust and try to implement cursor connections on user lists. please help.

let client: Client = self.pool.get().await.map_err(|err| {
            error!("Error getting client {}", err; "query" => "user_users");
            err
        })?;
let statement = client.prepare("select * from user_users").await?;

        let users = client
            .query(&statement, &[])
            .await
            .map_err(|err| {
                error!("Error getting users. {}", err; "query" => "user_users");
                err
            })?
            .iter()
            .map(|row| User::from_row_ref(row))
            .collect::<Result<Vec<User>, _>>()
            .map_err(|err| {
                error!("Error getting parsing users. {}", err; "query" => "user_users");
                err
            })?;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.